Jump to content

Large integers above limit.


pangore
 Share

Recommended Posts

I was tasked with creating a HUD for a RP group. So far its been going really well and I have scripted the majority of it.  I have now ran into a problem that I cant even seem to wrap my head around. This RP community not only has individual people but they also have entire planets with running governments.  Money is a problem with entire planets having way over the 2.2. billion limit for integers. 

I'm having a really hard time trying to come up with a way to get around the 2.2 billion integer limit while sticking within LSL scripting.  I cannot figure out how to make a webpage to do it for me. I have tried for months.  

My current line of thought was to store the whole number in a string and pull out parts of it that I would need to do the math. Unfortunately I cant seem to figure out how to make that work when someone wants to do more then 2 billion in a transaction.  

Anyone have any suggestions? 

Link to comment
Share on other sites

A simple way to implement arbitrarily large integers (google that) is to store them in a list, then calculate/display them as strings.

For example, the largest number you will deal with is 1 billion. If you need to display a number like 4.2 billion, you have a list of [200'000'000, 4] and you build a string such that it reads "4'200'000'000" or "4.2 B" or whatever format you wish (I recommend separators for all our sanity). And if you get into even bigger numbers, your list could simply grow like [200'000'000, 999'999'999, 6] to create "6'999'999'999'200'000'000" or "6.9 Quint" or whatever.

If you're fluent in Java, here's an example implementation: https://gist.github.com/rgb-24bit/931e45660d8826fce2053c943d0b2c99

If you're not fluent in Java but have general programming knowledge, that's still a workable example of how to implement the basic stuff like add/dec/mul and building a string.

Edit: I gave the reverse-order example because of the example code, but if you can store the numbers in the correct order instead, you can simply typecast the list to string to get the full number readout.

Edited by Wulfie Reanimator
  • Like 3
Link to comment
Share on other sites

Another method is to expand on the game currency with additional units.

e.g. a 'Planetary Bond' worth 1B credits. It could even be an inventory item, to be cashed in/out from designated terminals. And that simplifies the whole process of displaying a balance on the HUD.

 

The real trouble with ingame currencies is there are many avenues for earning, but few for spending. It leads to players amassing vast fortunes and the inevitable inflation. Whatever you're building, factor in routine expenses for the player too.

  • Like 2
Link to comment
Share on other sites

I'm not suggesting it, but for the record, floats support almost arbitrarily large numbers, if you don't mind minor losses in precision as the amount increases:

https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limitations_on_integer_values

above 4 billion the lossiness is around 512 units. If the main 'income' is from lots of small transactions, would probably be a problem.

 

Link to comment
Share on other sites

I thought of a different way to handle this if i can accomplish it. 

Going to make the main variable a string and keep the large number in. When someone wants to do something with that number. Ill take the number they submit with the main number..  using substring ill pull each of the numbers.. do the math then take the remainder to the next number.. add it all back into a string and be done... 

That makes it sound easy to me but ill find out if thats true today or tomorrow as i can get back on the computer.

  • Like 1
Link to comment
Share on other sites

1 hour ago, bobsknief Orsini said:

2 integers.

seems fine until hyper-inflation kicks in. Once you hit the point where you need more than 2 billion, what's to say you won't eventually need numbers greater than a couple quintillion?

When you get 2 integers in a list working, it shouldn't be too much more effort to generalize to any arbitrary number of numbers in your list, but will definitely future-proof you.

Link to comment
Share on other sites

suggest going with Mr Amore method

using llChar and llOrd we can create Base50000 numbers (coins) encoded in a string


1 char is upto 50,000
2 chars is upto 2,500,000,000
3 chars is upto 125,000,000,000,000
4 chars is 6,250,000,000,000,000,000
5 chars is 312,500,000,000,000,000,000,000

and so on

addition and subtraction is done moving from left to right

to denote a value come up with a name for each coin. Like
 
Penny = 1 penny .. 49999 pennies
1 Shilling = 50,000 pennies
2 Shillings is 100,000 pennies
1 Florin is 50,000 shillings
1 Pound is 50,000 florins
1 Guinea is 50,000 Pounds

so if our coins were valued [20432][334][17][2][1]

then our worth is

1 guinea, 2 pounds, 17 florins, 334 shillings and 20,432 pence

 

ps edit

if you want to run negative balances then add another char to the start of the string denoting the sign

for example: llChar(0x20) is positive. llChar(0x21) is negative
 

 

Edited by Mollymews
  • Thanks 1
Link to comment
Share on other sites

string AddBigNum(string cAddend1, string cAddend2)
{
    integer nLength1 = llStringLength(cAddend1);
    integer nLength2 = llStringLength(cAddend2);
    integer nLongerLength;

    if (nLength1 > nLength2)
        nLongerLength = nLength1;
    else
        nLongerLength = nLength2;

    integer i;
    string cResult = "";
    integer nCarry = 0;        
    integer nDigit1;
    integer nDigit2;
    for (i = -1 ; i >= -nLongerLength ; i--)
    {
        nDigit1 = (integer)llGetSubString(cAddend1,i,i);
        nDigit2 = (integer)llGetSubString(cAddend2,i,i);
        cResult = (string)((nDigit1+nDigit2)%10+nCarry)
            + cResult;
        nCarry = (nDigit1+nDigit2)/10;
    }
    if (nCarry > 0)                        
        cResult = (string)nCarry + cResult;
    return cResult;
}

This Works For adding at the moment. Just need to figure out how to subtract with it now.  I keep reading what everyone is posting but honestly I don't understand what people are saying or how it would relate to scripting. 

Link to comment
Share on other sites

3 hours ago, pangore said:

how to subtract

If you have addition, you can implement subtraction by adding 10's compliment plus 1, and subtracting the final carry:

string compliment(string number)
{
  string return;
  integer index = llStringLength(number);
  while(~--index)
  {
    return = (string)(9-(integer)llGetSubString(number,index,index)) + return;
  }
}
string SubBigNum(string a, string b)
{
  b = compliment(b);
  while(llStringLength(b)<llStringLength(a)) // inefficient.
  {   b = "9"+b;
  }while(llStringLength(a)<llStringLength(b)) // inefficient.
  {   a = "0"+a;
  }
  string result = AddBigNum(a,b);
  result = AddBigNum(result,1);
  return llGetSubString(result,1,-1);
}

You'd also have to deal with some pesky '-' signs, but that should give you something to work with.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...