在.NET a float
表示使用存储使用32位的IEEE binary32单精度浮点数。显然,代码通过将这些位组装成一个int
,然后使用unsafe
将它转换为float
来构造这个数字。转换是用C++术语称为reinterpret_cast
,当执行转换时不进行转换 - 这些位仅被重新解释为新类型。
组装的数量是十六进制4019999A
或01000000 00011001 10011001 10011010
二进制:
- 符号位为0(它是一个正数)。
- 指数位是
10000000
(或128),导致指数128-127 = 1(分数乘以2^1 = 2)。
- 小数位是
00110011001100110011010
,如果没有别的,几乎都有可识别的零和一个模式。
返回的浮点数与2.4转换为浮点的位数完全相同,整个函数可以简单地用文字2.4f
代替。
那种“打破了比特模式”的分数的最后零可能使浮点数匹配可以使用浮点数字书写的东西吗?
那么常规演员和这个奇怪的“不安全演员”之间有什么区别?
假定以下代码:
int result = 0x4019999A // 1075419546
float normalCast = (float) result;
float unsafeCast = *(float*) &result; // Only possible in an unsafe context
第一铸造取整数1075419546
并将其转换为它的浮点表示,例如1075419546f
。这包括计算将原始整数表示为浮点数所需的符号,指数和小数位。这是一个不平凡的计算,必须完成。
第二次演员更险恶(只能在不安全的情况下执行)。 &result
将地址result
返回指向存储整数1075419546
的位置的指针。指针解引用运算符*
然后可以用于检索指针指向的值。使用*&result
将检索存储在该位置的整数,但是通过首先将指针指向float*
(指向float
的指针),则会从存储器位置检索浮点数,从而导致float 2.4f
被指定为unsafeCast
。所以*(float*) &result
的叙述是给了我一个指向result
的指针,并且假设指针是指向float
的指针并检索指针指向的值。
与第一次演员相反,第二次演员不需要任何计算。它只是将存储在result
中的32位推入unsafeCast
(幸运的是32位)。
一般来说,执行这样的转换可能会在许多方面失败,但通过使用unsafe
,您告诉编译器您知道自己在做什么。
你在哪里找到的样本?它没有任何关于它要返回的内容的解释吗? –
这是错的..'result'不是一个指针..我不能将它的地址转换为浮点指针我猜 – Anirudha
我找到使用mscorlib/System/BitConvert/ToSingle中的ILSpy的示例代码。没有给出解释。我需要了解什么是流程,因为我需要将其转换为PHP。 – gchimuel