Large Integers and Currency

I had been wondering about that as well to be honest. So I looked through the code once more and found out that the result is actually being printed as a signed integer, despite declaring it as unsigned. I found out that the reason for this happening, is the Format Specifiers I used. I made the mistake of using the %d specifier throughout the code, which declares ‘signed’ integers … So let me correct that, using %u (unsigned int) where required, and see what happens.

#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main()
{
    uint32_t currentUnits, result;
    int32_t addUnits;
    
    printf("Enter value for current Units (unsigned integer): ");
    scanf("%u", &currentUnits);
    
    printf("Enter value for Units to add (signed integer): ");
    scanf("%d", &addUnits);

    printf("Added Units signed value: %d \n", addUnits);
    
    result = currentUnits + addUnits;
    
    printf("The sum = %u", result);
    
    return 0;
}
Enter value for current Units (unsigned integer): 0
Enter value for Units to add (signed integer): 3744000000
Added Units signed value: -550967296
The sum = 3744000000

Hmmm, interesting … Blame me for not being familiar with C! lol

I should have looked up what turned out to be Format Specifiers, instead of assuming they were some sort of temp assigned variable for input and output (scanf and printf). Even more so after scratching my head over the same thing you just pointed out! It all makes sense now though, … my bad!

So let’s go over it once more and see what the actual outcome of such a transaction would be!

  • We enter a Unit balance of 0 (unsigned) = uint32_t currentUnits
  • We then enter a value for the Fusion Ignitors we sell, 3744000000 (signed) = int32_t addUnits

Then the result (unsigned) = uint32_t result is calculated. Because we are ‘adding’ a signed integer to an unsigned integer, we have to take the C99 standard into account. This means the signed integer is converted to unsigned before the total is calculated. So instead of using the overflow value of -550967296, it actually uses 3744000000 in the calculation. This value is equal to -550967296 + 1 + uint_max = -550967295 + 4294967295 = 3744000000

So even though the signed integer addUnits will overflow by itself, it will now instead be converted to an unsigned integer before the result is calculated!

Because the value of 3744000000 is not large enough to overflow an unsigned integer, nothing unexpected will happen there!

Conclusion

You may see a (large) negative value for what you are selling, when its total worth is larger than the max ‘signed’ 32bit integer value (2,147,483,647). However, when this value is used to calculate our new Unit balance when completing the transaction, it is converted to the unsigned ‘proper’ value.

I can only imagine an issue, if Hello Games has not prevented an overflow of this ‘converted’ value. What I mean by that, is if the value of what you have to sell, is actually even more than the max value of an unsigned 32bit integer, ie. > 4,294,967,295. In case of Fusion Ignitors, this would mean selling more than 275 of them. In-game, this would not be possible, as this would require more than 55 slots. With a maximum of 48 slots, I can not imagine an in-game scenario, where the total worth of what you have to sell, is greater than the max value of an unsigned 32bit integer. Unless this would actually be possible, the calculation would always be correct.

Assuming Hello Games has indeed prevented an overflow of the value for your Units balance, you will never be able to exceed 4,294,967,295 Units. You may miss out on Units, but not lose Units, even though the total sell value may show a negative value.

So in your case, assuming you sell Fusion Ignitors at a base price of 15600000, you will not see a negative value up to 137 of them. Selling 138 Fusion Ignitors will all of a sudden show a negative value, but completing the sale is expected to add the ‘proper’ unsigned value to your Units balance.

PS

Sorry about messing up earlier! Learned my lesson, hopefully no mistakes this time :wink:

I have made some additional changes to the code, making it easier to test your own scenario, not including overflow prevention:

New code
#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main()
{
    uint32_t currentUnits, totalUnits;
    int32_t itemValue, amount, valueTotal;

    printf("Enter value for your current Units (unsigned): ");
    scanf("%u", &currentUnits);
    
    printf("Enter value in Units for item to sell (signed): ");
    scanf("%d", &itemValue);
    
    printf("Enter the amount of items to sell (signed): ");
    scanf("%d", &amount);
    
    valueTotal = itemValue * amount;
    
    printf("Total worth in Units (signed) = %d \n", valueTotal);

    totalUnits = currentUnits + valueTotal;
    
    printf("Your new total in Units (unsigned) = %u", totalUnits);
    
    return 0;
}

You can test the above code, using the link below:

3 Likes