c中的反向整数会产生溢出

c中的反向整数会产生溢出,c,C,我正在用c语言解决leetcode中的反整数问题,但它在sum=sum+rem*10;行上给出了运行时错误 runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int' 这是代码 #define INT_MAX 2147483647 #define INT_MIN -2147483648 int reverse(int x){ int sum=0,rem=0;

我正在用c语言解决leetcode中的反整数问题,但它在sum=sum+rem*10;行上给出了运行时错误

runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int'
这是代码

#define INT_MAX 2147483647
#define INT_MIN -2147483648

int reverse(int x){
    int sum=0,rem=0;
    int p;
    if(x > INT_MAX || x < INT_MIN){return 0;}
    if(x==0){return 0;}
    if(x<0){p=x;x=abs(x);}
    while(x%10==0){x=x/10;}

    while(x>0){
        rem=x%10;

        if(sum > INT_MAX || sum*(-1) < INT_MIN){return 0;}        
        sum=sum*10+rem;

        x/=10;
    }
    if(p<0){sum=sum*(-1);return sum;}
    else{return sum;}
}

首先,您不应该为INT_MAX和INT_MIN定义自己的值,而是应该包括定义这些值的值

第二,这:

sum > INT_MAX 
将永远不会为true,因为sum不能保存大于INT_MAX的值。因此您不能执行操作,然后检查是否溢出。你可以做的是先检查操作,然后做一些代数来防止溢出

if ( INT_MAX / 10 < sum) return 0;
sum *= 10;
if ( INT_MAX - rem < sum) return 0;
sum += rem;

首先,您不应该为INT_MAX和INT_MIN定义自己的值,而是应该包括定义这些值的值

第二,这:

sum > INT_MAX 
将永远不会为true,因为sum不能保存大于INT_MAX的值。因此您不能执行操作,然后检查是否溢出。你可以做的是先检查操作,然后做一些代数来防止溢出

if ( INT_MAX / 10 < sum) return 0;
sum *= 10;
if ( INT_MAX - rem < sum) return 0;
sum += rem;

一种方法(虽然不是性能最优,但很简单)是将整数转换为字符串,然后还原字符串,然后再转换回整数

下面的解决方案适用于正整数-我将把它留给OP来扩展它以处理负整数

可能看起来像:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int reverse(const int n)
{
    if (n < 0)
    {
        printf("Handling of negative integers must be added\n");
        exit(1);
    }

    char tmp1[100];
    char tmp2[100] = { 0 };
    sprintf(tmp1, "%d", n);
    printf("Input : %s\n", tmp1);
    size_t sz = strlen(tmp1);
    for (size_t i = 0; i < sz; ++i)
    {
        tmp2[i] = tmp1[sz-i-1];
    }

    int result = tmp2[0] - '0';
    char* p = tmp2+1;
    while(*p)
    {
        if ((INT_MAX / 10) < result)
        {
            printf("oh dear: %d can't be reversed to int\n", n);
            exit(1);
        }
        result = result * 10;
        if ((INT_MAX - (*p - '0')) < result)
        {
            printf("oh dear: %d can't be reversed to int\n", n);
            exit(1);
        }
        result += *p - '0';

        p++;
    }

    return result;
}

int main()
{
    printf("Output: %d\n", reverse(123));
    printf("Output: %d\n", reverse(123456789));
    printf("Output: %d\n", reverse(1234567899));
    return 0;
}

一种方法(虽然不是性能最优,但很简单)是将整数转换为字符串,然后还原字符串,然后再转换回整数

下面的解决方案适用于正整数-我将把它留给OP来扩展它以处理负整数

可能看起来像:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int reverse(const int n)
{
    if (n < 0)
    {
        printf("Handling of negative integers must be added\n");
        exit(1);
    }

    char tmp1[100];
    char tmp2[100] = { 0 };
    sprintf(tmp1, "%d", n);
    printf("Input : %s\n", tmp1);
    size_t sz = strlen(tmp1);
    for (size_t i = 0; i < sz; ++i)
    {
        tmp2[i] = tmp1[sz-i-1];
    }

    int result = tmp2[0] - '0';
    char* p = tmp2+1;
    while(*p)
    {
        if ((INT_MAX / 10) < result)
        {
            printf("oh dear: %d can't be reversed to int\n", n);
            exit(1);
        }
        result = result * 10;
        if ((INT_MAX - (*p - '0')) < result)
        {
            printf("oh dear: %d can't be reversed to int\n", n);
            exit(1);
        }
        result += *p - '0';

        p++;
    }

    return result;
}

int main()
{
    printf("Output: %d\n", reverse(123));
    printf("Output: %d\n", reverse(123456789));
    printf("Output: %d\n", reverse(1234567899));
    return 0;
}
但它在sum=sum+rem*10;行上给出了运行时错误

runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int'
要测试正和rem的潜在int溢出,请事先与int_MAX/10和int_MAX%10进行比较

    if (sum >= INT_MAX / 10 && (sum > INT_MAX / 10 || rem > INT_MAX % 10)) {
      // overflow
    } else {
      sum = sum * 10 + rem;
    }
处理底片

注意x=INT\u MIN。。。x=-x;。这就是int溢出和未定义的行为

有时,通过将正数转换为负数来解决正数和负数的整数问题是很有趣的,这是你唯一的希望。狂笑

小于零的int值比大于零的int值多1倍。所以当x>0时,x=-x总是定义得很好

但它在sum=sum+rem*10;行上给出了运行时错误

runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int'
要测试正和rem的潜在int溢出,请事先与int_MAX/10和int_MAX%10进行比较

    if (sum >= INT_MAX / 10 && (sum > INT_MAX / 10 || rem > INT_MAX % 10)) {
      // overflow
    } else {
      sum = sum * 10 + rem;
    }
处理底片

注意x=INT\u MIN。。。x=-x;。这就是int溢出和未定义的行为

有时,通过将正数转换为负数来解决正数和负数的整数问题是很有趣的,这是你唯一的希望。狂笑

小于零的int值比大于零的int值多1倍。所以当x>0时,x=-x总是定义得很好


如果x>INT_MAX | | x2147483647,对吗?如果x>=0,则变量p未初始化成员-并非所有整数值都可以反转,仍然适合整数fx>INT_MAX | x2147483647,对吗?如果x大于等于0,则变量p未初始化使用。成员-并非所有整数值都可以反转,但仍然适合整数