ID:167029
 
BYOND Version: 348.905

Operating System:
Microsoft Windows XP Home Edition

Web Browser:
Mozilla Firefox

Game/Hub(s): None?

Detailed Problem Description:
Well, I was just working on my game, making a respawn system. After I did that (well, part of it), I ran the game. When I tested the respawn stuff, though, it showed lots of [Random].[Random] numbers (at the end of the countdown though, it went to -1.86265e-006...). When I tried it with another system that'd output the same thing as the old thing should have, it worked fine.

Code Snippet to Reproduce Problem:
// Old system:

var/time = 10
while (time)
sleep(1)
time -= 0.1
src << time

// New system:

var/time = 10 * 10
while (time > 0)
sleep(1)
time -= 0.1 * 10
src << time / 10


Does the problem occur:
Every time? Or how often? Every time in this house...

In other games? Don't know.

On other computers? Don't know.

In other user accounts? Don't know, they're all password protected...
The error you're seeing is due to floating point maths, and will happen with any programming language that uses floating point numbers (i.e. most programming languages).

As that page mentions, the number 0.1 cannot be precisely represented in binary, in a similar way to the number 1/3 in decimal; if you try to write 1/3 in decimal form you get infinitely repeating digits, like this: 0.333333... So when you repeatedly subtract 0.1 from a floating-point number, you will inevitably get some error in the calculation. After 100 or so such subtractions, the error can grow fairly large. (Note that -1.86265e-006 is actually 0.0000018625, which is pretty close to zero; that amount of error isn't too bad for some applications, but can become fatal .)

The solution, as you discovered, is to subtract the number 1 instead, and do the error-producing division by 10 only when you have to. The number 1, like all whole numbers, can be precisely represented; and so you don't get odd roundoff errors when you use them.

Even professional software engineers get caught out by this sometimes... occasionally with disastrous results!
In response to Crispy
Oh, I never knew that. Thanks for showing how it works. (I actually already knew that it used float point maths, but I didn't really know what it meant so I just ignored it.)
In response to LXShadow
No worries!

Actually, I was slightly wrong - not all whole numbers can be represented precisely. Large ones will have some roundoff error when using floating-point. You can observe this if you print out the value of world.realtime every second; for several seconds in a row, its value is the same! And when it does change, it jumps in increments of several seconds. This is because the number of seconds since January 1, 2000 is too large to be represented precisely by a floating-point number. This is what happens when you try to represent a potentially infinite number with a finite amount of memory. =)
In response to Crispy
Concerning the part of that article about the scuds, I have heard that they were not nearly as successful as the miliary tried to claim anyway.

I recall watching a documenary in which it was explained that, in the military's report on their supposed success, their definition of success was to fly to the incoming missile and detonate in its vicinity. It did not have to actually stop the incoming enemy missile to be called a success; it just had to detonate nearby. Therefor, in their reports, their "success rate" was not really the rate at which they stopped incoming missiles... it was just the rate at which they failed slightly as opposed to drastically - what a "success." In this way many people were fooled into thinking that they were actually successful.
In response to Loduwijk
Yeah, well, having accumulated floating-point errors certainly wouldn't have helped. =)