ID:1932567
 
(See the best response by Ter13.)
Code:
proc
example(var/n)
n = num2text(n,34)
world<<n


Problem description:

num2text seems to return... just, flat out wrong numbers when trying to handle large numbers.

For example, if I run 1,000,000,005 through this, I get 1,000,000,004. Even more perplexingly if I run 1,000,050,005 through it, I get 1,000,050,008. The variance seems to go up to around 32~ in range, above and below, depending on what number is placed in it.

I'm unsure if this is a bug, and if it is I'll move it, but until that's verified I'll just go ahead and assume I'm missing something.
Best response
This is due to floating point numbers not being entirely accurate beyond about 2^24.

Because BYOND's numbers are floating-point based, there are going to be rounding errors and the more sigfigs you have, the bigger they are going to be.
Is there any way to work around it? I assume I can if I lower numbers using the % operator and store them in two separate variables.
You'll need some kind of bignum implementation.

I'll warn you. They are all pretty bad. Out of curiosity, though, why do you need your numbers to go so high?
Removing the scientific notation was what I was actually working on when this issue arrived.

I'll have to decide on if it peeves me enough to have a ~32 variance in stats to implement some form of bignum, does the variance get any bigger with even larger numbers? If so, what are we talking? 1,000 isn't so bad but larger than that might start causing my headaches.


Dragonball Z Numbers, what can I say. To my credit my numbers are true to the show.
Dragonball Z Numbers, what can I say.

Yeah... Akira Torayama's writing jumped the shark after Piccolo Daiomao. If you want to make a dragonball game, don't have such high stats. They are impossible to balance at those levels. You can probably get away with having your stat numbers really low in the codebase, but displaying higher.

proc/output_power_level(input_pl)
return num2text(0.25*(input_pl/10)**1.65 + 10)


You'll have to find your own function, but this growth curve starts off really slow, displaying 0 as 10, 93.55 as 20, 182 as 40, 304.17 as 80, 482.75 as 160, 794 as 320, 1152 at 640, 1761 at 1280, 2688 as 2560, 4300 as 5000, 6100 as 10K, 9300 as 20K, 14K as 40K, 21K as 80K, 33K as 160K, 50K as 320K, 76000 as 640000, 100K as 1M, 150K as 2M, 232K as 4M, 350K as 8M, 540K as 16M, and so on.

Once you get into the millions, you really don't need an exact number. People can't really grapple the large numbers.

Having the display powerlevel exponential like this, but the internal powerlevel being much, much lower would probably help you avoid both the balancing issues and the display issues.
Just don't have powerlevels.
Hrm, that system seems the best to go with at the moment, but I'll still have the issue eventually, I'm sure.

Also, strange behaviour, my game seems COMPLETELY unable to handle any number about 2.1billion (I assume this is the upper limit for some integer type). This is strange because I know of and even have source files of Zeta rips in which this doesn't happen.

world<<30000000000 //30,000,000,000 30 billions

Outputs: "2.14748e+009"


That hasn't ever happened to me before, the inaccuracy I can understand but what's this about.


Edit:
Ok I guess that's just a caveat of the actual DM compiler, once you're in-game you can turn 300m into 3b and the number works (Alright-ish), but you can't actually put numbers larger than 3b in the source. Which is fine because I was only testing but still.


I think I'll just inflate the numbers players see whilst having smaller ones in the source as you suggested. Thanks a lot!
I'll still have the issue eventually, I'm sure.

You shouldn't. Infinite progression is dumb.

also, strange behaviour, my game seems COMPLETELY unable to handle any number about 2.1billion

You shouldn't be handling numbers this big.

Outputs: "2.14748e+009"

Yep, that's scientific notation.

2,147,480,000

Which is roughly half of the 32 bit upper bound for a signed integer.

An unsigned integer's range is 32 bits, therefore 2^32 = 4,294,967,296. Since a signed integer has one bit representing positive or negative, the bound of a signed number is 2^31. This allows you 2,147,483,648 integer values to work with. This gives you a possible range of -2,147,483,647 to +2,147,483,647.
Again, I want to seriously reiterate that numbers like this are fundamentally something you don't want to represent at an integer granularity.

What you are doing is just not sensible, and it never will be.

Better to reduce the granularity or not work with such high numbers. You are going to run into major headaches the more you try to make this work. If you have numbers this high as stats in your game, I can promise you that it's going to completely suck from a design perspective.
In response to Ter13
You shouldn't. Infinite progression is dumb.

Players like their numbers! I doubt I'll let it get anywhere near that silly though. Official powerlevel rankings for Omega Shenron are 1.9b, which is still a lot higher than I anticipate being attainable.

Yep, that's scientific notation.

I understand that, what I don't understand is why the game at runtime can understand above 31 bit integers but the compiler can't. It's inconsistent, whilst understandable because huge numbers are relatively ridiculous, it's still strange.
No game in the history or gaming has ever benefited from ultra high stat numbers. They're ugly and horribly unweildy to balance. Other than that, nothing that needs to be said hasn't already been said.
In response to Ter13
Ter13 wrote:
Again, I want to seriously reiterate that numbers like this are fundamentally something you don't want to represent at an integer granularity.

Whilst I agree with that, I was hoping to keep numbers true to the series. This just isn't feasible I realize now.

What you are doing is just not sensible, and it never will be.

It can be sensible, I imagine, using percentage based damage with the percentage being affected by differentials.

Better to reduce the granularity or not work with such high numbers. You are going to run into major headaches the more you try to make this work. If you have numbers this high as stats in your game, I can promise you that it's going to completely suck from a design perspective.

Promises of my game sucking aside, I understand what you're saying. There will always be the point of terminality in which 1 million is a huge amount, but makes no difference in the game of billions. This was Akira Toriyama's problem too. A difference of 30m completely changed whether a fight was a whitewash or not, even when numbers were as crazy as 2.5b.

It's not feasible to get numbers like that to work in a logical sense from a design perspective, outside of whoever attacks first with the bigger number wins.
You can still represent numbers of this size. You just need to make your internal numbers much, much smaller and calculate the larger display numbers using the internal numbers like I mentioned above.

Regardless, though, the way that human beings look at numbers, after the seventh zero, they are just completely meaningless.
In response to Ter13
Wonderful video, four links later and now I know there's a number that if you try to picture in your head, you turn yourself into a black hole.

Fun stuff, thanks a lot for your help, I will be doing what you suggested, though I'll probably break them down even harder, in the aim of making the number look larger. Though it might look a bit strange when a level 10 does a 10million damage attack to a level 1000, it'll still be a lot better than oneshot central.
The lower you keep your stat ceiling, the easier your life will be. You can use large numbers, but like Ter said, understand the smaller, easier to balance numbers first and it'll make it easier.

For example, I like numbers in the hundreds for aesthetic reasons. 500 speed looks better than 5 speed, even though they're the exact same thing in terms of the movement system, only an added conversion step for the former. The goal of big numbers is to act like floating values between small numbers without being ugly. A speed stat of 465 looks better than 4.65 again. Exact same example, but is only changed by aesthetics.
In response to Rushnut
Rushnut wrote:
I understand that, what I don't understand is why the game at runtime can understand above 31 bit integers but the compiler can't. It's inconsistent, whilst understandable because huge numbers are relatively ridiculous, it's still strange.

At compile-time, the value is treated as a 32-bit signed integer, which limits its range to [-2147483648,2147483648] (the max would be 2147483647, but a 32-bit float can't represent that so it gets bumped up)

If you don't want it clamped to that range, just tack on a decimal point (ie write "30000000000.0" instead of "30000000000"). Then it will be compiled as a float, at whatever precision it can manage (which is "30000001024.0" in that case)

At runtime everything is a 32-bit float.
In response to DarkCampainger
Scientific notation seems to compile as floats, too:
world << 3e10
In response to DarkCampainger
DarkCampainger wrote:
If you don't want it clamped to that range, just tack on a decimal point (ie write "30000000000.0" instead of "30000000000"). Then it will be compiled as a float, at whatever precision it can manage (which is "30000001024.0" in that case)

At runtime everything is a 32-bit float.

Huh, that's a really interesting tidbit. Shouldn't the compiler be changed so that it automatically detects if a number is too large and switches it to a 32-bit float anyway?

I mean, it could cause bad habits ultimately but in the name of making the DM language even more user friendly.
Page: 1 2