C代码长时间未输出正确的数字int

时间:2019-11-23 03:13:47

标签: c

我正在尝试通过以下代码获取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。上面的代码有什么问题?

4 个答案:

答案 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);
}