在 C 中测试一个高数是奇数还是偶数

Testing if a high number is odd or even in C

我正在尝试测试一个数字是偶数还是奇数。

它适用于 8 位数的数字,但当我超过 9 位数时,它看起来很奇怪。我输入的数字发生了变化。

8 位数字示例:

Enter the ID : 20202020
20202020 is even.
Program ended with exit code: 0

但是当使用 10 位数字时,它看起来像这样:

Enter an integer: 2345678915
-1949288381 is odd.
Program ended with exit code: 0
// these nr that are different, what are they? 
//Have not found any info about it either... 

代码:

#include <stdio.h>

int main() 
{ 

    int id;
    printf("Enter the Id: ");
    scanf("%d", &id);

    if(id % 2 == 0)
        printf("%d is even.\n", id);
    else
        printf("%d is odd.\n", id);
    return 0;
}

我试过将其更改为两倍,但没有帮助。

和if语句有关系吗?

 if(id % 2 == 0)

典型的int(有符号32位长)最多只能存储2,147,483,647。您的输入 2345678915 超出了这个范围。

如果您的环境支持,您可以使用 long long,它通常为 64 位长,最多可存储 9,223,372,036,854,775,807。

#include <stdio.h>

int main() 
{ 

    long long id;
    printf("Enter the Id: ");
    scanf("%lld", &id);

    if(id % 2 == 0)
        printf("%lld is even.\n", id);
    else
        printf("%lld is odd.\n", id);
    return 0;
}

另一个选项是使用 int64_t,它可能在更广泛的环境中受支持。

#include <stdio.h>
#include <inttypes.h>

int main() 
{ 

    int64_t id;
    printf("Enter the Id: ");
    scanf("%" SCNd64, &id);

    if(id % 2 == 0)
        printf("%" PRId64 " is even.\n", id);
    else
        printf("%" PRId64 " is odd.\n", id);
    return 0;
}

受@0___________的启发,只看最后一位就可以判断一个数是偶数还是奇数。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main() 
{ 

    int input;
    int is_valid_number = 1;
    size_t input_len = 0;
    char* id = malloc(1);
    if (id == NULL) {
        perror("malloc");
        return 1;
    }
    printf("Enter the Id: ");
    /* read the first line */
    while ((input = getchar()) != '\n' && input != EOF) {
        char* next_id = realloc(id, input_len + 2); /* +1 for new character and +1 for NUL */
        if (next_id == NULL) {
            perror("realloc");
            free(id);
            return 1;
        }
        /* check if the input correctly represents a number */
        is_valid_number = is_valid_number && (isdigit(input) || (input_len == 0 && input == '-'));
        /* store this digit */
        id = next_id;
        id[input_len++] = (char)input;
    }
    id[input_len] = '[=12=]';

    if (input_len == 0 || !is_valid_number)
        printf("%s is not a number.\n", id);
    else if((id[input_len - 1] - '0') % 2 == 0)
        printf("%s is even.\n", id);
    else
        printf("%s is odd.\n", id);
    free(id);
    return 0;
}

问题不在于模运算,而在于您使用的数据类型。

您的身份证号码是 int,它(在本例中)由 32 位组成。这意味着您可以使用的最大数字是 2,147,483,647,而您正在使用更大的数字。

您应该尝试使用 long,或使用超过 32 位的数字类型,例如 long long。这意味着您可以使用的最大数量是 2<sup>63</sup> - 1 = 9,223,372,036,854,775,807,解决您的问题。

因此,您应该在代码中进行以下更改:

long long id;
printf("Enter the Id: ");
scanf("%lld", &id);

This Page 很好地解释了 C++ 中可用的类型。

因为您的程序只是检查输入的数字是偶数还是奇数。它不必存储在任何地方,因此无需将其转换为任何整数类型。我们只关心最后一位能不能被二除。

整数的最大长度由 MAXINTEGERLENGHT

定义
#define MAXINTEGERLENGHT (1000000LU)

int AND(const char *str)
{
    const static char DIGITS[] = "01234567890";
    const char *wrk = str;
    const char *lastpos;
    int result = -1;
    
    if(wrk && *wrk)
    {
        result = 0;
        while(*wrk)
        {
            if(!(lastpos = strchr(DIGITS, *wrk++)))
            {
                result = -1;
                break;
            }
        }
        if(result != -1)
            result = (lastpos - DIGITS) & 1;
    }
    return result;
}


int main(void)
{
    char number[MAXINTEGERLENGHT];
    fgets(number, sizeof(number), stdin);
    number[strlen(number) - 1] = 0;

    switch(AND(number))
    {
        case -1:
            printf("%s is invalid\n", number);
            break;
        case 1:
            printf("%s is odd\n", number);
            break;
        case 0:
            printf("%s is even\n", number);
            break;
    }
}

https://godbolt.org/z/33dG3a

例如非常长的结果:

x86-64 gcc 10.2

Program returned: 0
Program stdout

465954328762383465734826523743653247234684327563474368743634784368754386565465634623456435457656735643565465465645455445654543424536565434535464564564564564564564564564565464564564564556546564545643563456 is even

这个问题来自于这样一个事实,正如每个人所提到的,您正在尝试拟合更多信息,以了解可以包含在带符号(32 位)整数中的内容。

尽管如此,我觉得其他答案只是把罐子往下踢,所以我将为您提供一个解决方案,该解决方案也适用于非常高(奇数和偶数)的数字(最多 BUFFER_SIZE 位...):

#include <stdio.h>

#define BUFFER_SIZE 1024
int main(int argc, char  **argv) {
    if (argc < 2)
        return 1;

    char buffer[BUFFER_SIZE + 1];
    
    printf("Enter the Id: ");
    fgets(buffer, BUFFER_SIZE, stdin);
    unsigned len = strlen(buffer);
    buffer[len -1] = '[=10=]'; // remove '\n' from fgets
    
    // you might want to check that the user input a valid number
    // 
    
    int id = buffer[len - 2] - '0'; // get last digit

    if(id % 2 == 0)
        printf("%s is even.\n", buffer);
    else
        printf("%s is odd.\n", buffer);
    return 0;
}

输出:

Enter the Id: 6734863486834863486348648564386803486438683456438658438764568435864783
6734863486834863486348648564386803486438683456438658438764568435864783 is odd.