+ 14
Is there no data type which can store 100! In C++?
I heard many people on CodeChef.com and SoloLearn saying that In C++, no data type can store factorials of nos > 50; Then why is double able to do so? They emphasize use of arrays etc and make the task more complex... Eg = double fac(int x) { if(no==1) return 1; else return n*fac(n-1); } int main() { cout.precision(0); cout<<fac(100)<<endl; // Correctly prints 100! // 9332621544394410.... } Then why dont they realize that C++ also has a long double type, which can print 999! correctly?
13 Respostas
+ 34
Did you consider to treat the value as string? I tried addition and subtraction for large integers, I think multiplication is also supposed to be carried our in same manner as @Ace said.
Code of addition and subtraction :
https://code.sololearn.com/cLghDLF3cDrg/?ref=app
+ 15
@StillSoul
Because I want to prove that double isn't as small as it is thought of...
+ 13
@Ace
But sir, double is returing 100% accurate value!,
when I use - cout.precision(0) and cout.setf(ios::fixed)...
+ 12
@Ace
But yes sir, I wont be able to extract digits and all...
+ 12
@Shamima Yasmin
Please read the description as well...
+ 10
@Kinshuk Vasisht
You show 15 precision digits (your number isn't complete).
This program calculates 100! as best a double can:
https://code.sololearn.com/cmNS1d2qi84I/?ref=app
This program detects (within 1 step) where precision is lost (via a modulus quirk): https://code.sololearn.com/c11kVGy5Jn2C/?ref=app
But it's an accident (it's actually lost at 18!). You do need BIGINT, not doubles.
"Max safe integer" stored in doubles (aka: float64) is: 9007199254740991 = (2^53 - 1)
Add 1 to that value and it collides with itself (try out in javascript, below)
18! = 6402373705728000 SAFE
19! = 121645100408832000 UNSAFE
(19! - 1) collides with 19!
(19! + 1) collides with 19!
19!-21! do not show precision loss because significant digits are shifted left by multiplicative zeros:
4 * 5 + 1 zero
10 + 1 zero
14 * 15 + 1 zero
20 + 1 zero
Javascript double/float64 visualizer (including UNSAFEs and underflow)
https://code.sololearn.com/WYCTOysAGnLv/?ref=app
+ 8
Thing is..why d you need to store 100! ?
You can always use math
+ 7
@Ty Ler : Nice answer.
Overflow: CPUs also have two flags named OVERFLOW and CARRY.
Hairsplitting: Integer underflow sets 0000 to 1111 (all 0's to 1's) then counts DOWN to 0000 again; this rollover is exactly the same whehter it's signed or not (it's why signed and unsigned can be assigned to each other with no bit twiddling).
Float underflow is 0-1 and means your value is below the "minimum negative exponent" used to build floats, causing lost precision.
+ 6
Here is a link that explains the limits of variables.
http://www.cplusplus.com/doc/tutorial/variables/
A few points to note is over flow and not all computers are the same. If you have overflow in your variables your not going to be able to tell that you did overflow unless a negative is printed out or you double check your answer on a calculator. For instance if you create an unsigned integer and set the value to 0 and minus 1. You will get underflow which will print out the highest possible number for the int. Same idea happens in overflow.
Not all compilers are the same. Some can vary and make variables different sizes. In the link I provided note under the fundamental data type section that by each variable theirs a sentence that says "At least X bits." Some compilers may vary but at the very least they will be X amount of bits.
Another note when finding large positive numbers. Make your variables unsigned as this will double the number of positive numbers that can be represented but this does not change the number of bits in the number.
Example: A signed variable that can hold the numbers -2 - 2 can also hold the numbers
0 - 4 if unsigned.
All variables are signed by default so you dont have to say "signed int" but you can if you want. When you want to unsign an int you type "unsigned int".
+ 6
That ..is a weird argument..
+ 6
^-^ ? Okay..
+ 4
@Kirk Schafer
This is what I get Sir on running the code in my question...
100! =
93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032
Thus, there is an error in the value...
Ill try learning some other way...
Thank you!
+ 4
@Ace
Yes sir...
I'll try finding one for a better result...