Problem statement- calculate the product of no.s from 1 to n
Solution1- I have generated the no.s using for loop and stacked them in an array and then used multiply array elements vi to generate the result
Solution2- i have used factorial vi to calculate the product of no.s from 1 to n
Until 12 the results agree but after that when i use 13 the results start to disagree.
Attached the vi with this mail....can anyone tell me why there is no agreement of results for 13 and no.s more than that......
Thanks & Regards
Solved! Go to Solution.
The [i] is an i32 so when you multiply all the elements in the array, eventually the result is larger than an i32 can represent and it rolls over.
I made some changes in the code and tried to approach the problem in 4 different ways....Now until 20 its working fine but 21 onwards the results don't match. Attached with this mail is the vi.
That's because you are doing different methods that use different datatypes.
The Factorial subVI is using an underlying dll and its inputs are outputs are a double datatype. Doubles will have round-off errors when you get to ever larger numbers. A double has a total of 64 bits of precision, but they are designated as 1 sign bit, 11 exponent bits, and 52 mantissa bits. With factorials and products of integers, the final result is always an integer, so it is better to use integer datatypes as a U64 gives you a full 64 bits toward the integer.
And your compound arithmetic is also using doubles, and requires you do add another input for the 21 value, and change them all to U64's.
In your original example, both results are wrong because the indicator has the wrong representation.
As others have said, a factorial is a very rapidly growing function and will exceed the range of simple numeric datatypes very quickly. Even DBL can only represent about 15 significant digits, so the result for larger number is only an approximation.
You really need to put a little bit more thought into it, for example in your second example (third version) there is no need to convert to U64 three times. Initialize the shift register with a U64 of 1 (I assume you know how to change representation), but even for U64, you'll quickly run out of range (the largest number is 2^64, or 18446744073709551615, which is smaller than 21!). And no, the "Numeric" can stay at I32. Compare:
Of course what you can do is represent the number as an array of digits and do the multiplication the old fashioned way. My old example posted here can easily calculate all 35660 digits of 10000! (the code could be made orders of magnitude faster with a few advanced tricks, this is just a very simple demo)
The largest factorial for the built-in function is 170! Anything higher will result in Inf.
The factorial function only get the first 12 digits correct due to limitations of the DBL datatype (use a DBL indicator!):
170! = ~7.257415615308E+306
My code will give all of the digits of 170! correctly:
170! = 7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000
And yes, the zeroes at the end are all correct, of course. Think about it!