ID:116326
 
Resolved
The == and != operators returned incorrect results when comparing 0 and -0, where -0 could result from some calculations.
BYOND Version:489
Operating System:Windows XP Home
Web Browser:Opera 9.80
Applies to:Dream Daemon
Status: Resolved (490)

This issue has been resolved.
Descriptive Problem Summary:
In specific situations, it seems that the difference between 0 and -0 show up.

Numbered Steps to Reproduce Problem:
I'm not quite sure, though two examples occur below.

Code Snippet (if applicable) to Reproduce Problem:
mob/Login()
var/list/l = list( list(0,-4,-5),
list(4,0,-6),
list(5,6,0)
)

var/x = 5 * (1 - 1)
var/y = -(5 * (1 - 1))

world << (x == y)
world << (x == -y)
world << l[1][1]
world << -l[1][1]
world << (l[1][1] == -l[1][1])


Expected Results:
That the results would be 1, 1, 0, 0, 1.

Actual Results:
The results are 1, 0, 0, 0, 0.

Does the problem occur:
Every time? Or how often? Every time.
In other user accounts? Yes.
On other computers? Yes.

When does the problem NOT occur?
Unsure. It appears that it only occurs when dealing with negating a value before a comparison, but I don't know if this is the only situation it does occur.

Workarounds:
Specifically checking if the value is equal to zero, e.g. through absolute values or etc.

[Edit]

And alternative test case is below:
var/f = 0
var/g = 0

world << (f == g) // 1
world << (f == -g) // 0
world << (-f == -g) // 1
world << (-f == g) // 0
Definitely a bug that seems to happen during runtime. When an output is done like 'world << (0 == -0)' during compile-time, computes correctly. However, it does not compute converted variables (with 0s) correctly or somehow assumes it is false when met up with a variable that equals 0 or a constant 0.

It could be a compiler issue, VM issue, or both. This issue only happens when converting any variable with a 0 to negative (which confuses it as a -0). However, it still outputs like a regular 0.
Comparison values for negative zero and such are flags set in the assembly that can be changed. (For example, setting the assembler to either throw an error when dividing by zero or return infinity.) I assume BYOND uses whatever C++ has by default. (Could be compiler-dependent or a compiler option.)
The VM must use the FPU at some level.

I wonder if anyone has tried on Linux. The results might be different.
I'm guessing this is why some Division by zero errors occur, most recently showing up in Pixel_Movement where sometimes it would return -0. It would then check if it was zero, it would return false instead of true and then try to divide by -0 which would cause the error.
Bravo1 wrote:
I'm guessing this is why some Division by zero errors occur, most recently showing up in Pixel_Movement where sometimes it would return -0. It would then check if it was zero, it would return false instead of true and then try to divide by -0 which would cause the error.

There are a lot of other reasons for that, and I dunno if it's likely this is a reason. Also, Pixel_Movement isn't referring to pif_MovementSystem, is it?
No it's referring to pixel_movement from Forum_Account. In one portion he has a variable (dx) that becomes a dividend. There's a check in there so that if dx==0 that it skips the division, since it would cause an error. He had to change it because, even though there was already a sanity check, occasionally there would be Dividing by zero errors. I can only assume that the result was -0 and byond wasn't returning true for dx==0 which it should, regardless if it's 0 or -0
I did a test with num2text on a variable that is converted to a negative. Definitely shows a negative zero (-0) in play when outputted.
http://www.byond.com/members/ BYONDHelp?command=view_tracker_issue&tracker_issue=3098
You think he made it "Not a bug", because he can't fix it?
Chowder wrote:
http://www.byond.com/members/ BYONDHelp?command=view_tracker_issue&tracker_issue=3098
You think he made it "Not a bug", because he can't fix it?

That was not actually a case of it, because no one could reproduce it. This is a reproducible case.

Sure the bug report I posted couldn't reproduce it, but all the code in it's comments can. I was kinda bummed when he closed it with "Not a bug". So I'm glad you made another one in any case.
This is still appearing, easily-demonstrable, and awkward to work-around. It would be nice to hear some input from the developers.