(C++) 2^32=0 但 2^31 * 2 有效
(C++) 2^32=0 but 2^31 * 2 works
所以我最近用 c++ 做了一个简单的计算器,除其他外,它可以计算指数,但它只能工作到 2^31。
问题来了,我的input/output如下:
I: 2^31
O: 131072
I: 2^32
O: 0
I: 13107*2
O: 262144
基本上它不能做 2^32 但它可以做 (2^31)*2,我就是不明白为什么。如果有人可以帮助我并解释为什么我会非常感激。这是计算指数的代码:
long exp(long x, int y) {
int p;
if (y % 2 == 0) {
p = 1;
}
else {
p = x;
}
while (y > 1) {
x *= x;
y /= 2;
}
return x*p;
}
即使是小数,你的函数也会给出错误的结果。
考虑:
std::cout << exp(2,4); // 16
std::cout << exp(2,5); // 32
std::cout << exp(2,6); // 16 ???
首先你需要修复函数的实现,其次使用能够表示更大数字的更大的类型:
long long exp(long long x, int y)
{
long long result = x;
while(--y)
{
result*=x;
}
return result;
}
编辑:注意它只适用于正数。
另请注意,C++ 中没有内置 "power operator"。 Operator ^
称为异或运算符,对两个数进行按位运算。
注:
int x = 0b101'111; //47
int y = 0b110'010; //50
//x^y = 0b011'101
std::cout << (x^y); //outputs 29
异或运算结果中的每一位都设置为1,如果只有一对位中的一个被设置,否则为0。
x: 0 1 0 1
y: 0 0 1 1
result: 0 1 1 0
通过将 "long" 变成 "long long" 我设法表示 2^32.
另外一个大家指出的问题是2^31是错误的,那是因为我没有考虑到即使y开始even 它可以在除以 2 时变为 奇数 ,然后当你再次潜水 2 时,它会比它应该做的少一个循环。
EX: y=6 >> 6/2 = 3 >> 3/2 = 1
编辑:我设法修复了它,如果有人感兴趣,这里是代码现在的样子:
long long exp(long long x, int y) {
int p = 1;
while (y > 1) {
if (y % 2 != 0) {
p *= x;
}
x *= x;
y /= 2;
}
return x*p;
}
据我所知,它似乎在工作。
所以我最近用 c++ 做了一个简单的计算器,除其他外,它可以计算指数,但它只能工作到 2^31。 问题来了,我的input/output如下:
I: 2^31
O: 131072
I: 2^32
O: 0
I: 13107*2
O: 262144
基本上它不能做 2^32 但它可以做 (2^31)*2,我就是不明白为什么。如果有人可以帮助我并解释为什么我会非常感激。这是计算指数的代码:
long exp(long x, int y) {
int p;
if (y % 2 == 0) {
p = 1;
}
else {
p = x;
}
while (y > 1) {
x *= x;
y /= 2;
}
return x*p;
}
即使是小数,你的函数也会给出错误的结果。 考虑:
std::cout << exp(2,4); // 16
std::cout << exp(2,5); // 32
std::cout << exp(2,6); // 16 ???
首先你需要修复函数的实现,其次使用能够表示更大数字的更大的类型:
long long exp(long long x, int y)
{
long long result = x;
while(--y)
{
result*=x;
}
return result;
}
编辑:注意它只适用于正数。
另请注意,C++ 中没有内置 "power operator"。 Operator ^
称为异或运算符,对两个数进行按位运算。
注:
int x = 0b101'111; //47
int y = 0b110'010; //50
//x^y = 0b011'101
std::cout << (x^y); //outputs 29
异或运算结果中的每一位都设置为1,如果只有一对位中的一个被设置,否则为0。
x: 0 1 0 1
y: 0 0 1 1
result: 0 1 1 0
通过将 "long" 变成 "long long" 我设法表示 2^32.
另外一个大家指出的问题是2^31是错误的,那是因为我没有考虑到即使y开始even 它可以在除以 2 时变为 奇数 ,然后当你再次潜水 2 时,它会比它应该做的少一个循环。
EX: y=6 >> 6/2 = 3 >> 3/2 = 1
编辑:我设法修复了它,如果有人感兴趣,这里是代码现在的样子:
long long exp(long long x, int y) {
int p = 1;
while (y > 1) {
if (y % 2 != 0) {
p *= x;
}
x *= x;
y /= 2;
}
return x*p;
}
据我所知,它似乎在工作。