I=4 But FLOOR(I)=3
Root / Programming Questions / [.]
HackTheWorldsCreated:
Well I'm pretty sure this is a bug. Apparently when you add .4 to a variable until it equals 4, the floor value is 3. I'm using an old 3DS and I don't know if this only happens in FOR loops. Can somebody else try this out to see if it happens to them?
This code should reproduce the bug:
ACLS FOR I = 2 TO 4 STEP .4 PRINT "I=";I PRINT "FLOOR(I)=";FLOOR(I) PRINT NEXT IThis is the output I get:
I=2 FLOOR(I)=2 I=2.6 FLOOR(I)=2 I=3.2 FLOOR(I)=3 I=3.6 FLOOR(I)=3 I=4 FLOOR(I)=3As you can see that last output is really weird. (Edit: Fixed some typos. Thanks 12Me21.)
Ok. That's still kinda weird though considering it's 0.4. I wonder if it's just 0.4?
It's kind of weird how it does that... I'd expect something like that to happen with, say, .1 because you can't represent it fully with binary (that actually happened in PTC), but I don't know why it would happen with .4. Maybe you can't represent .4 entirely in binary? I think you can, but I'm not sure. At the very least, I'm surprised that it's not consistent with making it 3.9999999 and 3.
It turns out this isn't limited to .4 and 4. I can confirm it happens when adding 0.8 ten times (which should be 8) and when adding 0.1 ten times (which should be 1). They both produce a value just slightly under 8 and 1, resulting in the FLOOR value being one less than what it should be.
This is unfortunately a common error in a lot of languages. For example, in Haskell, I can make a list (array) starting from 0 until 1 incrementing by .1 each time by doing:
[0, 0.1 .. 1]and the resulting list is:
[0.0, 0.1, 0.2, 0.30000000000000004, 0.40000000000000001, 0.50000000000000001, 0.60000000000000001, 0.70000000000000001, 0.8, 0.9, 1.0]This gets really annoying. We need languages that prevent this kind of stuff from happening.
This is unfortunately a common error in a lot of languages. For example, in Haskell, I can make a list (array) starting from 0 until 1 incrementing by .1 each time by doing:That's too bad. And I agree. This shouldn't still be an issue with modern programming languages.[0, 0.1 .. 1]and the resulting list is:[0.0, 0.1, 0.2, 0.30000000000000004, 0.40000000000000001, 0.50000000000000001, 0.60000000000000001, 0.70000000000000001, 0.8, 0.9, 1.0]This gets really annoying. We need languages that prevent this kind of stuff from happening.
This is unfortunately a common error in a lot of languages. For example, in Haskell, I can make a list (array) starting from 0 until 1 incrementing by .1 each time by doing:This isn't an issue with the language. Everything that implements a floating-point type, even double-precision, suffers from precision loss. This is simply how floating-point works: it tries to store an immense amount of decimal precision into only 64 bits (for doubles), so it has to take a sacrifice somewhere. The only way to circumvent this would be to put in better floating-point technology (better error correction, improve precision, make it so integers are always exact etc.) or forgo floating-point entirely in favor of infinite-accuracy math, which is far less efficient. EDIT: Reading this back, it's likely there's a bug in SB (or even in the 3DS system) that causes this rounding to work improperly, since I is said to be 4 even though flooring it is 3. Maybe two separate correction procedures are used for output versus rounding, and this is what's causing it.[0, 0.1 .. 1]and the resulting list is:[0.0, 0.1, 0.2, 0.30000000000000004, 0.40000000000000001, 0.50000000000000001, 0.60000000000000001, 0.70000000000000001, 0.8, 0.9, 1.0]This gets really annoying. We need languages that prevent this kind of stuff from happening.
Well hey what do you know, SmileBasic DID specify their limitations in the instruction manual this entire time!
We can observe, but now nobody can complain :p
http://smilebasic.com/en/reference/
FOR: Repeats the process for the specified number of times - The NEXT instruction should be placed at the end of the process - If the condition is not satisfied, the process may not be executed at all (omitted) - If the increment is specified as a fractional value, the intended loop count may not be achieved due to operational errors.