Jump to content

Javascript problem with exp. numbers

Go to solution Solved by Nineshadow,

You don't need to calculate factorial of n to know how many 0-s it has.

It all has to do with combinations of 2 and 5, or powers of 5. It's pretty obvious that you only need to count the number of appearances of 5 (under any form)

In C/C++, the algorithm would be:

long no_0(long n){    long k=0;    long x=5;    while(x<=n)    {        k+=n/x;        x*=5;    }    return k;}

Used long because I had to use it in a problem that required that big of a number ( up to 10^9 digits of 0 at the end , or maybe 10^8 , can't recall correctly ; the actual problem was to find n such as n! has p digits of 0 at the end, where p represents the user input; see if you can figure that out ;) )

@N0ps32

 

It's more efficient and should get rid of the need to work with really large numbers.

I found an interesting challenge online where you are supposed to return the number of 0s at the end of a factorial calculation like 30!.

Now according to my calculations 30! should be around 2.652528598121911e+32.

 

Javascript can't display the number how I would like it with all 0s at the end but only in exponential notation.

My understanding of exponential notation was that I take all numbers before "e" so in this case "2652528598121911" => 16 numbers

and subtract that from my e+N like so: 32 - 16. This returns 16 which is wrong, the correct answer is 7.

I've never been too amazing in Math so this is probably the wrong approach?

How can I get the number of 0s at the end of a factorial number in Javascript?

//returns the factorial of a given numberconst getFact = (n, acc = 1) => (n > 1) ? getFact(n - 1, n * acc) : acc;const zeros = n => {  //get factorial of n  let fact = getFact(n);    //match numbers that are not exponential like 12300000, then extract the number of 0s at the end  if(fact.toString().match(/e/) === null)    return fact.toString().match(/0*$/)[0].split('').length;    //match exp. numbers  let matched = fact.toExponential().match(/\.(\d*).+(\+\d*)/);    //calculate e+(X) - number of numbers before e => 1.22e+5 = 5 - 3  return Number(matched[2]) - (matched[1].length + 1);  }
Link to comment
https://linustechtips.com/topic/469097-javascript-problem-with-exp-numbers/
Share on other sites

Link to post
Share on other sites

What you could is when multiplying your factorial count and remove the zeros at the end of your result. Then to simplify future calculations only continue with the last x digits of the result.

I verified my algorithm, each time continuing with the last 5 digits, by testing the results using a Big number library and found that it was accurate past 80,000 factorial (19995).

 

 

Iteration:

  1. current: 1           count: 0
  2. current: 2           count: 0
  3. current: 6           count: 0
  4. current: 24         count: 0
  5. current: 12         count: 1
  6. current: 72         count: 1
  7. current: 504       count: 1
  8. current: 4032     count: 1
  9. current: 36288   count: 1
  10. current: 36288   count: 2
  11. current: 99168   count: 2
  12. current: 90016   count: 2
  13. current: 70208   count: 2

 

I hope this helps.

Link to post
Share on other sites

You don't need to calculate factorial of n to know how many 0-s it has.

It all has to do with combinations of 2 and 5, or powers of 5. It's pretty obvious that you only need to count the number of appearances of 5 (under any form)

In C/C++, the algorithm would be:

long no_0(long n){    long k=0;    long x=5;    while(x<=n)    {        k+=n/x;        x*=5;    }    return k;}

Used long because I had to use it in a problem that required that big of a number ( up to 10^9 digits of 0 at the end , or maybe 10^8 , can't recall correctly ; the actual problem was to find n such as n! has p digits of 0 at the end, where p represents the user input; see if you can figure that out ;) )

@N0ps32

 

It's more efficient and should get rid of the need to work with really large numbers.

i5 4670k @ 4.2GHz (Coolermaster Hyper 212 Evo); ASrock Z87 EXTREME4; 8GB Kingston HyperX Beast DDR3 RAM @ 2133MHz; Asus DirectCU GTX 560; Super Flower Golden King 550 Platinum PSU;1TB Seagate Barracuda;Corsair 200r case. 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×