代码之家  ›  专栏  ›  技术社区  ›  Jeff Saremi

exp()是非常不准确的

  •  1
  • Jeff Saremi  · 技术社区  · 6 年前

    我只是做了一个从1到50的循环,并打印出了WebGL的exp(float)计算结果。我用的是高精度的,这些是WebGL2的。

       precision highp float;
        varying vec2 TexCoords;
        uniform highp sampler2D A;
    
        void main() {
          float result = exp(texture2D(A, TexCoords).r);
          gl_FragColor.r = result;
        }
    

    我在javascript中运行了同样的程序并比较了结果。聪明的东西很小,但很快就会变成非常大的数字。

    所以我还比较了javascript和python(numpy)的结果,它们非常相似。

    下面是Math.abs(diff)中的最后几个数字:

    差分,'8.25484055456E-8, 3.700182968913168e-7, 0.0000037810978241736848, 0.0000055018942362039525, 0.0000031228868712565236。。。12720537652、21883728284、30738633104、20683268800、3245434496、2989835245824、6539001840640, 12329169293312、110431739568128、262788127178752、6150237094536, 136952888085312028196912005120

    这是javascript和pyton之间的最后几个区别 :

    3.0517578125e-05号 6.103515625e-05号 零 0.0。。。 零 零 零 零 零 三十二 零 0.0。。。 零 零 零 二十六万二千一百四十四

    以下是WebGL程序中的前几个数字:

    '来自WebGL的结果', '2.7182817459106445、7.3890557289123535、20.085533142089844,

    从javascript:

    '来自javascript的结果', '2.718281828459045、7.38905609893065、20.085536923187668,

    1 回复  |  直到 6 年前
        1
  •  4
  •   Spektre    6 年前

    不是一个 WebGL网站 用户,所以我可能错了,但你的差异表明,只有首先 6-7 数字正确 WebGL网站 . 听起来很适合 32bit 浮子精度(仅 23bits 尾数)

    这个 javascript 结果在前16位是正确的,对应于 64bit double 所以你很可能比较 32位 与。 64位 计算如此精确并不奇怪。

    这里比较:

    WebGL     : 2.7182817459106445 ,7.3890557289123535 ,20.085533142089844  ,
    javascript: 2.718281828459045  ,7.38905609893065   ,20.085536923187668  ,
    PI float  : 2.71828174591064453,7.38905572891235352,20.08553504943847656,
    PI double : 2.71828182845904509,7.38905609893064952,20.08553692318766437,
    x87 double: 2.7182818284590451 ,7.3890560989306504 ,20.0855369231876679 ,
    

    前两行是你的号码。这个 PI 行的计算结果是 e 常数计算方式 x87 32位 64位 . 最后一行使用 x87平板电脑 内部的 e^x 实施 80bit -> 64bit .

    如你所见 WebGL网站 32位 非常接近地支持我的结论。