-1

我有这样的代码:

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 结果。为什么不是?我应该阅读什么才能理解?

4

7 回答 7

6

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

因为y是双精度,而不是整数。现在,如果您要问为什么没有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

如果您要查看值为 的内存转储x100.1您会看到:

66 66 66 66 66 06 59 40

当您将其作为 int 访问时,您会得到66 66 66 66,转换为十进制后,是 1717986918。


需要注意的另一件事是,C++ 无法保证这些。事实上,您的程序实际上并不合法,因为当您x通过指向 int 的指针访问双精度时,您违反了别名规则。您的程序可以合法并获得相同的结果,但 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 上也有很多关于别名的问题和答案。

于 2013-06-01T16:24:54.633 回答
4

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

于 2013-06-01T15:31:00.627 回答
4

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

你的指针 int *,你得到了一个int结果。

但这不是您要显示的内容。您正在显示y哪个是double.

1.71799e+09int你得到的双重表示。

于 2013-06-01T15:33:39.127 回答
3

当你这样做

y = *p;

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

假设sizeof(double)是 8 并且sizeof(int)是 4

x = 100;是否将xdouble中的值 100放在 8 个字节上。然后,当您这样做时,您只会使用 8 个字节中的 4 个作为int值,然后将该数字转换为doubley = *p;

doubleint的二进制格式不同。例如,作为双精度的 100 与 100 int的表示方式不同(更不用说大小差异,例如 8 对 4)。

看到这个链接

于 2013-06-01T15:30:22.827 回答
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; 

没有明智的方法可以使用指针来进行这种转换。

于 2013-06-01T15:34:18.963 回答
0

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

p = (int *) &x;

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

于 2013-06-01T15:40:33.490 回答
-1

阅读 C++ 指针和数据类型文档

http://www.cplusplus.com/doc/tutorial/pointers/

http://www.cplusplus.com/doc/tutorial/variables/

于 2013-06-01T15:39:37.630 回答