我正在尝试通过以下代码获取int main()
{
long long int from, to;
printf("signed long long int: ");
bytes=sizeof(long long int);
bits = 8* bytes;
from = -(1 << (bits-1));
to = (1 << (bits-1)) - 1;
printf(" %d bytes from %lld to %lld\n", bytes, from, to);
}
的大小限制:
signed long long int: 8 bytes from -2147483648 to 2147483647
输出为:
def _customer_resources_details(customer_id=''):
try:
res = session.query(
DbObjects.ResourceProperty.resource_id,
DivvyDbObjects.ResourceProperty.name
).filter(
DbObjects.ResourceProperty.name=='customerid'
).filter(
DbObjects.ResourceProperty.value==customer_id
).all()
return res
except Exception as e:
logger.error('_customer_resources_details ' + str(e))
我希望它是-9223372036854775808至9223372036854775807。上面的代码有什么问题?
答案 0 :(得分:3)
上面的代码有什么问题?
1 << (bits-1)
将类型int
的整数常量移出其范围,并导致整数溢出和不确定的行为。
您可能要考虑移动long long
而不是int
。
1LL << (bits-1)
这也是整数溢出和未定义的行为,因为它将1移到long long
范围之外。
E1 << E2的结果是E1左移E2位位置; ...如果E1具有带符号的类型且非负值,并且E1×2 E2 在结果类型中可表示,则它是结果值;否则,行为是不确定的。 C11dr§6.5.74
要便携式找到long long
的范围,请使用LLONG_MIN, LLONG_MAX
中的<limit.h>
。
#include <limit.h>
printf("%d bytes from %lld to %lld\n", bytes, LLONG_MIN, LLONG_MAX);
如果 long long
缺少填充(这种情况非常普遍,C并不需要),则下面将显示long long
的最大值。
#include <limit.h>
int main(void) {
long long max;
int bytes = sizeof(long long);
int bits = CHAR_BIT * bytes;
long long max_halfish = 1LL << (bits-2);
long long max = (max_halfish - 1) + max_halfish;
printf("max %lld\n", max);
}
min
就是(-max - 1)
如果,我们假定非常常见的2的补码。
答案 1 :(得分:2)
您需要在移动之前强制1
,否则将其视为int
常量:
#include <stdio.h>
int main()
{
long long int from, to;
printf("signed long long int: ");
int bytes = sizeof(long long int);
int bits = 8 * bytes;
from = -(((long long)1) << (bits-1));
to = (((long long)1) << (bits-1)) - 1;
printf(" %d bytes from %lld to %lld\n", bytes, from, to);
}
或者使用@phuclv指出的更具可读性的1LL
。
输出:
signed long long int: 8 bytes from -9223372036854775808 to 9223372036854775807
答案 2 :(得分:0)
1
是一个int常量,因此1 << (bits-1)
以int
类型完成,由于您移动的距离超过了类型的宽度,因此会调用未定义的行为。使用1LL
代替long long
值
答案 3 :(得分:0)
1是一个整数常量,更改为1LL可以得到long long int形式的结果。
int main() {
long long int from, to;
int bytes,bits;
printf("signed long long int: ");
bytes=sizeof(long long int);
bits = 8* bytes;
from = -(1LL << (bits-1));
to = (1LL << (bits-1)) - 1;
printf(" %d bytes from %lld to %lld\n", bytes, from, to);
}