簡體   English   中英

為什么int指針給我浮點數?

[英]Why int pointer gives me floating point number?

我有這樣的代碼:

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結果。 為什么不是呢? 我應該讀懂什么?

我的指針是int,我也期望int結果。 為什么不是呢?

因為y是雙精度數,而不是整數。 現在,如果您要問為什么y不具有整數值,因為它應該是將int(必須*具有整數值)轉換為兩倍的結果,所以請看以下內容:

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

當您將其作為整數訪問時,您將獲得66 66 66 66 ,它將轉換為十進制,為1717986918。


需要注意的另一件事是C ++不能保證所有這些。 實際上,您的程序實際上是不合法的,因為當您通過指向int的指針訪問double x時,您違反了別名規則。 您的程序可以合法使用並獲得相同的結果,但是C ++沒有指定浮點值的表示形式,因此特定的整數值在法律上可能會有所不同。


我應該讀懂什么?

這是一篇介紹浮點數的文章: http : //ridiculousfish.com/blog/posts/float.html

C ++沒有指定浮點數的表示方式,但是大多數C ++實現都使用IEEE-754,因此您也可以查看該規范。 這是Wikipedia頁面,供您開始使用: https : //en.wikipedia.org/wiki/IEEE_floating_point

要了解C ++的別名規則,您可以找到並閱讀規范。 IIRC§3.10/ 10中涵蓋了嚴格的別名。 關於SO的別名還有很多疑問和答案。

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

我的指針是int,我也期望int結果。 為什么不是呢?

您的指針 int * ,和購買的int結果。

但這不是您要顯示的內容。 您正在顯示y ,它是一個double

1.71799e+09是您獲得的int的雙1.71799e+09表示。

當你做

y = *p;

變量y接受p指向的int ,然后將其轉換為double。

假設sizeof(double)為8並且sizeof(int)為4

x = 100; 您將xdouble值100放在8個字節上。 那么當你做y = *p; 您將只使用8個字節中的4個作為int值,然后將該數字轉換為double

doubleint的二進制格式是不同的。 例如,將100表示​​為double的方式與使用100 int表示的方式不同(更不用說大小差異,例如8 vs 4)。

看到這個鏈接

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; 

我們沒有明智的方法可以使用指針進行此轉換。

運行以下行時,您將觸發未定義的行為:

p = (int *) &x;

一旦觸發了不確定的行為,其余的問題就毫無意義了,因為對不確定的行為進行推理是沒有意義的(盡管看了其余的問題,這可能是因為這部分不確定的行為不會影響您的行為)真的在問。不過我不確定。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM