【问题标题】:How to solve a runtime error problem like " signed integer overflow: 2147483644 + 4 cannot be represented in type 'int' "?如何解决运行时错误问题,如“有符号整数溢出:2147483644 + 4 不能用类型'int'表示”?
【发布时间】:2019-12-24 07:23:45
【问题描述】:

我什至尝试使用 long int 代替 int,但编译器执行时间过长,并且仍然没有给出任何输出。

我正在使用 CS50 的 IDE。

这是导致问题的代码:

int sum_alt = 0;
int sum_rest = 0;
int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i <= count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

如何解决这个问题?

这是完整的代码:

#include <stdio.h>
#include <cs50.h>

int main(void)
{
long long Cardnumber;

//Typos correction + User input
do
{
    Cardnumber = get_long_long("Number: ");
}
while(Cardnumber < 0);

int count = 0;
long long counter = Cardnumber;

//To count the number of digits
while(counter != 0)
{
    counter = counter / 10;
    count++;
}

//Declaring an array for cardnumber
printf("%i", count);
int number[count];

if((count != 13) && (count != 15) && (count != 16))
{
    printf("INVALID\n");
}

for(int access = 0; access < count; access++)
{
    number[access] = Cardnumber % 10;
    Cardnumber = Cardnumber / 10;
}

int originalnumber[count];

for(int i = 0; i < count; i++)
{
    originalnumber[i] = number[i];
}

long long int sum_alt = 0;
long long int sum_rest = 0;
long long int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i < count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

if(total % 10 == 0)
{
    if(((count == 13) || (count == 16)))
    {
        if((originalnumber[12] == 4) || originalnumber[15] == 4)
        {
            printf("VISA\n");
        }
        else if(originalnumber[15]== 5)
        {
            if(originalnumber[14] == 1 || originalnumber[14]== 2 || originalnumber[14] == 3 || originalnumber[14] == 4 || originalnumber[14] == 5)
            {
                printf("MASTERCARD\n");
            }
        }

        else
        {
            printf("INVALID\n");
        }
    }
    else if (count == 15)
    {
        if(originalnumber[15] == 3)
        {
            if(originalnumber[15] == 4 || originalnumber[15] == 7)
            {
                printf("AMERICAN EXPRESS\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else
        {
            printf("INVALID\n");
        }
    }
}

else
{
    printf("INVALID\n");
}   

}

PS。我不明白 CS50 的 IDE 为何要花这么多时间进行计算。

【问题讨论】:

  • 您的代码不完整。你想达到什么目的?为什么 long int 需要更长的时间来计算?计算持续时间不受 count 限制吗?你是否也增加了count 的值?
  • countfor(int i = 1; i &lt; count; i=+2) 中的值是多少??
  • 数组number[]有多少个元素?如果您有 count 元素,那么您在第二个循环中阅读的内容超出了结尾。 i &lt;= count 是可疑的。
  • @chmike Count 是用户输入的信用卡号的位数。上面的代码给出了错误信息背后的背景。计数也是一个有限的数字。我不明白为什么要花这么长时间来计算输出?
  • 您发布的代码不存在您描述的问题。见minimal reproducible example

标签: c cs50


【解决方案1】:

这是因为 2147483644 + 4 = 2147483648 大于 2147483647(有符号 int32 限制)。而 64 位整数类型是 long long int,AFAIK。

应该是这样的:

long long int sum_alt = 0;
long long int sum_rest = 0;
long long int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i <= count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

附:另外,变量“count”不是按照这段代码定义的,所以可能有问题。

【讨论】:

  • 我对代码进行了适当的更改,但输出仍未得到计算。
  • "而 64 位整数类型是 long long int,AFAIK。" - 不,这不对。大小是实现定义的。如果你特别想要 64 位,你需要int64_t。检查此以获取更多详细信息:stackoverflow.com/a/13604190/3212865
【解决方案2】:

以下代码从用户那里获取一个信用卡号,检查其长度和校验和,并确定发行者。

该程序可以使用从https://ccardgenerator.com/获得的信用卡号进行测试。

这段代码的属性是

  • 它没有输入可能确实会溢出的整数
  • 它处理一个字符序列
  • Luhn 算法已正确实现(number[i]*2 的数字必须相加)
  • 我改进了测试以识别信用卡发卡机构(基于前 4 位数字);原来的代码有很多错误
#include <stdio.h>
#include <ctype.h>

int main()
{
    char buf[32];
    printf("enter credit card number: ");
    fgets(buf, sizeof(buf), stdin);

    int len = 0;
    while(isdigit(buf[len]))
        len++;
    if(len < 13 || len > 16) {
        printf("INVALID\n");
        return 1;
    }

    // verify credit card number check sum
    int checkSum = 0;
    for(int i = 0; i < len; i++) {
        int d = buf[len-i-1] - '0'; // get digit from right most to left most 
        if((i&1) == 0)
            checkSum += d;
        else
            checkSum += (d*2)%10 + (d*2)/10;
    }
    if(checkSum%10 != 0) {
        printf("INVALID\n");
        return 1;
    }

    // determine issuer (see https://www.regular-expressions.info/creditcard.html)
    int start = (buf[0]-'0')*1000 + (buf[1]-'0')*100 + (buf[2]-'0')*10 + buf[3]-'0';
    if((len == 13 || len == 16) && start/1000 == 4) {
        printf("VISA\n");
    } else if(len == 16 && ((start >= 5100 && start < 5600) || (start >= 2221 && start <= 2720))) {
        printf("MASTERCARD\n");
    } else if(len == 15 && ((start >= 3400 && start < 3500) || (start >= 3700 && start < 3800))) {
        printf("AMERICAN EXPRESS\n");
    } else if(len == 14 && ((start >= 3000 && start < 3060) || start/100 == 36 || start/100 == 38)) {
        printf("DINERS CLUB\n");
    } else if(len == 16 && (start == 6011 || start/100 == 65)) {
        printf("DISCOVER\n");
    } else if((len == 15 && (start == 2131 || start == 1800)) || (len == 16 && start/100 == 35)) {
        printf("JCB\n");
    } else {
        printf("UNKNOWN\n");
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    相关资源
    最近更新 更多