1

I have this very simple function that checks the value of (N^N-1)^(N-2):

int main() {

 // Declare Variables
 double n;
 double answer;

 // Function
 cout << "Please enter a double number >= 3: ";
 cin >> n;

 answer = pow(n,(n-1)*(n-2));
 cout << "n to the n-1) to the n-2 for doubles is " << answer << endl;
}

Based on this formula, it is evident it will reach to infinity, but I am curious until what number/value of n would it hit infinity? Using a loop seems extremely inefficient, but that's all I can think of. Basically, creating a loop that says let n be a number between 1 - 100, iterate until n == inf

Is there a more efficient approach to this problem?

Adib
  • 1,282
  • 1
  • 16
  • 32
  • As a side note you say N^((N-1)^(N-2)) which is pow(n,pow(n-1,n-2)); not pow(pow(n,n-1),n-2); – tolanj Oct 10 '14 at 21:31
  • Woops! Sorry, it's (N^N-1)^(N-2) – Adib Oct 10 '14 at 21:32
  • 2
    Are you asking what is the maximum value that can be stored in a double variable? – VAndrei Oct 10 '14 at 21:32
  • Possibly that is the case - the maximum value that can be stored in a double variable – Adib Oct 10 '14 at 21:33
  • Cool! I found the value here: http://stackoverflow.com/questions/3793838/which-is-the-first-integer-that-an-ieee-754-float-is-incapable-of-representing-e It seems the largest number for double is 9,007,199,254,740,993 (2^53 + 1). – Adib Oct 10 '14 at 21:43
  • @AdibBehjat: No, that's very different. `2^53 + 1` is the _smallest integer_ that cannot be represented _exactly_. – Mooing Duck Oct 10 '14 at 21:57
  • 1
    In GCC for x64, the largest number that doubles can hold is ~1.79769e+308 (closer to 2^1023), which is _waaaay_ bigger than what you say. – Mooing Duck Oct 10 '14 at 21:59
  • Thanks Mooing. I'm very new to this idea of IEEE754 and GCC standards. Is there a good document to have as a reference for all these values? (Max, min...etc) – Adib Oct 10 '14 at 22:02

2 Answers2

1

I think you are approaching this the wrong way. Let : F(N) be the function (N^(N-1))(N-2)

Now you actually know whats the largest number that could be stored in a double type variable is 0x 7ff0 0000 0000 0000 Double Precision

So now you have F(N) = max_double just solve for X now. Does this answer your question?

Sayu Sekhar
  • 169
  • 5
  • 1
    Can you show what the inverse for OP's function would look like? I tried asking WolframAlpha to no avail: http://www.wolframalpha.com/input/?i=inverse+of+x^%28%28x-1%29%28x-2%29%29 – Svalorzen Oct 10 '14 at 21:50
  • This is a great approach! Definitely very efficient because it follows a mathematical method. To be honest, though, how would I code this? I haven't coded anything that would include double precision method (in essence, I'm not sure how to use 7ff0 0000 0000 0000 and conduct mathematical operations with it) – Adib Oct 10 '14 at 21:53
0

Two things: the first is that (N^(N-1))^(N-2)) can be written as N^((N-1)*(N-2)). So this would remove one pow call making your code faster.

pow(n, (n-1)*(n-2));

The second is that to know what practical limits you hit, testing all N will literally take a fraction of a second, so there really is no reason to find another practical way.

You could compute it by hand knowing variable size limits and all, but testing it is definitely faster. An example for code (C++11, since I use std::isinf):

#include <iostream>
#include <cmath>
#include <iomanip>

int main() {
    double N = 1.0, diff = 10.0;
    const unsigned digits = 10;

    unsigned counter = digits;
    while ( true ) {
        double X = std::pow( N, (N-1.0) * (N-2.0) );
        if ( std::isinf(X) ) {
            --counter;
            if ( !counter ) {
                std::cout << std::setprecision(digits) << N << "\n";
                break;
            }
            N -= diff;
            diff /= 10;
        }
        N += diff;
    }
    return 0;
}

This example takes less than a millisecond on my computer, and prints 17.28894235

Svalorzen
  • 5,353
  • 3
  • 30
  • 54
  • Thanks! The issue with hand is I'm testing via integer. Whereas testing, I can code it in a way to capture the decimal point as well (the double value for n). – Adib Oct 10 '14 at 21:38
  • You can simply add smaller and smaller increments to `n`. If you give me a second I can make an example for you. – Svalorzen Oct 10 '14 at 21:39
  • I'm trying to understand your iteration process in this code. We are saying that N = 1, and then it fails the isinf(), and goes to N -= diff, which is -9 (1 - 10). Then, we divide difference by 10? (1), and finally add the new difference to N (-8). Wouldn't that make it spiral into negative infinity? (where X = 0) – Adib Oct 10 '14 at 22:38
  • 1
    I started with a value (1) which I know for a fact won't give you infinity. Thus you skip the if, and add 10 until N becomes so big the result is inf. From then on, I add 1, again until infinity. Then I add 0.1. And so on. – Svalorzen Oct 10 '14 at 22:48
  • Oh wow, I miss read the if statement bracket. Thanks for pointing that out! I guess, so far, your answer is the best! Though, I would've liked to see Sayu Sekhar's approach. Thanks Svalorzen! – Adib Oct 10 '14 at 22:56
  • 1
    @AdibBehjat Unfortunately, I don't think he has an approach. The function you want is not invertible, which means you cannot extract N given the maximum value of double. In the comment under his answer I was being kind of sarcastic. – Svalorzen Oct 10 '14 at 23:02
  • I see! Thank you for the insight and the lessons today. Learned a lot of things in one day! (I'm a self-taught programmer), and to see how we can use wolfram, learn about IEEE Standards, and just this whole exercise was very very worth it! – Adib Oct 10 '14 at 23:11