Почему 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 имели такое же соглашение.