0

How do you solve the below equation in some programming language of your choice?

(1-1/X)^Y

Easy!

But how about when X & Y are very big and X>>Y

e.g.

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

Looks like it should be a simple enough problem, but getting around the double precision problem before applying the power is something I was not able to figure out.

Vitaly Olegovitch
  • 3,509
  • 6
  • 33
  • 49
  • 1
    I believe it is language dependent - in some languages, I believe you would use some library that implements fixed point arithmeric, like [`BigDecimal`](http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html) in java. – amit Apr 27 '12 at 14:37
  • 2
    Use wolframalpha.com to expand into a series representation that does not have any X^Y terms, and then compute as many terms of the series as necessary to achieve your desired precision. – mbeckish Apr 27 '12 at 14:42
  • 1
    To the closevoter: How is this off topic? – Li-aung Yip Apr 27 '12 at 15:04

2 Answers2

4

Well, (1 - 1/X)^Y = exp(Y*log(1 - 1/X)). If X is very large, and much larger than Y, you can approximate the logarithm with

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

and calculate

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

If X isn't that much larger than Y, using a third or even fourth term of the Taylor series of the logarithm may be necessary.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
0

Using GNU Octave the calculations are approximate:

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

Provided that the calculation made by Daniel Fischer is correct, the code to calculate exp(-(Y/X+ Y/(2*X*X))) in Java using BigDecimal is:

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());

}
Vitaly Olegovitch
  • 3,509
  • 6
  • 33
  • 49