为什么三倍添加1.0/3.0可以像数学上预期的那样工作? [英] Why adding 1.0/3.0 three times works just as mathematically expected?

查看:60
本文介绍了为什么三倍添加1.0/3.0可以像数学上预期的那样工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,在大多数情况下,实数不能精确地用二进制表示(即使使用所谓的双精度).例如,1.0/3.0近似为0x3fd5555555555555,实际上代表0.33333333333333333331483....如果执行(1.0/3.0)+(1.0/3.0),则获得0x3fe5555555555555(所以0.66666666666666662965 ...),就像在a中预期的那样.算术的感觉.

I am aware that real numbers cannot be represented exactly in binary (even though with so-called double precision) in most cases. For example, 1.0/3.0 is approximated by 0x3fd5555555555555, which actually represents 0.33333333333333331483.... If we perform (1.0/3.0)+(1.0/3.0) then we obtain 0x3fe5555555555555 (so 0.66666666666666662965...), just as expected in a sense of computer arithmetic.

但是,当我尝试通过编写以下代码来执行(1.0/3.0)+(1.0/3.0)+(1.0/3.0)

However, when I tried to perform (1.0/3.0)+(1.0/3.0)+(1.0/3.0) by writing the following code

#include<stdio.h>
int main(){
    double result=1.0/3.0;
    result+=1.0/3.0;
    result+=1.0/3.0;
    printf("%016llx\n",result);
}

并使用标准GNU C编译器进行编译,然后生成的程序返回0x3ff0000000000000(恰好代表1).这个结果让我感到困惑,因为我最初期望0x3fefffffffffffffff(我不希望舍入错误会互相抵消,因为(1.0/3.0)和(((1.0/3.0)+(1.0/3.0))都小于表示时的实际值(以二进制形式),而我仍然不知道发生了什么.

and compiling it with the standard GNU C compiler, then the resulting program returned 0x3ff0000000000000 (which represents exactly 1). This result made me confused, because I initially expected 0x3fefffffffffffff (I did not expect rounding error to cancel each other because both (1.0/3.0) and ((1.0/3.0)+(1.0/3.0)) are smaller than actual value when represented in binary), and I still have not figured out what happened.

如果您让我知道此结果的可能原因,我将不胜感激.

I would be grateful if you let me know possible reasons for this result.

推荐答案

这是一个很好的四舍五入问题.如果我没有记错的话,算术协处理器使用80位:64位精度位和15位用于指数(

That is a good rounding question. If I correctly remember, the arithmetic coprocessor uses 80 bits: 64 precision bits and 15 for the exponent (ref.). That means that internally the operation uses more bits than you can display. And in the end the coprocessor actually rounds its internal representation (more accurate) to give a 64 bit only value. And as the first bit dropped is 1 and not 0, the result is rounded upside giving 1.

但是我必须承认我只是在猜测...

But I must admit I am just guessing here...

但是,如果您尝试手工进行 操作,那么如果立即执行加法操作,则会将所有精度位设置为1(将5555 ... 5和555 ... 5移位1).加上要删除的第一位也是1 .因此,手工一个正常的人会向上舍入同时给出1,因此算术单元也能够进行正确的舍入也就不足为奇了.

But if you try to do by hand the operation, if immediately comes that the addition sets all precision bits to 1 (adding 5555...5 and 555...5 shifted by 1) plus the first bit to drop which is also 1. So by hand a normal human being would round upside also giving 1, so it is no surprise that the arithmetic unit is also able to do the correct rounding.

这篇关于为什么三倍添加1.0/3.0可以像数学上预期的那样工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆