ID:2143033
 
(See the best response by Kaiochao.)
Code:
mob
verb
test()
var/s1 = 2.8

s1 += 0.1
s1 += 0.1

var/c = 0
for(var/i = 1 to 3)

if(s1 + c >= 3)
world << i
break
else
world << "[s1 + c] >= 3"

c += 0.1

world << c + s1


Problem description:

I'm not sure whether this is a bug or me derping, the output looks like this:
3 >= 3 - first run, somehow this if statement ends up false
2 - second run, lands in the if and breaks out of the loop
3.1

have you tried using parenthesis in your if statement
Result remains the same
Best response
Try using explicit num2text() with a high SigFig (e.g. 12).

The default conversion of your sum to text rounds away the floating point error that is present when you add numbers that aren't a power of 2, such as 0.1.
Woo it changed to 2.99999976158 >= 3
As Kaiochao said, you're running into rounding error here. 0.1 is only represented with an approximation in floating point, as is 2.8. In floating point, 2.8 + 0.2 is not exactly 3 because they both have rounding errors.
Yeah, a general rule with floating point numbers is that you should not directly compare them for equality, but instead see if the (absolute value of the) difference is below some error threshold. It's not really a common practice on BYOND, though.
Drilling down a little further, the deal here is that floating point numbers are a 24-bit integer multiplied by a power of 2. The value of 0.1 in binary is actually:

0.000110011001100110011...2

It repeats forever, because 0.1 is 1/10 which is 1/5 × 2-1. Because 5 does not divide evenly into any power of 2, the sequence will repeat. But the floating point standard doesn't concern itself with repeating digits, so it has no exact representation for any fraction that does this.

In floating point, 0.1 is approximated by:

1.100110011001100110011002 × 2-4

or

1.100110011001100110011012 × 2-4

It depends on whether the number is rounded or simply truncated, which I'm not sure about. Your results suggest truncation.

If you're counting up by a rounded-off value like 0.1, what you need to do is check to see if you're close enough to the endpoint to consider it basically the same number. Thus instead of if(s1 + c >= 3), you probably want if(s1 + c >= 3 - FUDGE), where FUDGE is a small constant like 0.00001.