【问题标题】:C code not output the right number for long long intC 代码没有为 long long int 输出正确的数字
【发布时间】:2019-11-24 01:21:40
【问题描述】:

我正在尝试使用以下代码获取 long long int 的大小限制:

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

我希望它是 -9223372036854775808 到 9223372036854775807。上面的代码有什么问题?

【问题讨论】:

标签: c


【解决方案1】:

上面的代码有什么问题?

1 &lt;&lt; (bits-1)int 类型的整数常量 移到其范围之外,并导致整数溢出和未定义行为

您可能需要考虑转移 long long 而不是 int

1LL << (bits-1)

但这也是整数溢出和未定义的行为,因为它会将 1 移到 long long 范围之外。

E1 E2 在结果类型中是可表示的,那么这就是结果值;否则,行为未定义。 C11dr §6.5.7 4


要便携查找long long 的范围,请使用LLONG_MIN, LLONG_MAX from &lt;limit.h&gt;

#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

【讨论】:

    【解决方案3】:

    1 是一个 int 字面量,因此 1 &lt;&lt; (bits-1) 是在 int 类型中完成的,这会调用未定义的行为,因为您移动的范围超过了类型的宽度。使用 1LL 代替 long long

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-06
        相关资源
        最近更新 更多