Floating point 双精度a的最大指数(a-0.0001)+0.0001不等于a

Floating point 双精度a的最大指数(a-0.0001)+0.0001不等于a,floating-point,double,Floating Point,Double,假设我们在一台64位机器上使用浮点运算(带双精度)。我想找到一个最大指数,它有一个双a,这个指数为 (a - 0.0001) + 0.0001 == a 这是错误的 我可以举一些例子:a=5.0e-14就是其中之一。在这种情况下 (a - 0.0001) + 0.0001 = 5.0000002510715291e-14 我在C++中工作,如果是相关的话。编译器gcc-4.8.4,无优化 背景:在我正在查看的一段代码中,一个变量先下移0.0001以进行一些计算,然后上移0.0001以恢复原始

假设我们在一台64位机器上使用浮点运算(带双精度)。我想找到一个最大指数,它有一个双a,这个指数为

(a - 0.0001) + 0.0001 == a
这是错误的

我可以举一些例子:a=5.0e-14就是其中之一。在这种情况下

(a - 0.0001) + 0.0001 = 5.0000002510715291e-14
我在C++中工作,如果是相关的话。编译器gcc-4.8.4,无优化

背景:在我正在查看的一段代码中,一个变量先下移0.0001以进行一些计算,然后上移0.0001以恢复原始值。这不是正确的方法。理想情况下,我会保存原始值并将其复制回来,而不是来回移动。开发人员希望浮点中的非关联性不会对代码的其余部分产生任何重大影响。如果所有这些值都非常接近0.0,那么在我们的例子中就是这样

部分答案:指数不大于-5的正数,即1.0e-5,应全部作为示例

部分asnwer 2:0.00022207040003564455也是一个示例,其指数为-4


还有更大的数字也是例子吗?

描述结果正确的情况要比描述结果不正确的情况容易得多

首先,所有介于0.00005和0.0002之间的数字将产生正确的结果;根据Sterbenz定理,减法的结果可以精确地表示,因为输入是FP数,所以加法的结果也可以

其次,所有大于0.0001/eps/2的数字,其中eps是,在本例中,DBL_EPSILON将产生正确的结果,因为x-0.0001,然后加上0.0001的结果将是x。不要对这个界限太激动,它有几十亿

除此之外,您几乎没有可靠的不变量。0.0001四舍五入到浮点数不是一个好数字:因为它不是2的幂,也不是一个小整数乘以2的幂的结果,它的尾数中有很多1,破坏了你的推理能力。底线是,浮点相等很少是一个有用的尝试,而且

甚至上面的结果也假设了两件重要的事情:一是在第二个界的情况下,FP模式是四舍五入的,二是所有的计算都是以双精度进行的。第一个几乎可以肯定的假设,除非你已经改变了它,但是C++标准允许表达式中的中间结果以比操作数更高的精度执行,这意味着左手可以比右手边具有更高的精度,并且可以以更高的精度进行比较。这就允许在左手边有很多潜在的非零尾数位,而右手边不可能达到这些位


最终,对于满足或不满足等式的数字分组,您几乎无法做出任何假设

因为0.001不能精确地表示为二进制浮点数,所以不会有简单或优雅的答案。这种情况尤其如此,因为您编写公式的方式允许编译器在如何/何时/是否对中间值进行舍入方面留有余地。我建议你提供更多关于你试图解决的问题的信息。@snetel问题完全如前所述。0.0001不可精确表示的问题实际上并不相关。您可以假设我编写了基础二进制数,而不是0.0001。这只是他们在代码中的数字。你认为哪些方面需要更多的细节?编译器版本?如中所示,您需要如何处理这些信息?列出所有不符合您公式的数字的列表会很长,因此我认为这不是您想要的。@Sneftel添加了一些背景知识并简化了问题。@Sneftel简化了问题,仅确定了这样一个示例可能具有的最大指数。谢谢您的回答。什么是斯特本斯定理?我在谷歌上找不到推荐人。我想知道一件有用的事情。基本上,如果a和b在2的因子范围内,a-b是完全可表示的。我通常把它叫做斯特本斯引理。这里也是未赋值的定理11