浮点中整数的精确表示
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浮点中整数的精确表示相关的知识,希望对你有一定的参考价值。
我试图理解浮点格式的整数表示。
由于IEEE浮点格式对于尾数只有23位,因此我希望任何大于1 << 22的整数只是近似表示。这不是我在g ++中观察到的
下面的两个法院都打印相同的值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个尾数位,那么它可以精确地表示223个不同的整数值。
但由于浮点单独存储一个2的幂指数,它可以(受限于指数范围)代表那些223值乘以2的幂的任何一个。
33554432
正好是225,所以它只需要一个尾数位来表示它(加上一个表示乘以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) << "
"
<< f << "
"
<< std::nextafterf(f, f*2) << "
";
putchar('
');
}
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,223,224和230.正如您所看到的,对于较大的数字,间隙变大,每个幂为2时间隙的大小加倍。
您会得到类似的结果,但间隙较小,类型为double
或long double
。
以上是关于浮点中整数的精确表示的主要内容,如果未能解决你的问题,请参考以下文章
如何将浮点值转换为具有精确精度的整数,例如 123.3443 到 1233443?
深入理解计算机系统(2.7)------二进制小数和IEEE浮点标准