【问题标题】:Simple calculator not working with big numbers in C简单的计算器不适用于 C 中的大数字
【发布时间】:2018-11-25 15:05:28
【问题描述】:

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

我有这个代码

#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

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

【问题讨论】:

  • 您应该删除大约 90% 的输入和输出。不需要了解您的问题。
  • 与您的数字无关,但很可能是未定义的行为:char operator[4]; 对于 "krat""plus" 来说太小了,它们是 4 个字符 + 1 用于终止 0 长.所以operator应该是char operator[5];,你应该限制scanf()"%4s"读取4个字符。
  • 你为什么不简单地使用result = operator(result, num)
  • 您使用过long。为什么? shortint 不够吗?在您看来,为什么 C 有这些不同的类型?
  • 如果您的编译器支持它,您可以使用&lt;stdint.h&gt; 并将long 替换为int64_t

标签: c algorithm


【解决方案1】:

变量溢出了。

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

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

值得一提的是,溢出仅对无符号类型具有定义的行为。

其他cmets

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

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

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

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

另外,您对scanf 的使用是不安全的。您可以写超出数组的末尾。改为这样做:scanf("%4s %li" 注意 4。它为字符串提供了最大长度。最重要的是,您不应该检查scanf 以获得EOF。阅读有关它实际返回的内容的文档。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • long 大小为 4 个字节。 – 是这样吗?参考?
    • 我在我的答案中添加了参考链接。 @剑鱼
    • @meowgoesthedog 我现在阅读了其他链接,我知道这是至少 4个字节并更新了我的答案。
    • 如果你给你的链接一个标题而不是“链接”那就太好了,这样人们就知道他们把它们带到哪里而不必点击。大多数网站都有适合作为链接标题的标题。另请注意,被视为您答案一部分的相关信息必须包含在其中。适当时使用引用。链接可能会失效,当这种情况发生时,答案就毫无价值了。
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多