選択したプログラミング言語で次の方程式をどのように解きますか?
(1-1/X)^Y
簡単!
しかし、X と Y が非常に大きく、X>>Y の場合はどうでしょうか。
例えば
(1-1/X)^Y
where
X = 10^40
Y = 10^12
それは十分に単純な問題のように見えますが、電力を適用する前に倍精度の問題を回避することは、私には理解できませんでした。
そうですね(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
、対数のテイラー級数の 3 番目または 4 番目の項を使用する必要がある場合があります。
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 による計算が正しいとすると、BigDecimalを使用してJavaexp(-(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());
}