Почему True равен -1

Мне было интересно, почему True равен -1, а не 1. Если я правильно помню (в те времена) в C, "true" будет равно 1.

    Dim t, f As Integer

    t = True
    f = False

    Console.WriteLine(t) ' -1
    Console.WriteLine(f) ' 0
    Console.ReadLine()

5 ответов

Решение

Когда вы бросаете любое ненулевое число в Boolean, это будет оценивать True, Например:

Dim value As Boolean = CBool(-1) ' True
Dim value1 As Boolean = CBool(1) ' True
Dim value2 As Boolean = CBool(0) ' False

Однако, как вы указываете, каждый раз, когда вы бросаете Boolean это установлено в True для Integer, он будет иметь значение -1, например:

Dim value As Integer = CInt(CBool(1)) ' -1

Причина этого в том, что -1 является целочисленным значением со знаком, где все его биты равны 1. Так как Boolean хранится в виде 16-разрядного целого числа, легче переключаться между истинным и ложным состояниями, просто НЕ отмечая все биты, а не только НЕ считая наименее значимые из битов. Другими словами, для того, чтобы True быть 1, это должно быть сохранено так:

True  = 0000000000000001
False = 0000000000000000

Но проще просто сохранить его так:

True  = 1111111111111111
False = 0000000000000000

Причина в том, что на более низком уровне:

1111111111111111 = NOT(0000000000000000)

В то время как:

0000000000000001 <> NOT(0000000000000000)
0000000000000001 = NOT(1111111111111110)

Например, вы можете повторить это поведение, используя Int16 переменные как это:

Dim value As Int16 = 0
Dim value2 As Int16 = Not value
Console.WriteLine(value2) ' -1

Это было бы более очевидно, если бы вы использовали целые числа без знака, потому что тогда значение True это максимальное значение, а не -1. Например:

Dim value As UInt16 = CType(True, UInt16) ' 65535

Таким образом, реальный вопрос заключается в том, почему в мире VB.NET использует 16 бит для хранения одного битового значения. Настоящая причина - скорость. Да, он использует в 16 раз больше памяти, но процессор может выполнять 16-битные логические операции намного быстрее, чем он может выполнять однобитовые логические операции.

Причина по которой -1 хранится как 1111111111111111 вместо 1000000000000001Как и следовало ожидать (первый бит является битом знака, а остальные - нормальным значением), потому что он хранится как дополнение к двум. Хранение отрицательных чисел в качестве дополнения к двум означает, что процессору гораздо проще выполнять арифметические операции.

Является большинством языков, числовое значение 0 является ложным. Все остальное считается правдой. Если я правильно помню, -1 фактически все биты установлены в 1, а 0 все биты установлены в 0. Я думаю, именно поэтому.

В Visual Basic, 0 является False тогда как любое ненулевое значение True, Также по MSDN:

Когда Visual Basic преобразует значения числового типа данных в логическое значение, 0 становится ложным, а все остальные значения становятся истинными. Когда Visual Basic преобразует логические значения в числовые типы, False становится 0, а True становится -1.

Вот возможный дубликат: приведение логического числа к целому числу возвращает -1 для истины?

Логическая константа True имеет числовое значение -1. Это связано с тем, что логический тип данных хранится как 16-разрядное целое число со знаком. В этой конструкции -1 оценивает до 16 двоичных 1 (логическое значение True) и 0 как 16 0 (логическое значение False). Это очевидно при выполнении операции Not для 16-разрядного целого числа со знаком 0, которое будет возвращать целое значение -1, другими словами True = Not False. Эта внутренняя функциональность становится особенно полезной при выполнении логических операций над отдельными битами целого числа, такими как And, Or, Xor и Not.[4] Это определение True также согласуется с BASIC с начала реализации Microsoft BASIC начала 1970-х годов и также связано с характеристиками инструкций процессора в то время.

Я думаю, чтобы вернуться к языку ассемблера, где условный переводится для сравнения cmp операция и нулевой флаг (ZF) проверено. Для истинных выражений ZF не поднимается, а для ложных выражений это так. Ранние процессоры Intel такие, но я не могу вспомнить, был ли Zilog Z80 и 8-разрядные процессоры Motorola имели такое же соглашение.

Другие вопросы по тегам