-1

I'm trying to build a simple calculator that would perform multiplication and addition.

I have this code

#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;
}

this is the input for the program

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

and this is the output

0
123456789
15241578750190521
30483157500381042
91449472501143126
365797890004572504
1828989450022862520
-7472807373572376496

The problem is that when the numbers get bigger and bigger they turn to negative. Is this the problem with memory allocation for the variables and how to address this?

klutt
  • 30,332
  • 17
  • 55
  • 95
intelis
  • 7,829
  • 14
  • 58
  • 102
  • 1
    You should remove around 90% of the input and output. It is not needed to understand your problem. – klutt Nov 25 '18 at 15:18
  • Unrelated to your numbers but most likely undefined behaviour: `char operator[4];` is too small for `"krat"` and `"plus"` which are 4 characters **+** 1 for the terminating 0 long. so `operator` should be `char operator[5];` and you should limit `scanf()` to read 4 characters with `"%4s"`. – Swordfish Nov 25 '18 at 15:19
  • And reason why you didn't simply use `result = operator(result, num)`? – vgru Nov 25 '18 at 15:20
  • You have used `long`. Why? Wouldn't `short` or `int` suffice? Why, in your opinion, does C have these different types? – n. m. could be an AI Nov 25 '18 at 15:24
  • If your compiler supports it you could use `` and replace `long` with `int64_t`. – Swordfish Nov 25 '18 at 15:26
  • If you need to work with arbitrarily large numbers, you will have to use a "big numbers" library (like [GMP](https://gmplib.org/)), or implement these numbers as dynamic arrays of digits yourself. If your goal is to improve your programming skills, the latter approach might be a good idea. – vgru Nov 25 '18 at 15:26

2 Answers2

2

You're overflowing the variables.

You have two options here. Either find a solution for arbitrarily large numbers (there are libraries you can use) or accept that you cannot use numbers that are to big.

The largest number a signed 64 bit integer can hold (it's obvious from your output that long is 64 bit on your system) is 9223372036854775807 and the largest for an unsigned 64 bit is 18446744073709551615.

It could be worth mentioning that overflow only have a defined behavior for unsigned types.

Other comments

char[4] is not enough to hold "plus", since you need place for the '\0'. Use char[5] instead.

There is no reason to use pointers in this code. Unless you have a very good reason, I would suggest changing to:

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

Which in turn means that you can completely skip the function. You don't need a function to perform addition of two integers since you have the + operator to do that very thing.

Also, your usage of scanf is unsafe. You may write past the end of the array. Do this instead: scanf("%4s %li" Note the 4. It gives a maxlength for the string. On top of that, you should not check scanf for EOF. Read the documentation about what it actually does return.

klutt
  • 30,332
  • 17
  • 55
  • 95
0

Variables in programming languages have different size. In c++, long size is at least 32 bits (according to Fundamental Types (C++) (Microsoft website) and C++ Data Types (tutorialspoint website)). So, when you assign a number bigger which needs more bits to store number, it turns to negative (one's complement and 2's complement system in storing numbers).

read C++ Data Types (tutorialspoint website) about the size of each variable in c++ language and also wikipedia has good articles about one's complement and two's complement.

Hamid Ghasemi
  • 880
  • 3
  • 13
  • 32
  • 1
    *long size is 4 bytes.* – Is that so? Reference? – Swordfish Nov 25 '18 at 15:20
  • I've added a reference link to my answer. @Swordfish – Hamid Ghasemi Nov 25 '18 at 15:23
  • @n.m. watch the reference link :) – Hamid Ghasemi Nov 25 '18 at 15:25
  • Above where the sizes of types are stated it clearly reads "Microsoft Specific". Its correct in the table: *Type long (or long int) is an integral type that is larger than or equal to the size of type int.* – Swordfish Nov 25 '18 at 15:28
  • The new link says "*typical* sizes". While they are commonplace they are in no way guaranteed to be true on all platforms. – meowgoesthedog Nov 25 '18 at 15:29
  • 1
    @meowgoesthedog I read other links now, and I understood this is **at least** 4 bytes and updated my answer. – Hamid Ghasemi Nov 25 '18 at 15:29
  • Your link doesn't point to any kind of C++ language reference, but to the documentation of one implementation among many. – n. m. could be an AI Nov 25 '18 at 15:30
  • The right(tm) place to read about the sizes of types would be "5.2.4.2.1 Sizes of integer types " for C99 – Swordfish Nov 25 '18 at 15:32
  • The size is not "at least 4 bytes" either. You can safely say it's at least 32 bits. A byte doesn't have to contain 8 bits. – n. m. could be an AI Nov 25 '18 at 15:32
  • @n.m. I do not understand your last comment. you mean a byte can be more than 8 bits? do you have any reference for more information about that? – Hamid Ghasemi Nov 25 '18 at 15:37
  • 2
    [What platforms have something other than 8 bit char?](https://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char) also see `CHAR_BIT`. – Swordfish Nov 25 '18 at 15:42
  • @Swordfish Thank you – Hamid Ghasemi Nov 25 '18 at 15:42
  • 1
    It would be nice if you gave your links a title other than "link" so people know where they take them without having to click. Most websites have headlines that are appropriate as title for a link. Please also note, that relevant information to be considered to be part of your answer has to be contained within it. Use cites if appropriate. Links can become invalid and when that happens the answer is worthless. – Swordfish Nov 25 '18 at 15:45