我在IEEE754乘法中失去了 2 的幂
I'm losing 2's powers in IEEE754 multiplication
我正在研究IEE754,我对这些代码行感到困惑
double a = 0.2;
double b = 100.0;
double c = a * b;
我知道0.2不能通过2的能力完美地表示,而100可以,但是我得到20的完美结果,结果c。
可视化组成这些值的2的功率(我正在使用一个简单的JS可视化器:http://bartaz.github.io/ieee754-visalization/),我看到0.2始于
2^-3 + 2^-4 + 2^-7...
和100
2^6 + 2^5 + 2^2
现在是我的问题:这是20,又称c
2^4 + 2^2
^^^
什么?2^4来自哪里?如果我将数学上的所有条款乘以100的所有条款,我将获得2^3的最大功能。
因此,假设可视化器是正确的:
- 2^4来自哪里?
- 如果从一开始不精确的情况下,将0.2乘以0.2乘以100的精度损失呢?为什么
c
确切的结果?
IEEE算术规则中没有任何东西可以防止往返最终的击中您想做的十进制计算的确切结果。
双文字100.0的确切值当然是100。
双文字0.2的确切值是0.200000000000000011102233024625156540423636316680908203125
他们的产品是20.000000000011102233024625156540423631668090820312500
四舍五入到20的舍入错误是1.1102233024625156540423631668090820312500E-15
由于四舍五入的误差大于将四舍五入到20的误差,因此双重乘法的正确循环结果为20.0。舍入错误是2^-50 + 2^-52
,您的"丢失"功率为2。
我使用Java程序进行计算,因为方便的BigDecimal类可以准确地表示所有有限的双重数字,并且在它们上的某些算术结果(包括乘法)。Java双重算术遵循IEEE 754 64位二进制浮点数以圆头到最新的模式,这也是C双打的通常系统。
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
double a = 0.2;
double b = 100.0;
double c = a * b;
display(a);
display(b);
display(c);
BigDecimal exactProduct = new BigDecimal(a).multiply(new BigDecimal(b));
System.out.println(exactProduct);
BigDecimal down = new BigDecimal(20.0);
System.out.println(down);
BigDecimal up = new BigDecimal(Math.nextUp(20.0));
System.out.println(up);
System.out.println("Round down error "+exactProduct.subtract(down));
System.out.println("Round up error "+up.subtract(exactProduct));
}
private static void display(double in){
System.out.println(new BigDecimal(in));
}
}
输出:
0.200000000000000011102230246251565404236316680908203125
100
20
20.000000000000001110223024625156540423631668090820312500
20
20.000000000000003552713678800500929355621337890625
Round down error 1.110223024625156540423631668090820312500E-15
Round up error 2.442490654175344388931989669799804687500E-15
相关文章:
- 在计算中使用二的幂有多有利可图
- 有效地将大数存储为 2 的幂用于路径问题
- 计算 O(1) 中的幂函数
- 查找数字是否为 2 的幂的时间复杂度
- C++在不使用pow或循环的情况下计算一个数字的幂
- 使用用户定义的函数查找数字的幂时出现问题
- 仅在 2 的幂上错过了 clang 中的优化
- 10的幂的表查找
- 虽然这个简单的 C++ 程序可以打印 2 的幂,但它有很多问题时可以工作
- 一个整数的log2,该整数是2的幂
- 更好的算法来检查一个数字是否既不是素数也不是单个素数的幂
- 我怎样才能从 n 得到一个提高到自身等于 n 的幂的数字?
- 长整数不适用于 8 的幂C++
- 我在IEEE754乘法中失去了 2 的幂
- C++编译器识别2的幂吗
- 快速映射,其中键是 2 的幂 (C++)
- 为什么发出如此复杂的代码来将有符号整数除以 2 的幂
- 为什么数组元素长度的地址计算可被 2 的幂整除更有效
- 使用C++计算一个非常大的幂
- 有没有什么方法可以降低时间复杂度来找到这个矩阵的幂n