浮点数中整数的精确表示形式
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 个尾数位,那么它可以准确地表示 223个不同的整数值。
但是,由于浮点数单独存储 2 的幂指数,因此它可以(受有限的指数范围限制(准确地表示这2 23个值乘以 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) << "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
它显示了数字 1、2 23、224和 230的直接前身和后继者,类型为float
。如您所见,对于较大的数字,差距会变大,在 2 的每个幂处,差距的大小会翻倍。
你会得到类似的结果,但差距较小,类型为double
或long double
.
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 如何更好地表示 6 个整数键而不是作为 6 维数组的索引?
- 浮点数中整数的精确表示形式
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 给定一个整数,将其表示为平方和
- 整数文本太大,无法用任何整数类型表示--C++
- 运行时错误:有符号整数溢出:964632435 * 10 无法在类型 'int' 中表示
- 如何在以 256 为基数的唯一 xLen-digit 表示中写一个整数 x?
- 升序,三个整数表示C++
- 编译器C++如何在二进制代码中表示整数
- 将表示位置的整数分解为多个部分,然后再返回
- 计算表示有符号整数所需的最小字节数
- 整数数组元素,前导 0 表示垃圾输出
- 获取所有方式以两个整数的产品表示数字
- 为什么对Chrono :: Nanseconds的表示类型是签名的整数类型
- 用位表示整数类型大小的元程序
- 使用 cin.fail() 表示整数与地板
- 我有一个类来表示整数,我想区分磅和公斤,我该怎么做
- 使用布尔值表示整数