Почему 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()

Ответ 1

Когда вы производите ненулевое число до 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. Так как a 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, как и следовало ожидать (первый бит является знаковым битом, а остальное является нормальным значением), заключается в том, что он сохраняется как два-дополнение. Сохранение отрицательных чисел в качестве двух-дополнений означает, что арифметические операции намного проще для процессора.

Ответ 2

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

Ответ 3

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

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

Ответ 4

В Visual Basic 0 есть False, тогда как любое ненулевое значение True. Кроме того, за MSDN:

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

Ответ 5

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