【问题标题】:Testing if a high number is odd or even in C在 C 中测试一个高数是奇数还是偶数
【发布时间】:2021-02-19 23:48:57
【问题描述】:

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

它适用于 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。对较大的数字使用long long,并将格式运算符更改为%lld
  • @Barmar 做什么。我们只检查数字是奇数还是偶数。就这样。不需要整数

标签: c if-statement integer


【解决方案1】:

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

您的 ID 号是 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++ 中可用的类型。

【讨论】:

  • 典型的 64 位有符号整数的限制不是 2^64-1 而是 2^63-1。 2^64-1 是典型的 64 位 unsigned 整数的限制。
  • 另外不要忘记更改 printf() 的说明符。
  • "在您的实现中, 由 32 位组成" :-) 这不是 C 本身的要求,它只指定数据类型范围的下限,而不是上限。
  • 感谢你们的 cmets 伙计们,我已经根据你们的建议编辑了答案。
  • Alberto,将您的更改合并到希望格式更好的答案中(并使用模而不是模块),如果您不喜欢它,请随时更改,我只是认为它是更好的演示文稿。跨度>
【解决方案2】:

这个问题源于这样一个事实,正如每个人都提到的那样,您正试图拟合更多信息,这些信息可以包含在有符号(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] = '\0'; // remove '\n' from fgets
    
    // you might want to check that the user input a valid number
    // https://stackoverflow.com/questions/16644906/how-to-check-if-a-string-is-a-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.

【讨论】:

  • (void)buffer; // not sure if required 这是没有意义的,不需要。
  • unsigned len = strlen(buffer); buffer[len -1] = '\0'; 有各种问题。考虑buffer[strcspn(buffer, "\n")] = '\0';
  • 我赞成你,因为你提出了一个有趣的观点,因为通常最好使用 libc 函数,但我仍然需要 len 才能获得最后一位数字。此外,我认为通过 repne scasb x86 指令查找 \0 更快,该指令很可能与优化标志一起使用。您介意详细说明各种问题吗?
【解决方案3】:

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

整数的最大长度由 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

【讨论】:

    【解决方案4】:

    典型的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] = '\0';
    
        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;
    }
    

    【讨论】:

    • 没有解决这个问题输入任何长度的数字不需要整数
    • @0___________ 你的程序只支持小于 1023 位的整数。我会更新我的答案。
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2015-07-22
    • 2014-07-26
    • 2015-03-03
    • 2011-11-12
    • 1970-01-01
    相关资源
    最近更新 更多