ieee754浮点1 / x * x> 1.0

时间:2019-12-18 10:57:16

标签: c floating-point ieee-754

我想知道以下定义的程序是否可以返回1:

  • IEEE754浮点算法
  • 没有溢出(max/xf*x中都没有)
  • 没有nan或inf(显然)
  • 0
  • 没有不安全的数学优化
int canfail(int n, double x) {
    double max = 1ULL << n; // 2^n
    double f = max / x;
    return f * x > max;
}

我认为它应该有时返回1,因为roundToNearest(max / x)通常可以大于max/x。 我可以找到相反情况下的数字f * x < max,但是我没有显示f * x > max的输入示例,也不知道如何找到一个。有人可以帮忙吗?

编辑: 我知道x的值是否在10 ^(-6)和10 ^ 6之间(仍然留下很多(太多的双精度值)),但是我知道我不必处理上溢,下溢或子运算-正常数字! 另外,我刚刚意识到,由于max是2的幂,并且我们不处理溢出,因此,通过固定max=1 ,解决方案将是相同的完全相同的计算,但发生了变化。

因此,问题对应于找到一个正的,正常的双精度值x,使得`(1 / x)* x> 1.0 !!

我编写了一个小程序来尝试找到解决方案:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <omp.h>

int main( void ) {
    #pragma omp parallel
    {
        unsigned short int xsubi[3] = {
            omp_get_thread_num(),
            omp_get_thread_num(),
            omp_get_thread_num()
        };

        #pragma omp for
        for(int64_t i=0; i<INT64_MAX; i++) {
            double x = fmod(nrand48(xsubi), 1048576.0);
            if(x<0.000001)
                continue;

            double f = 1.0 / x;
            if(f * x > 1.0) {
                printf("found !!! x=%.30f\n", x);
                fflush(stdout);
            }
        }
    }
    return 1;
}

如果更改比较的符号,您将快速找到一些价值。但是,它似乎可以与f * x > 1.0

永远运行

3 个答案:

答案 0 :(得分:4)

在没有下溢或上溢的情况下,指数是无关紧要的;如果为M/x*x > M,则(M/p) / (x/q) * (x/q) > (M/p)为两个pq的任意幂。因此,让我们考虑2 52 x <2 53 M = 2 105 。我们可以消除x = 2 52 ,因为这会产生精确的浮点运算,所以2 52 <x <2 53 < / sup>。

将2 105 除以x得到整数商q和整数余数r,其中2 52 {{1 }} <2 53 ,0 <{q <r和2 105 = xq + x

为了使r超过M/x*x,除法和乘法都必须四舍五入。由于该除法是四舍五入的,所以M / 2≤x

舍入后,将2 105 的浮点除以r的结果将得出x + 1。然后,精确的(不是四舍五入的)乘法结果(q + 1)•q = xq + x = x•{ {1}} + q + x-x = rr + q + x-{{1 }} = 2 105 + r-x。由于r / 2 <xr-xr / 2,因此舍入该精确结果会舍入,得出2 105 < / sup>。 (由于2 105 具有低偶数位,因此,“ <”情况总是四舍五入,而“ =”情况则四舍五入。)

因此,对于两个x的幂和所有在指数范围内的算术运算,r永远不会发生从最近到最近的关系到偶数。

答案 1 :(得分:1)

乘以2的幂只是指数的缩放,它不会改变问题:因此,它与找到x使得(1/x) * x > 1一样。

一种解决方案是蛮力搜索。
出于相同的原因,我们可以将搜索x的时间间隔限制为(1.0,2.0(

一种更好的方法是在没有暴力的情况下分析错误范围。

让我们注意ix最接近1/x的浮点。

xix视为精确分数,我们可以写整数除法:1 = ix * x + r其中r是余数
(所有分母均为2的幂的分数,因此我们必须将整个方程乘以2的适当幂才能真正具有整数除法。)
换句话说,ix = 1/x - r/x,其中-r/x是求反的舍入误差。
当我们将逆近似值乘以x时,精确值为ix*x = 1 - r
我们知道浮点结果将四舍五入到最接近该精确值的浮点数。
因此,假设默认舍入模式为最接近的,偶数为偶的,问的问题是-r是否可以超过0.5 ulp

简短的回答永远不会!
假设|r| > 0.5 ulp,那么舍入误差-r/x确实超过了精确结果1/x的一半。
这不是一个正确的答案,因为确切的结果不是浮点且没有ulp,但是您会明白...
如果有时间,我可能会带回正确的证明,但我敢打赌,您可能已经发现它已经完成了,也许是这样

编辑 为什么找到(1/x) * x < 1

仅因为1.0处于binade极限,所以低于1,我们必须证明r<0.25 ulp,这是我们不能...

答案 2 :(得分:1)

canfail(1,pow(2,1023)*(2-pow(2,-51)))将返回1。