奇怪的uint32_t进行浮点数组转换 [英] Strange uint32_t to float array conversion

查看:492
本文介绍了奇怪的uint32_t进行浮点数组转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码段:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆