【问题标题】:Unexpected output printing long number意外输出打印长号
【发布时间】:2016-04-03 12:07:32
【问题描述】:

尝试在 32 位机器上用 C++ 打印long。我得到了一个意外的输出。

从此代码:

long n = 5330111323L;
printf("n = %ld\n", n);
printf("can print? %s\n", LONG_MAX < 5330111323L ? "yes" : "NO");
printf("LONG_MAX = %ld\n", LONG_MAX);

我明白了:

C# 输出很好。

这个:

long n = 5330111323L;
    Console.WriteLine(n);

打印:

5330111323

两者都使用 32 位编译器。为什么我会得到这个 C++ 输出?

【问题讨论】:

  • 你觉得5330111323和2147483647哪个更大?

标签: c# c++ mingw long-integer 32-bit


【解决方案1】:

条件有误,应该是:

LONG_MAX &gt; 5330111323L ? "yes" : "NO"

n 如果低于 LONG_MAX,则可以(正确)打印,因为在所有情况下,如果n 具有n 将低于或等于LONG_MAX被声明为long

编辑:注意你也可以使用&gt;=

【讨论】:

  • &gt;= 实际上不会比&gt; 更好吗?
  • 另请注意,如果n 已明确声明为long,则根据定义,它将始终为&lt;=LONG_MAX
  • 他的代码的一个问题是他直接与整数文字常量进行比较,编译器可以根据需要扩展 - 有时不会发出警告。
  • 我没看懂你写的内容:/
  • 当你写LONG_MAX &gt; 5330111323L时,你不一定要比较两个longs。如果5330111323L 大于可能的最大值long,编译器可能会默默地将其提升为long long,而不管有人可能认为的“L”后缀会强制它被解释为long。仅在将小整数文字提升为较大类型时才会将常量强制为类型。
【解决方案2】:

在 C# 中,long 是 64 位数据类型。在 32 位上编译并不重要,它的大小仍然是 64 位。在 C++ 中,我们对long 的所有了解是,它必须拥有与int 一样多或更多的容量,并且它至少为 32 位。如果您在 c++ 中使用long long,则保证至少为 64 位,这将与您在 C# 中的内容相匹配。即使您在 C++ 中编译为 32 位,它也是 64 位。

【讨论】:

    【解决方案3】:

    sizeof(long) 在任何地方都没有固定,甚至没有“习惯”大小,实际上不建议使用这种类型(有些检查器甚至在每次使用long 时都会发出错误)。特别是,在您的系统上,long 的大小很明显是 32 位。

    附带说明,long(或任何其他非指针类型)的大小与 32 位和 64 位模式无关。

    在第三个注释中,您的检查在逻辑上不正确。当 LONG_MAX 大于该数字时,您应该打印“yes”。

    【讨论】:

    • long 的大小有些固定,它必须至少为 32 位。不知道是谁“不推荐”的;当您需要一个至少包含 32 位的整数类型时,它是合适的。
    • @PeteBecker,int 是一种很好的类型,至少可以保存 32 位。更重要的是,它通常精确地保存 32 位,这很有帮助。 Long 对 int 没有任何好处,只会增加混乱(很多人,比如 OP,倾向于认为它比 intlonger)。这就是不建议使用它的原因 - 以避免不必要的混淆。
    • int 只需要至少保持 16 位。
    • @PeteBecker,从技术上讲 - 是的。实际上,我从未见过具有 16 位整数的编译器。甚至 cppreference 也有:However, on 32/64 bit systems it is almost exclusively guaranteed to have width of at least 32 bits (see below).
    • @SergeyA,那么你很幸运。我们中的一些人在很久以前就有用于 MS-DOS 和 16 位 Windows 的 C 和 C++ 编译器。我们中的一些人甚至将它用于 8 位 CP/M-80。但是你不需要时间胶囊来获得小于 32 位的编译器ints:想想微控制器和嵌入式处理器。
    【解决方案4】:

    在 C++ 中,过大以适应其原始类型的整型文字常量可以自动解释为更长的类型,即使它们具有错误的后缀。

    #include <iostream>
    
    int main(){
        auto a=9876543210;  // ‘L’ or ‘LL’ suffix missing.
        int  b=a;           // Not even a warning
        int  c=9876543210;  // warning: "implicit constant conversion", even without suffix!
        std::cout << a << '\n' << b << '\n' << c << '\n';
    }
    

    【讨论】:

      【解决方案5】:

      您认为 5330111323(用户输入)或 2147483647(LONG_MAX)哪个更大?

      您实际上是在尝试在系统上打印一个超出长范围的值,这是对未定义行为的邀请。

      顺便说一句,在您的程序中改进以下条件。

      printf("can print? %s\n", LONG_MAX > 5330111323L ? "yes" : "NO"); //
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 2013-12-20
        • 2014-11-05
        • 2022-01-10
        相关资源
        最近更新 更多