Why doesn't this function exceed the value 2^31?
-
12-04-2021 - |
题
The power function (written in c++)...
long power (long a, long b){
long result=1l;
for (int i = 0;i<b;i++){
result*=a;
}
return result;
}
Now I do some output testing...
cout<<power(2l,2l)<<endl;
cout<<power(2l,4l)<<endl;
cout<<power(2l,31l)<<endl;
cout<<power(2l,32l)<<endl;
cout<<power(2l,61l)<<endl;
Output:
4
16
-2147483648
0
0
Well there seems to be some problem with the long falling back to a 32 bit size (instead of staying as a 64 bit). I'm wondering why this doesn't work, yet if I use the long long
type, everything works fine.
Some extra info:
I'm using C++ and the compiler MinGW
I am running a 64-bit OS (Windows 7)
UPDATE:
You guys are awesome! Never thought that this type of thing would be going on.
I just checked some arbitrary PDTs using sizeof
and this is what I found...
cout<<sizeof(long)<<" "<<sizeof(int)<<" "<<sizeof(char)<<" "<<sizeof(long long)<<" "<<sizeof(uint64_t)<<endl;
Output:
4 4 1 8 8
So, it looks like my long
and int
are both 32 bit in size. Some more playing around shows that the intmax_t type is also 64 bit. Practically every single PDT is capped at 64 bits, so if I ever needed to represent a 128-bit integer, does c++ have a built in class for that (something similar to BigInteger
in Java)?
解决方案
Apparently, the type long
is 32 bits in your environment.
To get around similar problems, I would suggest that you use types like uint64_t
instead of relying in the assumption that a native type has a specific size.
EDIT
To answer your second question (does c++ have a built in class for 128-bit integers?): No, it does not. Or rather, it does not mandate one. However, if an implementation would provide one you would be able to use something like uint128_t
. Personally, I haven't seen any system that does this, though. There are third party libraries like GMP that provide that functionality, though.
其他提示
A. trying running:
cout<<sizeof(long);
To see that it's a 32 bit.
B. I guess it is a problem with the definition of your project. even if you work on a 64 bit machine it can compile a 32 bit program so you can use it both on 32 and 64 but machines.
and long is always the size of a pointer...
C. uint64_t
is the best practice.
Well long type takes 32 bits, so max positive value is 4294967296-1. But your function calculates value 5842587018385982521381124421=21^21.
In C++, as well as in C, size of int
is architecture-dependent, and that's all true, but that catch is that 32-bit signed int
's go between -2^31 and (2^31-1), not 2^31. You are indeed overflowing a 32-bit number. You should use an unsigned int
instead. That goes between 0 and (2^32-1).