c - ubuntu 64 位上的单精度浮点表示不正确

标签 c ubuntu floating-point 64-bit ieee-754

我有以下数据。

float u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);

void ScaleFunction(float *u_ptr)
{
  for(int i = 0; i < 4; i++)
  {
    printf("u[%d] = %f\n", u_ptr[i]);
  }
  // And a lot more
}

包含上述代码片段的应用程序在运行 ubuntu 16.10 的 64 位机器上执行。

令我懊恼的是, float 被错误地解释为:1066736960.000000、1059092608.000000、1033487232.000000 和 1051985344.000000。

以十六进制打印的数字确认调用者将正确的值传递给被调用者。

我在这里做错了什么?

我什至不高兴地尝试了以下内容。

uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);

void ScaleFunction(uint32_t *u_ptr)
{
  float ut[4];
  for(int i = 0; i < 4; i++)
  {
    ut[i] = (float) u_ptr[i];
    printf("ut[%d] = %f\n", ut[i]);
  }
  // And a lot more
}

我希望将被调用方中的十六进制解释为: 1.1649, 0.6268, 0.075, 0.5516

最佳答案

问题是,你用大整数值初始化你的数组,而不是 float 的十六进制表示。您的十六进制常量以 0x3f 左右的值开头,很明显这些是值在 1.0 左右的 float 据。

据我所知,没有直接的方法可以用十六进制常量初始化 float 组(如果有的话,社区,请告诉我!)。

因此您必须将数据数组定义为 int 并在使用时将其转换为 float。 重要提示:直接将指针从 int 转换为 float 会破坏 C 的别名规则,并可能导致代码看起来正确但行为异常。

虽然通过 memcpy 在两种数据类型之间进行转换是安全的,而且编译器通常足够聪明,可以发现这一点并对其进行优化。

所以这里的解决方案可以满足您的需求:

#include <stdint.h>
#include <stdio.h>
#include <string.h>

uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};

void ScaleFunction(uint32_t *u_ptr)
{
  for(int i = 0; i < 4; i++)
  {
      float temp;
      memcpy (&temp, &u[i], sizeof (float));
      printf("u[%d] = %f\n", i, temp);
  }
  // And a lot more
}


void main (int argc, char **args)
{
  ScaleFunction (u);
}

关于c - ubuntu 64 位上的单精度浮点表示不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44277743/

相关文章:

javascript - 在 JavaScript 中,为什么零除以零返回 NaN,而任何其他除以零返回 Infinity?

scala - 为什么 0.29999999999999998 转换为 0.3?

C - 在没有 strcmp 的情况下测试字符串等价性

c - 在c中获取char类型输入的问题

c - 读取输入引脚的状态并显示在 LED 上 - LPC1115

c - 是否可以在预处理时或编译时修改 "function call"

python - 修复 *displaying* 在 python 中 float 时的精度问题

ubuntu - Sublime Text 2 : Autoload new files in the list

php - 如何运行我所有的 PHPUnit 测试?

postgresql - 使用 Postgres 数据库时调用了哪些函数