奇怪的uint32_t进行浮点数组转换 [英] Strange uint32_t to float array conversion
问题描述
我有以下代码段:
#include <cstdio>
#include <cstdint>
static const size_t ARR_SIZE = 129;
int main()
{
uint32_t value = 2570980487;
uint32_t arr[ARR_SIZE];
for (int x = 0; x < ARR_SIZE; ++x)
arr[x] = value;
float arr_dst[ARR_SIZE];
for (int x = 0; x < ARR_SIZE; ++x)
{
arr_dst[x] = static_cast<float>(arr[x]);
}
printf("%s\n", arr_dst[ARR_SIZE - 1] == arr_dst[ARR_SIZE - 2] ? "OK" : "WTF??!!");
printf("magic = %0.10f\n", arr_dst[ARR_SIZE - 2]);
printf("magic = %0.10f\n", arr_dst[ARR_SIZE - 1]);
return 0;
}
如果我在MS Visual Studio 2015下对其进行编译,则可以看到输出为:
If I compile it under MS Visual Studio 2015 I can see that the output is:
WTF??!!
magic = 2570980352.0000000000
magic = 2570980608.0000000000
因此最后一个arr_dst
元素与前一个不同,但是这两个值是通过转换相同的值而获得的,该值填充了arr数组!
是虫子吗?
So the last arr_dst
element is different from the previous one, yet these two values were obtained by converting the same value, which populates the arr array!
Is it a bug?
我注意到,如果以以下方式修改转换循环,则会得到确定"结果:
I noticed that if I modify the conversion loop in the following manner, I get the "OK" result:
for (int x = 0; x < ARR_SIZE; ++x)
{
if (x == 0)
x = 0;
arr_dst[x] = static_cast<float>(arr[x]);
}
因此,这可能是向量化优化的问题.
So this probably is some issue with vectorizing optimisation.
在gcc 4.8上不会重现此行为.有什么想法吗?
This behavior does not reproduce on gcc 4.8. Any ideas?
推荐答案
我对PowerPC的实现(Freescale MCP7450)进行了调查,因为它们的IMHO记录要比Intel提出的任何伏都教徒要好得多.
I did an investigation on a PowerPC imeplementation (Freescale MCP7450) as they IMHO are far better documented than any voodoo Intel comes up with.
事实证明,对于浮点运算,浮点单元,FPU和向量单元可能具有不同的舍入.可以将FPU配置为使用以下四种舍入模式之一:四舍五入到最接近的值(默认),截断,向正无穷大和向负无穷大.然而,向量单元只能舍入到最接近的值,而一些选择指令具有特定的舍入规则. FPU的内部精度为106位.向量单元满足IEEE-754,但文档中没有说明更多.
As it turns out the floating point unit, FPU, and vector unit may have different rounding for floating point operations. The FPU can be configured to use one of four rounding modes; round to nearest (default), truncate, towards positive infinity and towards negative infinity. The vector unit however is only able to round to nearest, with a few select instructions having specific rounding rules. The internal precision of the FPU is 106-bit. The vector unit fulfills IEEE-754 but the documentation does not state much more.
查看结果,转换2570980608更加接近原始整数,这表明FPU的内部精度比矢量单位或不同的舍入模式还好.
Looking at your result the conversion 2570980608 is closer to the original integer, suggesting the FPU has better internal precision than the vector unit OR different rounding modes.
这篇关于奇怪的uint32_t进行浮点数组转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!