Large floats behave strangely in GLFW
Monkey Forums/Monkey Programming/Large floats behave strangely in GLFW
| ||
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) |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
@Goodlookinguy - that looks great, would probably work, but I don't see a license anywhere on it, so is it just public domain? |
| ||
Yes, actually, it's under the WTFPL like most things I put out. |
| ||
:) Great, thank you |