Large Integers and Currency

I know that people have discussed the maximum units allowable during various updates of the game, and I suspect this topic has also been discussed, but I haven’t found it on several searches.

Short version: What happens when the galactic trade terminal gives you a negative number of units?

Detailed version:

According to what I have read, the maximum number of units one can have in NMS is determined by a 32 bit integer. It has been a long time since I dabbled in programming, but I believe that 32 bit signed integers occupy a range of −2,147,483,648 to 2,147,483,647. If you use 32 bits to represent an unsigned integer, it gives you a range from 0 to 4,294,967,295, with the last value representing the most units a person can have in NMS. In earlier versions I understand that when a player hit maximum, the units rolled over, so that if you were at the maximum and earned another 10 units, you would have 9 units. In later versions of the game, from what I have read, once you hit the limit, earning more units does not increase the number you have.

I don’t know how accurate all that is, because I have never tested any of it myself, nor had the resources to do so.

With the advent of multiple bases, I constructed a monstrous multi-base factory to churn out high priced products. I admit that building the factory has been a lot more fun than running it, but it runs well. While the process is tedious, it feels less like a grind than older methods of picking up large amounts of currency. I had originally planned to max out the number of units, then to focus on exploration, creative base building, and cataloguing species. But now, because running the factory is feeling more like grinding, I decided to sell all the product I had made and free up storage for other pursuits. After some research, I found a system that would give me a decent price (less than 10% below market.) I hauled the lot of them to the station to sell them.

I’m pretty sure I made several mistakes at this point. I took them to the trade terminal. I don’t know the effect of selling them to pilots, but it may have had less impact on the price offered at the trade terminal. Also, I didn’t make a point of saving before I started such a large transaction and overwrote the autosave before I considered that saving and trial and error could have answered my questions.

I went to sell the products, and the trade terminal offered me a large negative number of units for the load. I had never considered that the trade terminal might use signed integers for units. What would have happened if I had completed the transaction? I played with the number of products until I could see that when I had enough product to go over the size of a signed 32 bit integer, it rolled over and continued counting up from the negative limit. So instead of 2B units, it was offering -2B units for the load.

In the end, I decided to do it in two transactions, lacking the courage to try to unload the entire inventory without a guarantee that it wouldn’t saddle me with years of galactic debt. When I went to sell the second load, the price had dropped more than 50% below market value, so I abandoned the project for now.

So the question is this: what would have happened if I had ignored the negative number and sold the entire load?

3 Likes

Never having had that much money, I don’t know.

But if you can turn nearly 4.3 billion into a negative sum with a single transaction, I imagine there’s a place for you in Bernie Madoff’s organisation. Or Enron.

6 Likes

And give up my promising career with Lehman Brothers? No way.

I’ll give Enron this: their executive retirement benefits have been very secure.

5 Likes

Most likely the opposite of what you expected: it would have added that negative amount to the money you had, potentially making you very, very, very rich. See, the thing is, while there is an integer overflow, there is also an integer underflow. In other words, the wrap around to the other end of the spectrum happens when you cross the lowest or the highest value. And if the players money is indeed stored in an unsigned integer, it would mean that if it went below zero, it would go straight up to 4,294,967,295.
You could have just tried it and restored your game to be sure, of course.

It’s perfectly accurate. :slight_smile:

EDIT:

This post is faulty, see my correction here


Very interesting :slight_smile:

So I figured I’d make some code in C, to 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("%d", &currentUnits);
    
    printf("Enter value for Units to add (signed integer): ");
    scanf("%d", &addUnits);
    
    result = currentUnits + addUnits;
    
    printf("The sum = %d", result);
    
    return 0;
}
Enter value for current Units (unsigned integer): 0                                                                         
Enter value for Units to add (signed integer): 3744000000                                                                   
The sum = -550967296

So I entered 0 for my current amount of Units, which I have declared as an unsigned 32bit integer (uint32_t = currentUnits). I used 0 to easily see what happens.

Then I entered the value for Units to add, which I have declared to be a signed 32bit integer (int32_t = addUnits). I used a full 48 slot inventory, filled to the max with Fusion Ignitors. Of course this would not quite be possible in-game, but sufficient for the purpose of testing. The value entered equals 48 slots * stack of 5 * 15600000, the value of a Fusion Ignitor = 3744000000

Then the result is calculated by adding both values. This resulting value would also be an unsigned 32bit integer, as it would be your new Units total (uint32_t = result).

As expected the amount of Units to add, overflows, as it is greater than 2,147,483,647. The amount it overflows is equal to 3,744,000,000 - 2,147,483,647 -1 = 1,596,516,352. This means the actual value is equal to the maximum negative range value plus the amount of overflow: −2,147,483,648 + 1,596,516,352 = -550,967,296. This is the exact result shown!

So basically the expected result of selling a full 48 slot inventory of Fusion Ignitors, would result in losing quite a lot of Units… If you manage to only ‘just’ overflow the value by 1, you will lose the most… :cry:

However this may be the expected result, but because of not having verified this to happen, we can not know for sure. I am purely explaining the expected result of a calculation where an overflown signed 32bit integer is being added to an unsigned 32bit integer. In reality additional code may have been implemented to have a different result, although I honestly doubt this to be the case though. I have also assumed the core coding language to be C, where in different coding languages the results may possibly vary, although unlikely. Of course the main assumption here is oversight, where the developers have likely assumed such a case to never happen. Therefor we assume no additional coding is implemented to come to a different result.

Note:
According to the New C Standard (C99 standard, section 6.3.1.8 Usual arithmetic conversions), the following happens when dealing with both operands in the ‘addition’ explained above:

Because the 32bit signed and 32bit unsigned integers used are equal in rank, the signed 32bit integer is converted to a 32bit unsigned integer in the calculation. So basically the negative value of -550,967,296 is no longer treated as the signed type, to calculate the end result.

PS: I do find this interesting and I am sure any issues can be avoided. I will however not go into details on possible solutions, which may actually be in place, unless we verify to know for sure :wink:

4 Likes

My partner quite enjoys making units via farming & then looking around for the best deal while exploring. She is now trying to work out how to get rid of the 3 point something billion she has.
I paused at 1.4 billion. I rarely sell much, I buy most stuff yet I’m still increasing & am currently at about 1.5 billion. Once your are loaded you are kind of stuck with it.
Hopefully they bring in the ability to buy space stations or something else hideously expensive so there is some massive cash burner to help us shed excess wealth.

6 Likes

<She’s trying to get rid of 3 billions?
Tell her I am here haha :moneybag:

5 Likes

I find myself in a similar position. I have a 34 slot class S freighter, a fleet of class S frigates, five nice ships, and 2.6 billion units in the bank.

There’s nothing left to spend it on.

5 Likes

That is assuming that the calculated value of the trade goods is also unsigned. The fact that he reported that the amount of money he’d get from selling them was negative suggests that this is calculated in a signed primitive.
This could be a UI artefact… I.e. the actual value might be unsigned, but the UI interprets it as signed.

However, my statement above that the players money might underflow and end up very high seems to be incorrect. Promotion rules in C++ dictate that when doing operations with signed and unsigned types, the signed type gets promoted to an unsigned type, so the result would probably be exactly what you predicted.

2 Likes

This is what I surmised when adding one unit caused it to jump from about 2B to about -2B. I was expecting both values to be unsigned 32 bit integers, but apparently it was doing arithmetic on two different data types. I have no idea what sort of overflow protection they may have built in to the transaction. It appears that they have protected the maximum units, but I was reluctant to see if the transaction had overflow protection. It would have meant risking losing most of the hard work I’ve done since NEXT was released.

She might try ship and freighter trading. It’s really easy to lose a ton of money at that, and it’s a little bit less tedious than buying out the market and deleting inventory.

1 Like

This is why I have not bothered to make Units. They seem to come fairly easily in NEXT without farming. As soon as I have about 10mil I run out and buy a Frigate. I have several A class ships and 10 Frigates. Still searching for better ships, taking my time. Not too poor and not too rich.

1 Like

It may be different on other gaming platforms but on the PC the additional units simply disappear. If I sell enough to go over the 4,294,967,295 units it doesn’t go negative. It just stays at 4,294,967,295 units. This changed for me somewhere in the 3.xx versions of the game. Before that it would go negative so I simply deleted stuff.

I don’t really understand why such a limit exists, especially considering the lucrative rewards received for sending out 5 frigates missions. With 4 billion units it’s pretty hard to not make many more units.

4 Likes

This is so true. I send out frigate missions, because… well, what else am I going to do with them?

But they bring back pots of cash, and goods I have to sell, because I’ve got no room to store them. And my bank balance goes up and up, and there’s nothing to spend it on.

2 Likes

Time for a bit of a ramble but I have a point so bare with me…

I’ll start with my interpretation of our character in NMS:
I think we are simply supposed to be a being, thrust into an unknowing existence, with just a few key missions to guide us but really, the life we live is up to us.
We become a traveller through necessity, ultimately becoming a ‘Traveller’ in the way we know the term in NMS.
We better our circumstance as we go, improving & adding to our equipment, gaining financial security & establishing sharable bases.
There are multiple ways to improve our lot so we can choose our lifestyle(s): Farmer, Trader, Pirate, Treasure Hunter, Frigate Commander, Bounty Hunter etc etc.
As we travel & explore, we learn languages & lore with a growing understanding of our universe & the final decisions of the Atlas being our end game (should we want it).

I don’t think S grade everythings are the goal.
I don’t think getting rich is the goal.
I don’t think ploughing through the quests is the goal.
In fact, I don’t think any of the materialistic or trophy achievement things are the goal.
I think travelling, exploring & experiencing life as a traveller IS… just as it always was from day one. The other stuff is just candy you grab along the way.
Making money became an infectious obsession after Atlas Rises but since NEXT it’s simply not that important.
If you are too rich & it bothers you…start a new game & approach it with a different philosophy.
I think I might.

8 Likes

I totally agree. It’s something I’ve done since the game released, and it’s what’s kept me going over the years since then.

The game is what you make it.

Nevertheless, having lots of cash makes many things easier. In fact, without cash, some things are impossible.

But beyond a certain point, it becomes difficult to maintain your game activity, and not make more money. And, at roughly the same point, it becomes impossible to spend more money.

There have been lots of suggestions. Allow us to buy space stations. Allow us to buy planets. Or systems. It seems that HG haven’t thought through what happens when players get to this point - and they need to. It’s unfinished business.

5 Likes

Donate to the needy…:smile:

4 Likes

I could not agree more! Reaching the center of the galaxy also seems to have been a hollow goal at best for those who did it. Confused goals may created some of the dissatisfaction felt by those players who have left NMS along the way.

My original plan to create a massive factory for the generation of stasis devices was motivated by two factors:

  1. The pure joy of setting up such a task and working my way through it.
  2. The desire to have enough money that I didn’t need to stop to earn more if I chose to upgrade a ship or a freighter.

Honestly, I really love cataloguing plants, animals, planets, and systems. I love the peaceful trek through different places trying to get a full understanding of them. It bleeds off stress like no other game I have played.

That being said, sometimes I feel a bit like doing something different, and I really enjoy the liberty to do so. No one has to worry about straying from the path when you are the first person on a planet. There are no paths. If we want paths, we have to make our own.

NEXT has allowed an exciting level of freedom in base building. Base construction provides an easy outlet for the enjoyment of setting up procedures and systems, while at the same time allowing for artistic expression. It is not bothersome at all that my bases would not appeal to anyone else. I’ve hacked at painting and sculpture knowing that they would not appeal to anyone else, either, but they are not for anyone else, anyway. I do them for the pure fun of it.

Building the massive multi-system factory for stasis devices was fun, too. Running the factory felt less like a grind than anything else I have ever done for money in any other game. Watching it churn out products worth enormous amounts of money created an unexpected sense of satisfaction.

NMS grows into what you make of it. The players I have enjoyed meeting in forums such as this one are an exceptionally creative bunch, and the skillsets I have seen represented here are humbling. I have no choice but to find enjoyment in a game that appeals to such people.

4 Likes

This experiment came the closest to answering my original question so far. Based on the experiment, if the galactic trade terminal overflows, it is possible for it to drain your units. Since it is a signed 32 bit integer, it overflows at half the maximum number of units a person can have. It is entirely possible to overflow it in a single transaction selling a large number of expensive items.

While the maximum number of unit overflow has been fixed according to many people, I haven’t seen any clear evidence that the Galactic Trade Terminal overflow has also been fixed.

It seem odd to me that you declared “result” as an unsigned 32-bit integer in the first line of main(), but it printed as signed. I didn’t realize that could happen.

2 Likes

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