2

I’m trying to grab a Long Long Int and split each place number into it’s own spot in an array, in order of course, with array[0] being the largest number.

So for instance, if the number was 314, then array[0] = 3, array[1] =1, and array[2] = 4.

This is part of a calculator project for a microcontroller where I’m writing the graphics library (for fun) and using arrays to display each line.

The issue is, it needs to be able to deal with really large numbers (9,999,999,999+), and I’m having dramas with the large stuff. If the Long Long is < 1,000,000, it will writes all the numbers perfectly, but the more numbers I add, they all start to be written wrong towards the end.

For instance, 1,234,567,890 displays as 1,234,567,966.

Here’s the snippet of code I’m using:

long long int number = 1234567890;
int answerArray[10];
int numberLength = 10;

for(writeNumber = 0; writeNumber < numberLength; writeNumber++)
{
    answerArray[writeNumber] = ((int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;
}

I’m fairly sure this has to do with either the “%” and multiple data types, because any number within the Int range works perfectly.

Can you see where I’m going wrong? Is there a better way achieve my goal? Any tips for large numbers?

3
  • 1
    pow is for floating point exponentiation; it will lose precision with long long arguments, and floating point is not something you want to use on a microcontroller. Typically you would rewrite this to successively divide and mod by 10 instead. Commented Oct 27, 2020 at 23:51
  • @NateEldredge amazing i didn’t know that, so you think just do it 10 at a time? Commented Oct 27, 2020 at 23:53
  • 1
    Yes, it's easier if you fill the array from right to left. Commented Oct 27, 2020 at 23:54

2 Answers 2

3

The signature of pow is

double pow(double x, double y);

When you call the function, the computation will implicitly use floating point. That is why it is no longer exact as pure integer operations.

In addition, you have to be careful how you cast to int.

In your question, you have

((int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;

The parentheses do not match, so I will assume you meant:

(int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;

However, here you cast a number that may exceed the range of int before you apply the modulo 10 operation. That can result in an integer overflow. The code is doing the same as if you had written:

((int)(number / pow(10, (numberLength - 1 - writeNumber)))) % 10;

To avoid the overflow, it would be better to perform the modulo operation first. However, you are dealing implicitly with double at this point (because of pow), so it is not ideal either. It is best to stick with pure integer operations to avoid these pitfalls.

Sign up to request clarification or add additional context in comments.

Comments

2

Your issue is that you're casting what is potentially a very large number to an int. Look at the iteration when writeNumber is numberLength-1. In that case, you're dividing a long long by 1 and then forcing the result into an int. Once number becomes larger than 2^31-1, you're going to run into problems.

You should remove the cast altogether as well as the call to pow. Instead, you should iteratively grab the next digit by modding out by 10 and then dividing number (or a copy of it) by 10.

E.g.,

int index = sizeof(answerArray)/sizeof(answerArray[0]);
for (long long x=number; x>0; x /= 10) {
    answerArray[--index] = x%10;
}

4 Comments

sizeof(answerArray) should be the number of elements, sizeof answerArray / sizeof *answerArray.
Thank you! And modding a long long int will still work fine because it’s a whole number?
It will indeed.
As long as it is non-negative. For negative operands, % can produce negative results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.