Large floats behave strangely in GLFW

Monkey Forums/Monkey Programming/Large floats behave strangely in GLFW

benmc(Posted 2013) [#1]
If I create an Float variable that is really large, it seems that when printing it or drawing it, the last several numbers of the float get all screwed up in GLFW

For example, 40000000000000 displays 39999999311872

But in Flash and HTML5 it shows 40000000000000

I haven't tested on Android or iOS yet, but I'm hoping it displays properly as my game generates massive scores for fun.

Any idea on how to correct this (if possible)


ElectricBoogaloo(Posted 2013) [#2]
32 bit = 11111111111111111111111111111111 = 4294967295
Since Monkey signs it's numbers, you get half of that.
From the docs.. "A 32 bit int can represent a range of values from: -2,147,483,648 to 2,147,483,647"
You go over that number, and things get messy no matter what language you're using.

Floats get even messier, since you've got all your floating-point inaccuracies to deal with, too.
Again, from the docs.. "The range of floating point values support is target dependent, but is at least 32 bits."

Also remember that, although the Float might be more than 32 bits, it's actually using most of those bits to store the "post-decimal" digits, so trying to store huge numbers in a float is pretty much a recipe for disaster no matter what you're trying to do with it.


Xaron(Posted 2013) [#3]
With a float you have a accuracy of about 7.2 decimal digits. A double has about 15.9

So either you have something like 0.123456 or 1.23456 or 12.3456 or 123.456 .... or 123456

Anything beyond that becomes inaccurate. You can't have something like 1234569 anymore because it just gets 1.23456e+7 which is 1234560


Shinkiro1(Posted 2013) [#4]
I think the reason it works in flash is that flash represents numbers as objects and can then use more bits if needed (only an assumption).

As ElectricBoogaloo mentioned, all basic numeric data types have limits.
So in your case you could build a BigNumber class that works with strings. Of course you will have to write all the math yourself.

PS:
If you didn't know, there are also floats that you can't represent in a computer, simply due to the format they are stored.
e.g. 0.1 can't be exactly represented in binary format (imagine it like 1/3 can't be represented by natural numbers, just approximated). That's why you shouldn't ever have an equal comparision with floats, it's better to check if it is within a certain range.


benmc(Posted 2013) [#5]
So, I'm guessing I need to create my own number-object that keeps track of the math between each section of the number, such as I would do:

40000000000000.00 as

[040] [000] [000] [000] [000] . [000]

And then write some functionality that would ultimately do all the counting and arithmetic.

Sounds like a heck of a challenge. Could be interesting.


Gerry Quinn(Posted 2013) [#6]
Funny thing is that float comparisons of reasonably small numbers seem to work okay these days, although I am too old-school ever to trust them, and I always convert to ints or test a range.


Gerry Quinn(Posted 2013) [#7]
benmc, there must certainly be code available online that you can convert.

But for ints you might consider a cheap and cheerful method such as decimal encoding. If you store a number as an array of ints, each up to 10^9, the code to handle addition, comparison and printing of positive numbers, which are all you would need for a score, would be pretty simple.

Haven't tested this, but here is addition for 54 digit decimals:

Const MN_LENGTH:Int = 10				' Mega numbers contain ten int 'digits'
Const MN_MAXDIGIT:Int = 1000000000

Function AddMegaNumber:Int[]( n1:Int[], n2:Int )
	Local sum:Int[] = New Int[ MN_LENGTH ]
	Local carry:Int
	For Local i:Int = 0 Until MN_LENGTH
		Local val:Int = n1[ i ] + n2[ i ] + carry
		If val >= MN_MAXDIGIT
			val -= MN_MAXDIGIT
			carry = 1
		Else
			carry = 0
		End
		sum[ i ] = val
	Next
	If carry <> 0
		Return MN_MAX					' [ 999999999, 999999999, 999... ]
	End
	Return sum
End



benmc(Posted 2013) [#8]
Gerry, this is definitely the direction I am working in at this point.

I do need to do some multiplication, so it's been challenging, but multiplication can also be considered a lot of adding, so I'm looping X times through a similar function to get to my results. It's decimal multiplication that's causing me some headaches at the moment.

So far it's not perfect, but it looks like working with arrays of ints is the way to go.

I've found a pretty hefty explanation on StackOverflow that may work, but I haven't explored it completely yet:

http://stackoverflow.com/questions/5318068/very-large-numbers-in-java-without-using-java-math-biginteger


Goodlookinguy(Posted 2013) [#9]
Just putting this out there, but you may want to look into my More Numbers module: http://www.monkeycoder.co.nz/Community/posts.php?topic=5740


benmc(Posted 2013) [#10]
@Goodlookinguy - that looks great, would probably work, but I don't see a license anywhere on it, so is it just public domain?


Goodlookinguy(Posted 2013) [#11]
Yes, actually, it's under the WTFPL like most things I put out.


benmc(Posted 2013) [#12]
:) Great, thank you