【问题标题】:why does type casting to float from int prints "0.0000"为什么类型转换从 int 浮动打印“0.0000”
【发布时间】:2016-02-25 19:58:39
【问题描述】:

下面是我为理解类型转换而编写的一些代码,但我不明白为什么浮点或双精度的值被打印为“0.000000”,即使我从整数数组类型转换或尝试从联合地址解释.

#include <stdio.h>

union test1
{
 int x;
 float y;
 double z;
};


int main()
{
 int x[2]={200,300};
 float *f;
 f=(float*)(x);
 printf("%f\n",*f); /*(1)why is this value 0.0*/

 *f=(float)(x[0]); /*(2)this works as expected and prints 200.00000*/
  printf("%f\n",*f);

  union test1 u;
  u.x=200;
  /*(3)this line give compilation error why*/
  //printf ("sizeof(test1) = %d \n", sizeof(test1));
  /*(4) this line also prints the value of float and double as 0.0000 why*/
  printf ("sizeof(test1) = %lu u.x:%d u.y:%f u.z:%lf \n", sizeof(u), u.x, u.y, u.z);
  return 0;

}

【问题讨论】:

  • 选择一种语言。不同的语言工作方式不同。
  • 标题说“0.0000”。帖子说“0.000000”。建议进行更改,以便它们与您的真实体验相匹配。
  • 强制转换不会改变数据,它只会改变数据将被解释为的类型。谷歌搜索一下浮点数据(对于您选择的架构)是如何存储的,您可能会理解得更好。
  • 您所做的是未定义的行为 (UB)。使用"%e"将有助于更好地理解UB,但它仍然是UB。
  • @mah:嗯...不是真的。强制转换很好地改变了值的表示。对于一个指针,它是指针本身的值,而不是它指向的数据的值——这就是这里的问题。 C 没有像 C++ 这样的不同类型转换运算符的动物园。

标签: c pointers casting sizeof


【解决方案1】:

首先,intfloat 不是兼容的类型。

在你的代码中,通过说

 f=(float*)(x);

你破坏了strict aliasing rule。任何进一步的使用都会调用undefined behavior

简而言之,您不能只获取指向 float 的指针,将其转换为 int * 并取消引用 int * 以获得 int 值。引用wikipedia article

如果函数中的[..]指针参数指向根本不同的类型,则假定它们不是别名,[...]

如需更详细的说明,请参阅已链接的FAQ 答案。

【讨论】:

  • f=(float*)(&x);也没什么区别,你能解释一下吗
  • 很抱歉在您发布此答案后编辑标签以删除 C++!过失。无论如何,请注意神圣的 C++ 标准不包含术语“严格别名”。这完全是一个 gcc 概念,一个特定的编译器。虽然它与标准的一段密切相关。
  • @Cheersandhth.-Alf:这是“Mea Culpa”。正确的术语是“有效类型”,但标准中提到了“别名”。您与 gcc 关联的“严格别名”是与指针相关的另一个问题。请注意,这是关于 C,而不是 C++。
  • @Olaf:你确定word order在拉丁语中很重要吗?
  • @Sandman 在这里添加了一些解释,请参阅链接的答案,这是一个金矿。 :)
【解决方案2】:
printf("%f\n",*f); /*(1)why is this value 0.0*/

您正在获取int 的地址并将其视为包含float。那是未定义的行为。

【讨论】:

    【解决方案3】:
    printf("%f\n",*f); /*(1)why is this value 0.0*/
    

    这实际上是未定义的行为,但说这并不能解释为什么你的情况是 0.0。结果可能是任何东西,因为它是未定义的行为,但是对于给定的编译器和给定的机器,该行为虽然没有指定,但产生了一些东西。

    您正在将包含 int 编码的内存作为浮点数读取;很有可能将 200 编码为 int,读取为非常小的值(非规范化的小浮点数)作为浮点数并写入 0.0。在我的机器上,非规范化浮点数使用 printf 打印为 0.0(不知道这是否是标准的 printf 行为)。

    对于浮点编码,请阅读 IEEE 754。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      相关资源
      最近更新 更多