[英]Exact representation of integers in floating points
我試圖了解浮點格式的整數表示形式。
由於IEEE浮點格式的尾數只有23位,我希望任何大於1 << 22的整數都只是一個近似表示。 這不是我在g ++中觀察到的
下面的兩個cout都打印相同的值33554432。
由於尾數部分是負責精度的部分,我們如何能夠表示(存儲)需要超過23位才能准確存儲的精確數字。
void floating_point_precision(){
cout<< setprecision(10);
float fp = (1<<25);
cout<< fp <<endl;
cout<< (1<<25) <<endl;
}
作為基於以下答案的后續操作,即使兩個fp,i的打印內容都不相同,以下代碼為何仍未執行“不等於”操作?
void floating_point_precision(){
cout<< setprecision(10);
float fp = ((1<<25)+1);
cout<< fp <<endl;
int i = ((1<<25)+1) ;
cout<< i <<endl;
if(i != fp)
cout<< "Not equal" <<endl;
}
的確,IEEE浮點只有有限數量的尾數位。 如果有23個尾數位,則它可以准確表示2個23個不同的整數值。
但是由於浮點數分別存儲2的冪次冪,因此它可以(受限於有限的指數范圍)精確表示2個23值乘以 2 的冪 。
33554432
正好是2 25 ,因此只需要一個尾數位即可准確表示它(加上一個二進制指數,表示乘以2的冪)。 它的二進制表示形式是10000000000000000000000000
,它具有26位,但只有1個有效位。 (嗯,實際上它們都很重要,但是您明白了。)
您會發現它的相鄰整數值33554431
和33554433
無法准確地用32位float
。 (但是它們可以用64位double
。)
更一般而言, float
類型的可連續表示的值之間的差異隨該值的大小而變化。 在我的系統上(大多數系統使用IEEE格式,但是標准不需要),請使用以下程序:
#include <iostream>
#include <iomanip>
#include <cmath>
void show(float f) {
std::cout << std::nextafterf(f, 0.0) << "\n"
<< f << "\n"
<< std::nextafterf(f, f*2) << "\n";
putchar('\n');
}
int main(void) {
std::cout << std::setprecision(24);
show(1);
show(1<<23);
show(1<<24);
show(1<<30);
}
產生以下輸出:
0.999999940395355224609375
1
1.00000011920928955078125
8388607.5
8388608
8388609
16777215
16777216
16777218
1073741760
1073741824
1073741952
它以數字float
形式顯示數字1、2 23、2 24和2 30的直接前任和后繼。 如您所見,數字越大,差距越大,每乘以2的次方,差距的大小就會增加一倍。
您將獲得類似的結果,但使用double
或long double
類型的間隙較小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.