为啥输入 12 位数字时以下代码会崩溃? [复制]

Posted

技术标签:

【中文标题】为啥输入 12 位数字时以下代码会崩溃? [复制]【英文标题】:Why does the following code crash when I input a 12 digit number? [duplicate]为什么输入 12 位数字时以下代码会崩溃? [复制] 【发布时间】:2017-12-29 12:21:22 【问题描述】:

我一直在 Coursera 上学习有关算法的课程,并尝试将我学到的知识应用到代码中。这应该是一个“分而治之”的算法,我希望这部分没问题。我遇到了一个问题,只是弄乱了它:一切正常,直到我在程序中输入一个 12 位数字。当我这样做时,它只是结束 cin 并输出所有先前排序的数字(如果之前没有数字,则为空格)。如果可以的话,如果您发现错误,请告诉我出了什么问题。这是我的代码:

#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

// setup global variable for the number of inversions needed
int inversions = 0;

// function to merge 2 sublists into 1 sorted list
vector<int> Merge_and_Count(vector<int>& split_lo, vector<int>& split_hi) 
    // setup output variable -> merged, sorted list of the 2 input sublists
    vector<int> out;
    int l = 0;
    int m = 0;

    // loop through all the elements of the 2 sublists
    for (size_t k = 0; k < split_lo.size() + split_hi.size(); k++) 
        // check if we reached the end of the first sublist
        if (l < split_lo.size()) 
            // check if we reached the end of the second sublist
            if (m < split_hi.size()) 
                // check which element is smaller and sort accordingly
                if (split_lo[l] < split_hi[m]) 
                    out.push_back(split_lo[l]);
                    l++;
                
                else if (split_hi[m] < split_lo[l]) 
                    out.push_back(split_hi[m]);
                    m++;
                    inversions++;
                
            
            else 
                out.push_back(split_lo[l]);
                l++;
                inversions++;
            
        
        else 
            out.push_back(split_hi[m]);
            m++;
        
    

    return out;


// function that loops itself to split input into halves until it reaches the base case (1 element array)
vector<int> MergeSort_and_CountInversions(vector<int>& V) 
    // if we reached the base case, terminate the loop and feed the output to the previous loop to be processed
    if (V.size() == 1) return V;
    // if we didn't reach the base case
    else 
        // continue halving the sublists
        size_t const half_size = V.size() / 2;
        vector<int> split_lo(V.begin(), V.begin() + half_size);
        vector<int> split_hi(V.begin() + half_size, V.end());

        // feed them back into the loop
        return Merge_and_Count(MergeSort_and_CountInversions(split_lo), MergeSort_and_CountInversions(split_hi));
    


// main function of the app, runs everything
int main()

    // setup main variables
    int input;
    vector<int> V;

    // get input
    cout << "Enter your numbers to be sorted (enter Y when you wish to proceed to the sorting)." << endl;
    cout << "Note: do NOT use duplicates (for example, do not input 1 and 1 again)!" << endl;
    while (cin >> input)
        V.push_back(input);

    cout << "\nThe numbers you chose were: " << endl;
    for (size_t i = 0; i < V.size(); i++)
        cout << V[i] << " ";

    // get sorted output
    vector<int> sorted = MergeSort_and_CountInversions(V);
    cout << "\n\nHere are your numbers sorted: " << endl;
    for (size_t j = 0; j < sorted.size(); j++)
        cout << sorted[j] << " ";

    // show number of inversions that were needed
    cout << "\n\nThe number of inversions needed were: " << inversions << endl;

    return 0;

【问题讨论】:

【参考方案1】:

12 位十进制数字太长,无法放入 32 位数字,这就是 int 通常的表示方式。因此,使用&gt;&gt; 读取该数字会失败,cin &gt;&gt; input 会转换为 false 值,从而终止循环。

有关处理故障模式的详细信息,请参阅operator &gt;&gt; documentation。

【讨论】:

感谢您的快速回复!我尝试使用我能找到的最大运算符,在本例中为 unsigned long long int,它使最大位数达到 20,所以我想这是我现在能做的最好的。这是一个巨大的数字,我认为无论如何我都不需要那么多数字。 @DalvAlzar - 不保证long long unsigned 能够支持大于18446744073709551615 的值。这意味着 19 位十进制数字是可以的,但 20 位可能不是(并非所有 20 位数字都保证可以表示)。【参考方案2】:

您可以使用std::numeric_limits::digits10 常量获得类型可以表示的以 10 为基数的最大位数:

std::cout << std::numeric_limits<int>::digits10 << '\n';

int 类型的最大有效位数可能为 9,而您尝试通过标准输入提供 12。程序没有崩溃,(cin &gt;&gt; input) 的条件简单地计算为false

【讨论】:

【参考方案3】:

12 位对于 32 位整数来说太多了,尝试使用 unsigned long long int,检查以下限制: http://www.cplusplus.com/reference/climits/

【讨论】:

以上是关于为啥输入 12 位数字时以下代码会崩溃? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥下面的代码会崩溃?

为啥这个 C 程序会崩溃?它编译得很好[重复]

为啥输出的数字会变成科学计数法?

为啥用excel输入长数字就变成科学记数法?

为啥 DatePicker 在 Date 变为 nil 时会崩溃? [复制]

C 中的这段代码决定一个数字是不是是素数,它会因大数而崩溃。为啥?