简单的计算器无法在C中使用大数

时间:2018-11-25 15:05:29

标签: c algorithm

我正在尝试构建一个可以执行乘法和加法运算的简单计算器。

我有这个代码

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

long result = 0;
long *resultPointer = &result;

long plus(long *current, long num) {
    return (*current + num);
}

long krat(long *current, long num) {
    return (*current * num);
}

int main() {
    char operator[4];
    long num;

  printf("%d\n", 0);
    while(scanf("%s %li", &operator[0], &num) != EOF){
        if (num > 0) {
            if (strcmp(operator, "krat") == 0) {
                *resultPointer = krat(&result, num);
            }

            if (strcmp(operator, "plus") == 0) {
                *resultPointer = plus(&result, num);
            }

            printf("%li\n", result);
        }
    }

    return 0;
}

这是程序的输入

plus 123456789
krat 123456789
plus 0
krat 2
krat 3
krat 4
krat 5
krat 6

这是输出

0
123456789
15241578750190521
30483157500381042
91449472501143126
365797890004572504
1828989450022862520
-7472807373572376496

问题在于,当数字越来越大时,它们变为负数。这是变量的内存分配问题以及如何解决的问题吗?

2 个答案:

答案 0 :(得分:2)

您正在溢出变量。

您在这里有两个选择。要么找到任意大数字(可以使用的库)的解决方案,要么接受不能使用大数字的解决方案。

一个有符号的64位整数可以容纳的最大数字(从您的输出中很明显long是系统上的64位)是9223372036854775807,而一个无符号的64位的最大数字是18446744073709551615。

值得一提的是,溢出仅对未签名类型具有定义的行为。

其他评论

char[4]不足以容纳“加号”,因为您需要'\0'的位置。请改用char[5]

没有理由在此代码中使用指针。除非您有很好的理由,否则我建议更改为:

long plus(long current, long num) {
    return current + num;
}

这又意味着您可以完全跳过该功能。您不需要一个函数来执行两个整数的加法运算,因为您有+运算符可以执行此操作。

此外,您使用scanf是不安全的。您可以写到数组末尾。改为执行此操作:scanf("%4s %li"注意4.它给出了字符串的最大长度。最重要的是,您不应在scanf中检查EOF。阅读有关其实际返回结果的文档。

答案 1 :(得分:0)

编程语言中的变量大小不同。在c ++中,long的大小至少为32位(根据Fundamental Types (C++) (Microsoft website)C++ Data Types (tutorialspoint website))。因此,当您分配一个更大的数字并需要更多的位来存储数字时,它将变为负数(存储数字时为1的补码和2的补码系统)。

C++ Data Types (tutorialspoint website)阅读有关c ++语言中每个变量的大小的信息,维基百科也有关于one's complementtwo's complement的不错的文章。