为什么int指针给我浮点数?

时间:2013-06-01 15:28:08

标签: c++ c pointers casting

我有这样的代码:

double x = 100.1;
double y;
int *p;

p = (int *) &x;
y = *p;

cout << "y value is: " << y << endl;

我知道这是错误的,我们得到4个字节而不是8个字节。我也知道浮动数字在内存中有一些棘手的表现(但不知道如何),但这个脚本给了我这样的输出:

y value is: 1.71799e+09

据我所知,浮点数也很有价值。我的指针是int,我也期望int结果。为什么不呢?我应该读懂什么?

7 个答案:

答案 0 :(得分:6)

  

我的指针是int,我也期望int结果。为什么不呢?

因为y是double,而不是int。现在,如果你的意思是问为什么y没有一个整数值,因为它应该是一个int(必须*有一个整数值)转换为double的结果,看一看输出如下:

std::cout << "y value is: " << std::fixed << y << '\n';

您应该看到的输出是:

y value is: 1717986918.000000

因此,y 具有整数值,您只需使用科学记数法将其打印出来。如果你想知道为什么y具有这个特定的积分值,那是因为那是*p的值。

std::cout << "*p is: " << *p << '\n';

*p is: 1717986918

如果您要查看x的内存转储,其值为100.1,您会看到:

66 66 66 66 66 06 59 40

当你以int形式访问它时,你得到66 66 66 66,转换为十进制,是1717986918。


另外需要注意的是,C ++不能保证这一点。实际上,您的程序实际上并不合法,因为当您通过指向int的指针访问double x时,您违反了别名规则。您的程序可以合法并获得相同的结果,但C ++没有指定浮点值的表示,因此特定的积分值可能在法律上有所不同。


  

我应该阅读哪些内容?

这是一篇与浮点数表示相关的文章:http://ridiculousfish.com/blog/posts/float.html

C ++没有指定浮点数的表示方式,但大多数C ++实现都使用IEEE-754,因此您也可以查看该规范。这是维基百科页面的开头:https://en.wikipedia.org/wiki/IEEE_floating_point

要了解C ++的别名规则,您可以找到并阅读规范。 IIRC第3.10 / 10节中涉及严格混叠。在SO上还有很多关于别名的问题和答案。

答案 1 :(得分:4)

1.71799e+09是整数1,717,99x,xxx的浮点表示。

答案 2 :(得分:4)

  

我的指针是int,我也期望int结果。为什么不呢?

您的指针 int * 获得int结果。

但那并不是你所展示的。您显示的ydouble

1.71799e+09是您获得的int的双重表示。

答案 3 :(得分:3)

当你这样做时

y = *p;

变量 y 采用 p 指向的 int ,然后将其转换为double。

假设sizeof(double)为8,sizeof(int)为4

执行x = 100;您将double值100放在 x 中的8个字节上。然后当你执行y = *p;时,你只能使用8个字节中的4个作为 int 值,然后将该数字转换为 double

double int 的二进制格式不同。例如。 100 double 与100 int 的表示方式不同(更不用说大小差异,例如8 vs 4)。

See this link

答案 4 :(得分:3)

double x = 100.1;
double y;
int *p;

p = (int *) &x;      
// Set a pointer of type integer to point at a floating point. Better C++ style
// would be p = reinterpret_cast<int *>(&x);
// which explains more clearly what you are doing - reinterpreting the pointer as
// a different type. 

y = *p;
// *p is an integer. So y is set to the value of *p, which is some crazy 
// integer value formed from the interpretation of a double as integer.

cout << "y value is: " << y << endl;

请参阅上面代码中的注释。您正在指向不同类型的数据的指针,然后想知道为什么转换的二进制数字不代表它最初表示的...

(从技术上讲,这段代码违反了有关别名的规则 - 基本上,你为了两个不同的目的使用相同的内存,编译器没有义务在这种情况下“做正确的事” - 我怀疑它在这种特殊情况下会做出你能想到的事情 - 如果你期望的是你得到一个由double的四个第一个字节表示的整数值,那就是)。

如果您希望y实际包含x中数字的整数表示,则需要:

y = (int)x; 

我们没有明智的方法可以使用指针来进行此转换。

答案 5 :(得分:0)

当您运行以下行时,您将触发未定义的行为:

p = (int *) &x;

一旦你触发了未定义的行为,你的问题的其余部分就毫无意义,因为关于未定义行为的推理没有意义(尽管看看你的其余问题,可能是这一点未定义的行为不会影响你真正的问题。我不确定。)

答案 6 :(得分:-1)