【问题标题】:MSVC 2019 long long variable [duplicate]MSVC 2019 long long 变量 [重复]
【发布时间】:2020-05-06 01:00:28
【问题描述】:

我正在使用 MSVC 2019。

所以,我刚刚搜索了here。 他们说long long 是 8 个字节,值的范围是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。

所以,我认为这是可行的:

long long a = 2147483648 + 2147483648;
printf("%lld", a);

我以为它会打印4294967296,等于2147483648 + 2147483648

但它向我打印0.....

所以,这次我尝试了一点不同:

long long a = 2147483648;
printf("%lld", a + a);

它打印4294967296!!!

所以这里有两个问题。

FIRST:这些代码有什么区别?

第二个:为什么第一个代码给了我错误的数字(0)?

提前致谢:)

【问题讨论】:

  • 你的字面量仍然是int 大小。
  • @Amadeus,也可以,这是他/她的问题。
  • @DanielA.White 我知道我应该使用类似2147483628LL 的东西。但是,为什么第二个代码尽管只使用了 2147483628 仍然有效?
  • 您不应该对您的问题进行双重标记,因为 C 编译器与 C++ 编译器不同,它们可能使用不同的规则。而是根据您实际使用的编译器进行标记
  • @HoseongJeon 因为a 的类型是long long,此时它不是文字。

标签: c++ c


【解决方案1】:

2147483648 + 2147483648 的结果取决于 2147483648 的类型,它不考虑您稍后将结果存储到 long long 变量中。

MSVC 的 C 编译器不符合 C99 或更高版本的标准,它使 2147483648 具有类型 unsigned long,这是一个 32 位类型。 (这是 C90 中的正确行为)。那么加法的结果就是(unsigned long)0,按照无符号算术的定义。

【讨论】:

  • 好的,知道了。然后如果我加三倍,像这样:long long a = 2147483648 + 2147483648 + 2147483648;,它给我21474836482147483648 + 2147483648 = 0,不是0 + 2147483648 = -2147483648,因为02147483648int
  • 啊……我头晕了……哈哈
【解决方案2】:

常量2147483648 是一个unsigned int(或unsigned long)字面量,因此在您使用的平台上是一个4 字节的值。因此,当您将两个这样的常量加在一起时(如在您的第一个代码 sn-p 中),该操作以 4 个字节执行,并溢出(给零)。只有执行加法之后,结果才会提升为long long(但是,到那时,损坏已经完成)。

在您的第二个代码 sn-p 中,您添加了两个显式声明为 long long 的变量,因此,添加是作为 8 字节操作执行的。

要“修复”第一个 sn-p,并强制常量为 8 字节值,您需要添加 LL(或 ll)后缀:

long long a = 2147483648LL + 2147483648LL;

【讨论】:

    【解决方案3】:

    FIRST:这些代码之间有什么区别?

    long long a = 2147483648 + 2147483648;
    

    这实际上按 GCC 的预期工作(它打印 4294967296),但 VC++ 打印 0

    long long a = 2147483648;
    

    结果不同,因为在第一种情况下,整数文字被添加为int,而不是long long,因此中间结果溢出。

    在第二种情况下,加法是正确的,因为没有溢出,因为 + 运算符与 long long 操作数一起使用。

    第二个:为什么第一个代码给了我错误的数字(0)?

    除非您指定类型后缀,否则整数文字默认类型为int。 C++ 编译器不会自动加宽整数(即使在这种情况下上下文和开发人员的意图很明确)。

    所以这段代码...

    long long a = 2147483648 + 2147483648;
    

    ...等价于:

    int x = 2147483648;
    int y = 2147483648;
    int z = x + y;
    long long a = z;
    

    您可以通过使用long 整数文字后缀来解决此问题:LL:

    long long a = 2147483648LL + 2147483648LL;
    

    【讨论】:

    • 你的等价在任何 32 位 int 的系统上都不成立(因为常数对于 int 来说太大了,因此有一些其他类型)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2021-04-28
    • 1970-01-01
    • 2016-06-06
    相关资源
    最近更新 更多