c-反向导致溢出的未签名int数字



输入一个无符号的int,对其进行反向,然后查看其是否仍处于范围,如果是,则打印反向号码,如果不是,则打印您的号码不超出范围

#include <stdio.h>
#include <stdlib.h> 
#include <limits.h>
int main() {
    unsigned int a = UINT_MAX; // 0xffff
    printf("max unsigned int = %unn", a);
    unsigned int x = 0;
    printf("please enter any unsigned int,nit will show the reverse number if it's in rangen(enter 10 digit only)nn");
    while (scanf("%u", &x) != EOF) {
        //printf("x =  %un", x); 
        // above %d will print each UINT's binary oder, ex: enter 4294967292, x = -1 
        // if change %u, it will print entered number, ex: enter 4294967292, x = 4294967292 
        unsigned int temp = x, result = 0;
        int m = 0;
        while (temp > 0) {
            unsigned int digit = temp % 10;
            if (result > 429496729) {
                m++; //if reversed 9digits is already bigger 429496729, 
                //then 'result =  result * 10 + digit', it will have over flow problem.
            }
            result = result * 10 + digit;
            temp /= 10;
            if (temp == 0) break;
        }
        printf("m=%dn", m);
        if (m >= 1)
            printf("out of rangen");
        else
            printf("result is %un", result);
        printf("n");       
    }
    return 0;
}

您永远不会返回相反的数字,您返回的只是最终(最右)数字。

和您的函数不会"返回自身",它返回呼叫自己的结果,它不相同。

您的溢出测试不正确,因为您将unsigned int result的值与此类型范围更大的值进行比较,因此测试始终失败。

有两种检查溢出的方法:

  • 利用无符号算术的优势,您可以比较结果小于先前的结果。

  • 另外,您可以比较result是否大于UINT_MAX / 10,或者如果数字大于UINT_MAX % 10是否相等。此方法适用于所有整数类型,未签名和签名。

这是修改的代码:

#include <stdio.h>
#include <limits.h>
int main(void) {
    unsigned int x;
    printf("max unsigned int = %unn", UINT_MAX);
    printf("please enter any unsigned int,n"
           "it will show the reverse number if it is in rangen"
            "(enter 10 digit only)nn");
    while (scanf("%u", &x) == 1) {
        unsigned int temp = x, result = 0;
        int overflow = 0;
        while (temp > 0) {
            unsigned int digit = temp % 10;
            if (result > UINT_MAX / 10
            ||  (result == UINT_MAX / 10 && digit > UINT_MAX % 10)) {
                overflow++; // the result will not fit
                break;
            }
            result = result * 10 + digit;
            temp /= 10;
        }
        if (overflow)
            printf("out of range for unsigned int typenn");
        else
            printf("result is %unn", result);
    }
    return 0;
}

感谢您的回答,非常感谢!1.关于"如果结果大于uint_max/10的比较,或者如果数字大于uint_max%10。

是(结果== uint_max/10&amp; amp; digit> uint_max%10))吗?我假设输入以下数字(提醒:仅在uint_max中输入数字)

  • unsigned int 4294967295(10Digit),反向将为592769492(4)/out范围
  • 未签名的INT 4294967294(10Digit),反向将为492769492(4)/OUT范围

  • 未签名的INT 4227694924(10Digit),反向将为429496722(4)/in范围

  • 未签名的INT 927694924(9Digit),反向为429496729/in范围

  • 最接近的输入是3927694924我可以想到的,它将适合(结果== uint_max/10&amp; amp; amp; digit> uint_max%10)/range

但是,我对签名的INT也做了同样的操作,请在下面查看代码,但我不确定如何应用您的签名int方法:

#include <stdio.h>
#include <limits.h>
int main(void) {
    int x;
    printf("max int = %dn", INT_MAX);
    printf("min int = %dnn", INT_MIN);
    printf("please enter any integer within -2,147,483,648 ~ 2,147,483,647,n"
           "it will show the reverse number if it is in rangen"
            "(enter 10 digit or less)nn");
    while (scanf("%d", &x) == 1) {
        int temp = x, result = 0;
        int overflow = 0;
        while (temp >= INT_MIN || temp <= INT_MAX) {
            int digit = temp % 10;
            printf("temp is %un", temp);
            printf("result is %un", result);
            if (result > INT_MAX / 10 || (result == INT_MAX / 10 && digit > INT_MAX % 10)) {
                overflow++; // the result will not fit
                break;
            }
            if (result < INT_MIN / 10 || (result == INT_MIN / 10 && digit > INT_MIN % 10)) {
                overflow++; // the result will not fit
                break;
            }
            result = result * 10 + digit;
            temp /= 10;
            if(temp == 0) break;
        }
        if (overflow)
            printf("out of range for int typenn");
        else
            printf("result is %dnn", result);
    }
    return 0;
}

最新更新