浮点运算是如何在一个大数字上加一的
How does floating-point arithmetic work when one is added to a big number?
如果我们运行以下代码:
#include <iostream>
int main ()
{
using namespace std;
float a = 2.34E+22f;
float b = a+1.0f;
cout<<"a="<<a<<endl;
cout<<"b-a"<<b-a<<endl;
return 0;
}
那么结果将是0,因为浮点数只有6个有效数字。但浮点数1.0试图加到23位数字上。那个么,程序是如何实现数字1并没有位置的,算法是什么呢?
逐步:
IEEE-754 32位二进制浮点格式:
符号1位有效位23位指数8位
I) float a = 23400000000.f;
将23400000000.f
转换为float
:
23400000000=101 0111 0010 1011 1111 1010 0000 00002=1.01011100101011111110101010000000002•234。
但是有效位只能在该点之后存储23位。所以我们必须绕过:
1.01011100101011111110101 010000000002•234≈1.010111001010111111101012•234
因此,在之后
float a = 23400000000.f;
CCD_ 5等于23399991808。
II) float b = a + 1;
a=101011100101011111110101000000000002。b=10101011100101011111110101000000000012=1.01011100101011111110101000000000012•234。
但是,同样,有效位只能在该点之后存储23个二进制数字。所以我们必须绕过:
1.01011100101011111110101 000000000012•234≈1.010111001010111111101012•234
因此,在之后
float b = a + 1;
CCD_ 7等于23399991808。
III) float c = b - a;
101011100101011111110101000000000002
该值可以存储在float
中,而无需取整。
因此,在之后
float c = b - a;
CCD_ 10等于0。
基本原理是将两个数字对齐,使小数点位于同一位置。我用一个10位数的数字来让它更容易阅读:
a = 1.234E+10f;
b = a+1.0f;
计算+1.0f时,小数点需要排列:
1.234E+10f becomes 1234000000.0
1.0f becomes 1.0
+
= 1234000001.0
但由于它是浮动的,右边的1在有效范围之外,所以存储的数字将是1.234000E+10
——超过这个数字的任何数字都会丢失,因为数字不够。
[注意,如果你在优化编译器上这样做,它可能仍然会显示1.0,因为浮点单元使用64位或80位的内部表示,所以如果计算是在不将中间结果存储在变量中的情况下完成的(一个好的编译器肯定可以在这里实现这一点)对于2.34E+22f,可以保证不适合64位浮点,也可能不适合80位浮点。]。
当将两个FP数字相加时,它们首先转换为相同的指数。以十进制表示:2.34000E+22 + 1.00000E0 = 2.34000E22 + 0.000000E+22
。在该步骤中,1.0会因舍入而丢失。
二进制浮点的工作原理基本相同,只是E+22被2^77取代。
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何获取一个数字的前3位
- 为什么一个向量上的多线程操作很慢
- 函数在许多数字上转换为基数 1 时减去 2?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 如何在 Gnuplot 中分别绘制 2 个文件数据?我有一个文件"sin.txt",另一个文件"cos.txt",我想将它们分别绘制在一个图表上
- 以C++输出一个数字三角形
- 反转一个数字程序不起作用,为什么?
- WINUSB_ControlTransfer只能在设备上可用的两个接口中的一个上使用,而不能在另一个接口上使用
- R 中的算术在数字上比整数更快。这是怎么回事?
- 如何让用户在 c++ 中选择一个数字
- 输出一个数字,该数字可能是三种类型之一
- C++在不使用pow或循环的情况下计算一个数字的幂
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- put_time具有转换说明符,该转换指定符,该指定符在一个月的单个数字上输出没有前面字符的单位天数
- 切换始终在猜测一个数字游戏上输出默认值
- C++两个字节上写一个数字
- 浮点运算是如何在一个大数字上加一的
- 如何找到一个数字在两个方向上的最短路径
- 如何增加一个数字,停止它,在C++上使用 if/else 语句