Беззнаковый левый сдвиг в VB.NET? - PullRequest
2 голосов
/ 23 декабря 2010

Это должно быть легко для людей, но как мне выполнить беззнаковое смещение влево в VB.NET при использовании Option Strict?

Возможно, я делаю это неправильно, но, пытаясь реализовать свою собственную функцию IP2Long (у меня есть свои причины), я тестирую вещи, чтобы убедиться, что моя голова правильно обернута вокруг процесса преобразования.Я попробовал несколько тестов, и все, кажется, вызывают ошибки.

Dim a As Int32
a = CUint(172 << 24) 'Constant expression not representable in type 'UInteger'
a = DirectCast((172 << 24), UInt32) 'Value of type 'Integer' cannot be converted to 'UInteger'
a = Convert.ToUInt32(172 << 24) 'Compiles, but throws an OverflowException

Последний из них особенно смущает.172 << 24 - это всего лишь 2885 681 152, что значительно превышает ограничение, установленное типом данных UInt32.Я предполагаю, что .NET выполняет сдвиг влево в режиме со знаком, затем пытается преобразовать в неподписанное, и это вызывает какую-то ошибку.

По сути, мой вопрос сводится к следующему: почему неподписанныеВременами числовые данные должны действовать как подобные взломы .NET Framework?Неужели для Microsoft так сложно сделать типы данных без знака неотъемлемыми для фреймворка?

1 Ответ

4 голосов
/ 23 декабря 2010

Последнее особенно смущает.172 << 24 - это всего 2 885 681 152, что значительно превышает ограничение, установленное типом данных UInt32.Я предполагаю, что .NET выполняет сдвиг влево в подписанном режиме, затем пытается преобразовать в неподписанные, и это вызывает какую-то ошибку. </p>

Эта ошибка не является ошибочной.172 занимает 8 бит.Вы сдвигаете его на 24 бита, а 8-й бит теперь является 32-м битом.Это зарезервированный бит знака.Поэтому он технически переполнен.


Обрабатывать целые числа как C #

VB.NET будет проверять целочисленное переполнение в отличие от C # .

Чтобы заставить VB.NET игнорировать OveflowExceptions Exceptions goto:

Project properties->Compile->Advanced Compiler Option->"Remove integer overflow checks"

Или compile с

vbc foo.vb /removeintchecks

Явные битовые операции состояния

Если вы решили оставить проверки переполнения в своем коде, вы должны явно указать, что вы используете битовые операции, используя BitConverter Класс:

''//This will work
a = BitConverter.ToInt32(BitConverter.GetBytes(172 << 24), 0) 

Литералы Visual Basic

Также имейте в виду, что вы можете добавить литерал к своему коду в VB.NET и явно указать константы какбез знака.

...