将int转换为float:如何完成
Convert int to float: how it is done
我是C编程语言的新手,我想问一个问题。
这里的整数i是浮点型,然后f(不知何故)成功地表示5.0:
int i = 5;
float f = i; //Something happened here...
然而,如果我们尝试这种方法:
int i = 5;
float f = *(float *)&i;
f不会得到5.0,因为它以"float的方式"解释存储在i中的位。那么,在第一种情况下,编译器到底有什么魔力呢?这似乎是一项相当艰巨的工作。。。有人能具体说明吗?谢谢
这是一项耗时的工作,但任何支持浮点运算的CPU都会提供一条指令。
如果您必须将2的补码int
转换为IEEE浮点格式,您可以:
- 取以2为基数的整数log(与最高设置位的索引密切相关),它会给出指数。偏移此值并将其存储在浮点的指数位中
- 将int的顶部
n
位(从第一个设置的无符号位之后的位开始)复制到浮点的有效位。然而,n
是float
中有效位的许多位(对于32位单精度浮点值为23)。如果int
中有任何剩余的位(即,如果它大于224),并且在您有空间的位之后的下一个位是1
,则您可以四舍五入,也可以不四舍五进,这取决于操作中的IEEE四舍五五入模式 - 将符号位从CCD_ 7复制到CCD_
如果您查看组装
int i = 5;
000D139E mov dword ptr [i],5
float f = i;
000D13A5 fild dword ptr [i]
000D13A8 fstp dword ptr [f]
filt是什么神奇的
将int位转换为浮动
float IntBitsToFloat(long long int bits)
{
int sign = ((bits & 0x80000000) == 0) ? 1 : -1;
int exponent = ((bits & 0x7f800000) >> 23);
int mantissa = (bits & 0x007fffff);
mantissa |= 0x00800000;
// Calculate the result:
float f = (float)(sign * mantissa * Power(2, exponent-150));
return f;
}
在IA32系统上,编译器将生成以下内容:-
fild dword ptr [i] ; load integer in FPU register, I believe all 32bit integers can be represented exactly in an FPU register
fstp dword ptr [f] ; store fpu register to RAM, truncating/rounding to 32 bits, so the value may not be the same as i
魔术取决于您的平台。
一种可能性是,您的CPU有一条特殊的指令,可以将浮点数字复制到整数寄存器中。
当然,必须有人设计这些CPU,所以这并不是对现有算法的真正解释。
一个平台可能使用这样的浮点格式(实际上,为了示例起见,这是一种定点格式):
[sIIIIFFFF]
其中s
是符号,I
s是点之前的部分,F
s是点之后的部分,例如(点是虚拟的,仅用于表示)
- 47.5000
[sIIII.FFFF]
在这种情况下,转换几乎是微不足道的,可以使用比特移位来实现:
-47.5000
>> 4
---------------
-47
与本例一样,商品C++实现使用浮点表示,通常称为IEEE浮点,另请参阅IEEE 754-1985。这些比不定点数更复杂,因为它们确实指定了一个形式为_s*mn的简单公式,然而,它们有一个定义良好的解释,你可以将它们展开成更合适的东西。
好吧,我刚刚在VC++下编译了有问题的代码,并查看了反汇编:
int i = 5;
00A613BE mov dword ptr [i],5
float f = i;
00A613C5 fild dword ptr [i]
00A613C8 fstp dword ptr [f]
第一个汇编语句将5移动到i表示的内存中。第二个语句filtd将i表示的存储器转换为浮点数,并将其推送到FPU堆栈上。第三条语句fstp获取FPU堆栈上的内存并将其移动到f。
在几乎所有现代系统中,浮点运算的规范都是IEEE754标准。这详细介绍了从内存中的布局到截断和舍入如何传播的所有内容。这是一个很大的领域,在科学和工程编程中经常需要详细考虑一些问题。
- 模板参数替换失败,并且未完成隐式转换
- 用C++在单独的头文件中完成函数体
- 函数何时会在c++中包含stack_Unwind_Resume调用
- Python中的for循环与C++有何不同
- System.InvalidCastException - SQL to C++ - safe_cast<float>
- 等待整个 omp 块完成,然后再调用第二个函数
- 不必要的C++代码最终会出现在我完成的程序中吗?
- 没有从阵列<float>到阵列<int>的可行转换
- 数组下标的类型"float*[float]"无效
- C++一个线程如何正确通信其任务已完成?
- 在C++中释放内存期间,迭代器与指针有何不同
- 如何使用libav编写.mov文件,如果文件未正确完成,则可以播放
- 没有合适的构造函数可以从"float"转换为"_D3DCOLORVALUE"
- 为什么我会收到此错误?无法将 {lb, ub} 从<大括号括起来的初始值设定项列表>转换为 float(**)(float*, int)
- 将 **float array 从 C++ Dll 传递给 python
- 修复完成输入后重复"enter names of teacher"?
- async_write完成处理程序最早何时完成?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 将int转换为float:如何完成
- float的类内静态常量初始化与C++中的int有何不同