【问题标题】:Why do i get a wrong value for `i` integer?为什么我会得到错误的“i”整数值?
【发布时间】:2020-08-22 14:21:02
【问题描述】:

下面我有一个简单的 C++ 代码来生成长度为 18 的数字。当我调用 gen_nums 函数时,i 等于 1569325055,就好像我分配给 i 变量的数字是太大了。

#include <iostream>

using namespace std;

void gen_nums(){
    int i = 99999999999999999; 
    cout << i <<endl; 
}

int main()
{
   gen_nums();
   return 0;
}

【问题讨论】:

  • 当您打开警告时,编译器是否会说明此代码?
  • 特定架构上的数据类型具有特定的大小。 C++ 标准保证某些类型的最小大小,但不保证最大大小。也就是说,在大多数现代桌面系统(例如非嵌入式)上,整数是 4 个字节。 en.cppreference.com/w/cpp/language/types
  • 如果您在代码顶部使用#include &lt;limits&gt;,您可以在main 中写入std::cout &lt;&lt; "Maximum integer size: " &lt;&lt; std::numeric_limits&lt;int&gt;::max() &lt;&lt; std::endl;,以查看整数可以在您的系统上保存的最大值。 en.cppreference.com/w/cpp/types/numeric_limits
  • “好像我分配给i 变量的数字太大了。” -- 看起来你已经知道发生了什么。你有什么理由怀疑你的结论吗?

标签: c++ integer literals integer-overflow


【解决方案1】:

这可能是因为您为 int 分配的值超出了其范围。

当您分配一个超出其范围的 int 时,行为由实现定义。

一些编译器会将高位截断为您分配给它的整数类型的宽度。

如果你真的想使用这么大的数字,可以使用范围更大的long long

void gen_nums(){
    long long i = 99999999999999999 ; 
    cout << i <<endl; 

    //for (i = 99999999999999999; i < 999999999999999999 ; i++  ){ 
    //    cout << i  << endl; 
      
        
   // }
}

或者为了方便,你可以使用 auto

void gen_nums(){
    auto i = 99999999999999999 ; 
    cout << i <<endl; 

    //for (i = 99999999999999999; i < 999999999999999999 ; i++  ){ 
    //    cout << i  << endl; 
      
        
   // }
}

【讨论】:

    【解决方案2】:

    99999999999999999 超出了int 可以容纳的值范围。

    【讨论】:

      【解决方案3】:

      这样的任意大值不能保存在 4 字节整数数据类型中(如果您使用的是 64 位机器)。但是,如果您不确定哪种类型适合它,请寻求auto 的帮助:

      #include <iostream>
      
      void getNums() {
        // 'long int' after type deduction
        auto i = 99999999999999999;
        std::cout << i << std::endl;
      }
      
      int main(void) {
        getNums();
      
        return 0;
      }
      

      在我的例子中,i 被扣除为long 的类型。由于体系结构可能不同,因此您的系统可能会有所不同。

      另一方面,如果您想自己动手并查看 4 字节(即 32 位)整数可以容纳的最大数字,您可以使用 limits

      void getNums() {
        // 4-bytes integer on 64-bit machine
        // expands to 2,147,483,647 in my 64-bit system
        auto i = std::numeric_limits<int>::max();
      
        std::cout << i << std::endl;
      }
      

      最后,考虑启用编译器警告。这会对你有很大帮助。


      如果您想更好地了解,请参考Data Type Ranges

      【讨论】:

        【解决方案4】:

        大多数整数的最大大小为 +2147483647。你给它的数字太大,你应该使用“unsigned long long”例如。这是一个包含 c++ 中数据类型长度的页面。它是德语的,但我希望这不是问题。 http://www.mrknowing.com/2013/10/08/datentypen-in-c-wertebereich-und-speichergroesse/

        【讨论】:

        • “大多数整数的大小”是什么意思?
        • 整数有无穷多个,而且大部分都大于2147483647的量级。将其更改为“C++ 实现中int 的最大值的常见限制为 2147483647。”
        • 这里有一个很好的参考最大数:youtube.com/watch?v=4J9MRYJz9-4
        • 你能至少链接到一个英文网站吗?
        【解决方案5】:

        数据类型“int”不能容纳该值范围。

        请尝试以下代码:使用“long int”数据类型

        #include <iostream>
        
        using namespace std;
        
        
        void gen_nums(){
            long int i = 99999999999999999 ; 
            cout << i <<endl; 
        
            //for (i = 99999999999999999; i < 999999999999999999 ; i++  ){ 
            //    cout << i  << endl; 
              
                
           // }
        }
        
        
        int main()
        {
           gen_nums();
           return 0;
        }
        

        【讨论】:

        • 没有足够的答案?这个答案增加了什么其他答案没有?
        • 这不适用于 MinGW(可能也是 MSVC),其中 long 有 4 个字节大。使用long longint64_t 更安全。
        【解决方案6】:

        您需要将您使用的整数格式int(在您的以及所有其他实现中的最大值低于99999999999999999)更改为long long 格式,据我所知,它可以在某些实现中,假设最大值为9,223,372,036,854,775,807

        你得到的int(99999999999999999) = 1569325055的值是内部溢出的错误输出。

        【讨论】:

        • 1569325055 来自哪里?应该是2147483647
        • OP 声明这个数字是他使用int 得到的输出。
        • 这并不意味着这是最大值。如果我执行int x = 4294967295; std::cout &lt;&lt; x &lt;&lt; '\n'; 之类的操作,我会得到-1,这肯定不是最大值。
        • 在您的情况下,您必须写 unsigned int x = 4294967295; 才能使其工作。
        • 我知道,这不是重点。这是一个示例,表明 OP 的代码不一定会打印 int 的最大值。
        【解决方案7】:

        您应该使用 int64 而不是 int,因为给定的数字超出了 int 范围

        • _int8 nSmall; // 声明 8 位整数
        • _int16 nMedium; // 声明 16 位整数
        • _int32 nLarge; // 声明 32 位整数
        • _int64 nHuge; // 声明 64 位整数

        【讨论】:

        • “你应该使用 int32 而不是 int...” - 绝对。当标准中有完美的Fixed width integer types(如int64_t)时,您应该使用某些平台特定的类型/类型定义,这些标准适用于不同的实现。
        【解决方案8】:

        该错误的原因是 C++ 中的整数范围是 -2147483648 到 2147483647。所以您可以使用的最大数字是 2147483647。

        【讨论】:

        • C++ 中int 的范围至少是-32768+32767,通常是您所说的数字。许多嵌入式架构仍然使用 16 位整数。
        • 你上面所说的范围是short int的范围(典型位宽2字节)。整数范围是-2147483648到2147483647(典型位宽4字节)
        • @Abhijith11151:C++ 标准允许改变整数类型的大小和范围。不加限定地断言int 的范围是-2147483648 到2147483647 是不正确的。不要将这种错误信息传授给学生。而且,在写int 类型时,称它为int,而不是“整数”。
        • @Abhi 一个现代示例架构,其中int 仍然是 16 位,位于 AVR 微控制器上。这些在 Arduinos 中使用,因此初学者很有可能遇到。教导int 始终是 32 位会导致这些人极度困惑。更准确地说,int 在现代架构中通常是 32 位,但有时是 16 位。该标准仅保证它至少为 16 位。
        猜你喜欢
        • 2018-10-06
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-25
        • 1970-01-01
        • 2019-04-02
        • 1970-01-01
        相关资源
        最近更新 更多