Примечание: данный пост перепечатан в связи с закрытием бложиков на spaces.live.com, как имеющий какую-то ценность для автора и/или читателей.
Как известно, PowerShell позволяет очень просто конвертировать hexadecimal значения в decimal. Достаточно в консоли набрать 0xhex_значение. Вот несколько примеров:
[C:\] 0xFF 255 [C:\] 0x12345 74565 [C:\] 0xDead 57005
Кажется тут всё очень просто и говорить как бы не о чем даже. Однако при работе с относительно большими величинами нужно учитывать тип вводимых данных. К типам данных относятся следующие типы:
и много других типов (Decimal, Single, Double, etc). В контексте hexadecimal чисел нас будут интересовать только эти 4 типа представления чисел. К чему я это? А к тому, что при конвертировании определённых чисел из hex в decimal вы можете получить не совсем ожидаемый результат. Например:
[C:\] 0x7FFFFFFF 2147483647
и если мы прибавим единичку к этому выражению, то получим hex значение 0x80000000 и которое должно равняться 2147483648 в десятичном выражении. Посмотрим, что скажет нам PowerShell:
[C:\] 0x80000000 -2147483648
откуда появился знак минуса? А появился он очень просто. Я специально выше указал диапазоны значений для каждого типа данных. Дело в том, что 0x7FFFFFFF является самым большим положительным числом для типа Int32 и 0x80000000 в десятичной форме будет самым большим отрицательным числом для Int32. Диапазон отрицательных чисел для Int32 находится между -2147483648 (0x8000000) и -1 (0xFFFFFFFF). По умолчанию PowerShell старается присвоить число к типу Int32 или Int64. Как в этом можно убедиться? А очень просто:
[C:\] (0xDead).gettype().fullname System.Int32 [C:\] (4294967296).gettype().fullname System.Int64
Здесь видно, что PowerShell число 0xDead присвоил к типу Int32, а число 4294967296 присвоил к типу Int64. И если мы работаем только с арифметикой (только положительными числами), то при использовании типов Int32/Int64 мы будем получать весьма неожиданные результаты в виде отрицательных чисел. Поэтому нам нужен механизм, который бы подсказал PowerShell'у тот тип данных, который нам нужен. Это делается следующим образом - [тип_данных]данные:
[C:\] [Uint64]0x123ABC 1194684 [C:\] ([uint64]0x123ABC).gettype().fullname System.UInt64
UInt32/UInt64 не содержит отрицательных чисел в десятичном представлении, поэтому при работе только с положительными числами нужно использовать тип UInt32/UInt64, который избавит нас от проблем с появлением отрицательных чисел:
[C:\] [UInt32]0x80000000
Cannot convert value "-2147483648" to type "System.UInt32". Error: "Value was either too large or too small for a UInt3
2."
At line:1 char:9
+ [UInt32] <<<< 0x80000000
Как же так? Мы явно указали, что следует использовать тип UInt32!!! И вот я вас подвёл к тому, что хотел сказать - на самом деле PowerShell всю процедуру преобразования чисел в типы данных выполняет следующим образом:
Согласно этой последовательности действий PowerShell сначала преобразовал число 0x8000000 в Int32 и ему это удалось (получил -2147483648), после чего PowerShell перешёл к шагу 2 и попытался преобразовать число -2147483648 в UInt32. Но, как я уже сказал, UInt32/UInt64 не могут содержать отрицательных чисел, поэтому мы и получили ошибку. Это определённый недостаток, что PowerShell сначала делает своё внутреннее преобразование числа, а только потом пытается преобразовать к тому типу, который мы указываем явно. Однако PowerShell имеет механизм (большое спасибо разработчикам PowerShell за очень быструю реакцию в решении этого вопроса), который переопределяет порядок преобразований типов данных. Для того, чтобы PowerShell чётко следовал нашим инструкциям и сразу преобразовывал число в указанный явно тип данных нужно данное hexadecimal число включить в одинарные кавычки.
[C:\] [UInt32]'0x80000000' 2147483648
вот теперь мы получаем ожидаемый результат. Исходя из всего выше сказанного при работе с hexadecimal числами следует взять за правило явное указание типа используемых данных и включение hex числа в одинарные кавычки, как это показано на последнем примере.
Кстати говоря, использование кавычек (как одинарных, так и двойных) имеет достаточно много интересных и полезных особенностей. Для вводного курса по кавычкам советую почитать в блоге Василия Гусева:
Иногда кавычки имеют значение ;)
Хорошо всё то, что хорошо заканчивается :-)
Comments: