Big Integer handling in Blitz Basic 2D?
Miscellaneous Forums/General Discussion/Big Integer handling in Blitz Basic 2D?
How do you handle big integers (greater than 2million) in blitz basic 2d or blitz max? You must be able to do a majority of mathematical operations upon the big integer (including addition, multiplication, division, percent, mod, etc).
At the moment I'm using an abacus-style way of handling big integers.
If units > 999 then thousands = thousands + 1:
if thousands > 999 then millions=millions+1:thousands=0
if millions > 999 then billions = billions + 1: millions = 0
if billions > 10 then billions = 10
But, you can't do division or multiplication? has anyone been able to do a true abacus algorithm to handle really big ints in either Blitz Basic 2D or Blitz Max?
Many thanks.
Use longs?
Does "long" exist in Blitz Basic 2D (not plus, max, the one that came on a magazine?) I'm at work so I cannot verify this.
Does "long" exist in Blitz Basic 2D
No.
It does in Max.
Oh, I may just use Max to resolve my particular issues. How big does Long go to in Max? Does it go to at least 5 billion?
I may read more into the Japanese Soroban abacus method to resolve this particular issue, if someone has fully coded an abacus system for Blitz Basic 2D please post it!
http://webhome.idirect.com/~totton/abacus/
Is it possible to use binary to resolve this problem? Someone said that binary is more or less the same as binary, it's 8-bit and you can say 00000001 = 1 and 00000011 = 3
But this goes back to using binary multiple additions, etc.
A normal INT goes quite high doesn't it?
31 bits + sign bit =
+/- 2,147,483,647 (2 billion)
Or over 4 billion without sign.
Maybe INT's in BlitzBasic 2D are only 16 bit?
No they are 32 bit. 16 bit would only go up to +/- 32767
So, I guess it's just either:
a) Learn how to implement a true abacus system to handle big ints (including addition, subtraction, division, multiplication, percentages, etc)
or, more likely,
b) Move to BlitzMax (which I have, I'm just not very used to it).
If speed isn't a problem you could implement your own version of binary coded decimal (BCD) where you hold your values as strings and then manipulate them using proven algorithms on a digit by digit basis.
(I have been teaching the theory of this earlier this week !)
You should be doing the math at the binary level using things like & | Shl Shr etc
You can add together bigger numbers by splitting them into smaller chunks and adding each chunk together. If you are adding 2 Int's, split each of them into 2 Shorts so you end up with 4 shorts. e.g (Var1 Shr 16), (Var1 & $FFFF), (Var2 Shr 16), (Var2 & $FFFF). Then add the lower portion of var 1 to the lower portion of var 2. Then the upper portions. Any overflow that happens from the 15th into the 16th but you have to add to the total (e.g. ((Var1Short+Var2SHort) & $1000) Shr 16) added). There are tricks to it. You can still do it with the variable space you have but you just have to make it into smaller pieces and combine them.
I've done this to allow + and - of unsigned Long 64-bit numbers. * and / is harder though because two 16-bit values multiplies becomes up to a 32-bit value. I cheated and used conversion from unsigned 64-bit to signed 64-bit to Doubles and back.
I'm going to try to learn blitzmax ... this sounds too complex, it's a shame because I really enjoy using BB2D and find Bmax too complex to understand, but that's just probably me.
Thanks anyway.
Wouldn't floats (use # after variable name) do the trick?
I'm intrigued to know why you need numbers that have to be integers and are greater than 2 billion (not million as mentioned in the first post).
The answer is because if you've ever played "Trump: The Board game", it lowest dominator is 10 million, you can win potentially up to 1 billion +
In addition, in the game SWOS (Sensible World of Soccer) it used 1m 1.5m, 2.5k, etc (including a unit of measure) to aid usability and visual appeal, I wanted all of that -- but still wanted to do percentage cuts, and a multiplier of profits card (or multiple taxes card).
The way I resolved this problem was to do;
; This may be the wrong version, as I have different versions of the same code on my machine
; --------------------------------
Const use_tender = True
Const min_tender = 10
Global cash_millions = 10
Global cash_billions = 1
Function add( millions=0, billions=0 )
If (millions > 0) Then
cash_millions = cash_millions + millions
End If
If (billions > 0) Then
cash_billions = cash_billions + billions
End If
If cash_millions > 999 Then
Repeat
sum = (1000 - cash_millions)
cash_millions = ( 0 ) + sum
cash_billions = cash_billions + 1
Until cash_millions < 1000
End If
If cash_billions > 10 Then cash_billions = 10
End Function
Function subtract( millions=0, billions=0 )
If (millions > 0) Then
If (cash_billions > 0) Then
cash_millions = 1000
cash_billions = cash_billions - min_tender
End If
If cash_millions > 0 Then
cash_millions = cash_millions - millions
End If
End If
If (billions > 0) Then
cash_billions = cash_billions - billions
End If
If cash_millions < 0 Then cash_milions = 0
If cash_billions < 0 Then cash_billions = 0
End Function
add(0,0)
While Not KeyHit(1)
Cls
Text 100, 100 , cash_millions + "m"
Text 100, 110 , cash_billions + "b"
WaitKey()
subtract(10)
Flip
Wend
I did not try floats, but seeing as I just uninstalled BB2D, I'll have to reinstall it to find out if I can go to at least 10 billion.
Floats in BB2D do not give the right result.
cash# = 10000000000 ; 10 million
Print currency$ ( cash# )
;@currency function
Function Currency$(value)
curr$ = Str(value)
p=0
For i=Len(curr$) To 1 Step -1
If p = 3 Then
curr$ = Left(curr$,i)+","+Right(curr$,Len(curr$)-i)
p = 0
End If
p = p + 1
Next
Return curr$
End Function
This gives an output of 1,410,065,408. Turning "value" to "value#" gives an output that's even wierder.
It doesn't work, neither does using the ^ operator. You have to use a big int function, which I'm reading up upon (doesn't exist as yet), or make the computer work out sums like in binary, or program a chinese abacus system (which goes up to 10 trillion).
OR.... just learn Blitz Max, which I don't like; but I guess it's the only way.
I remember back in the day... after dll support was added... that someone had added support for a math library, but beyond that vague reference I can't remember anything else.
i had a quick try. this works but only for positive values. i got stuck then.
i think the best way is to write a dll to receive a string from b+, do the maths function as 64-bit values, and return the result as a string.
Graphics 640,480,0,2
value2$="100000020"
value1$="3000"
result$=AddLongString(value1$,value2$)
Print "value1="+value1
Print "value2="+value2
Print "result="+result+" ("+(100000020+3000)+")"
WaitKey
End
Function AddLongString$(val1$,val2$)
Local val1hi,val1lo,val2hi,val2lo,reshi$,reslo$,i,pad$
If (Len(val1$)>9) val1hi=Int(Left(val1$,Len(val1$)-9))
val1lo=Int(Right(val1$,9))
If (Len(val2$)>9) val2hi=Int(Left(val2$,Len(val2$)-9))
val2lo=Int(Right(val2$,9))
If (val1hi+val2hi<>0) reshi$=val1hi+val2hi
If (val1lo+val2lo<>0) reslo$=val1lo+val2lo
For i=1 To 9-Len(reslo$)
pad$=pad$+"0"
Next
Return reshi$+pad$+reslo$
End Function
The answer is because if you've ever played "Trump: The Board game", it lowest dominator is 10 million, you can win potentially up to 1 billion +
wait.wait.wait.
So, you can't have values lower than 10 million? Why not just divise/multiply everything by 10 million then?
Function PrintCash(monies)
If monies > 0 Then
Print somefancyfunctiontoplacecommas(monies) + "0,000,000$"
Else
Print "0$"
End If
End Function
no?
Sounds like you have plenty of precision for what you need. Just make the basic 'unit' something like 1000. That will give you a range of 0-2 trillion (I think - whatever 1000 billion is).
Sounds great -- but what about percentage cuts? Like "Player x wants 10% of 100m" and income multiplier. IE: "Player x plays his profit card, rolls dice and times by 10m".
Naturally, you could just say "Player x wants 10m to do this deal" but that really isn't the same as generating a percentage.
Secondly, you could just times roll of dice by 10 and there you go -- but this does not solve issues like say you have 10,000 and times by 1,000 and so forth.
Of course it's almost quite straight forward for the trump thingee, but if you're talking about other games which require big numbers then you're kinda fixed.
Well you simply need to work out your smallest unit.
Make it 10 and you can handle numbers up to 20billion.
Make it 100 and you can handle numbers up to 200billion
Make it 1000 and you can handle numbers up to 2 trillon.
I'm finding hard to believe that an INT won't give you the precision you need. If not, floats should be perfectly workable.
The answer is because if you've ever played "Trump: The Board game", it lowest dominator is 10 million, you can win potentially up to 1 billion +
wait.wait.wait.
So, you can't have values lower than 10 million? Why not just divise/multiply everything by 10 million then?
Function PrintCash(monies)
If monies > 0 Then
Print somefancyfunctiontoplacecommas(monies) + "0,000,000$"
Else
Print "0$"
End If
End Function
no?
Didn't *exactly* the same question come up on CW and that was the most workable answer?
Yes, I was the one who asked it... the answer given was similar to the code I supplied above.
The answer was to split each bit into units, thousands, millions and billions, much like an abacus does. -- let me re-empthasise there is no problem with this, I have already achieved it, the code works.
There is no problem with precision with INTs.
The problem:
* You cannot do multiplication (ie: how do you do unit * thousand, thousand * million, million * billion). You can keep adding figures together, much like binary multiple addition does it, this is a great step to solving it, but will not resolve issues such as 0.2 * 10m, etc
* You cannot do division with the code supplied. How do you do "% cut of a unit, % cut of a thousand", especally if they are only numbers that go to a base of 9?
The workable answer of just putting the printcash(monies) only solves the problem for units with a mod of 10m.
But the thing is, in future games you might need to use or display units. Like in SWOS, it has 250k, 2.5k, to at least 2 decimal places.
I guess I'm looking for a solution that will solve all problems all the time.
I tend to look for solutions to specific problems. You'll spend a long time looking for a solution to everything.
If you have an actual specific problem with a game you're working on I'm sure we'll be able to help you solve it.
Yes. I concur. I am sorry. I'll go back and work on it some more.
Use banks. consider every actual byte in the bank a bit, and do the binary math using peekbank and pokebank on various banks.
Andy