【问题标题】:High power and double precision大功率双精度
【发布时间】:2012-04-27 14:33:43
【问题描述】:

你如何用你选择的某种编程语言解决下面的方程?

(1-1/X)^Y

简单!

但是当 X 和 Y 很大并且 X>>Y 时呢

例如

(1-1/X)^Y
where 
X = 10^40
Y = 10^12

看起来这应该是一个足够简单的问题,但是在应用电源之前解决双精度问题是我无法弄清楚的。

【问题讨论】:

  • 我相信它依赖于语言 - 在某些语言中,我相信您会使用一些实现定点算术的库,例如 java 中的BigDecimal
  • 使用 wolframalpha.com 扩展为没有任何 X^Y 项的序列表示,然后根据需要计算序列的尽可能多的项以达到所需的精度。
  • 致最接近的投票者:这怎么跑题了?

标签: algorithm math numeric exponent


【解决方案1】:

好吧,(1 - 1/X)^Y = exp(Y*log(1 - 1/X))。如果X 非常大,并且比Y 大得多,您可以使用近似对数

log(1 - 1/x) = -1/x -1/(2*X^2) + O(1/X^3)

计算

exp(-(Y/X+ Y/(2*X*X)))

如果X 不比Y 大很多,则可能需要使用对数的泰勒级数的第三项甚至第四项。

【讨论】:

    【解决方案2】:

    使用GNU Octave 计算是近似值:

    octave:1> x = 10^40
    x =  1.0000e+40
    octave:2> y = 10^12
    y =  1.0000e+12
    octave:3> (1-1/x)^y
    ans =  1
    
    octave:8> exp(-(y/x + y /(2*x*x)))
    ans =  1
    

    如果 Daniel Fischer 的计算是正确的,那么在 Java 中使用 BigDecimal 计算 exp(-(Y/X+ Y/(2*X*X))) 的代码是:

    public static void main(String[] args) {
        BigDecimal x = new BigDecimal(10,MathContext.UNLIMITED).pow(40);
        BigDecimal y = new BigDecimal(10,MathContext.UNLIMITED).pow(12);
    
        BigDecimal twoXSquared = new BigDecimal(2,MathContext.UNLIMITED).multiply(x).multiply(x);
        BigDecimal yDividedByTwoXSquared = y.divide(twoXSquared);
    
        BigDecimal yDividedByX = y.divide(x);
    
    
        BigDecimal exponent = new BigDecimal(-1,MathContext.UNLIMITED).multiply(yDividedByX.add(yDividedByTwoXSquared));
        System.out.println(exponent.toEngineeringString());
    
        BigDecimal result = new BigDecimal(Math.E,MathContext.UNLIMITED).pow(exponent.intValue());
    
        System.out.println(result.toEngineeringString());
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      • 2011-05-17
      相关资源
      最近更新 更多