mthom / scryer-prolog

A modern Prolog implementation written mostly in Rust.
BSD 3-Clause "New" or "Revised" License
2.07k stars 125 forks source link

Negative zero (floating-point) #859

Open infradig opened 3 years ago

infradig commented 3 years ago

This came up on Hacker News so I checked...

$ ~/scryer-prolog/target/release/scryer-prolog ?- X is -0.0. X = 0.

$ gprolog | ?- X is -0.0. X = -0.0

$ swipl ?- X is -0.0. X = -0.0.

infradig commented 3 years ago

BTW scryer-prolog passes the '0.0 = -0.0' test (I think by accident), as does gprolog but not swipl (though swipl passes 0.0 =:= -0.0 case).

mthom commented 3 years ago

Huh, odd. This is a quirk with floating point?

infradig commented 3 years ago

It's an IEEE 754 thing.

UWN commented 3 years ago

Please see this note on ISO Prolog and LIA. IEEE 754 is not one simple standard but it is full of all kinds of modes and adaptations. Just think of what Java has made out of them. Kahan, the father of IEEE floats is all furious about it. The model ISO Prolog uses is much simpler - and this is also what SICStus does. There are no continuation values just direct exceptions and no such notions as -0.0. Both SWI and GNU are not a good reference here. SWI has recently changed everything to adopt BNR-constraints, and I suspect that's the only testcase. And GNU is much more into speed than correctness. Just type X is 7^7^7. to see this. (Since 1.5.0 this example works, but other overflows are still not caught)

If you are serious about going far beyond, you really would need to consider all the rounding modes and all of that. This is a very deep sink. I suspect it would be easier then to consider Unums as they are much less moded.

UWN commented 3 years ago

One such black hole of IEEE are de/subnormals. See this on SO. Brief: Support subnormals. It's no longer the RISCy 1990s.

UWN commented 3 years ago

Maybe this is the simplest way to decide where to go: As long as IEEE 1788 is not supported by rust, don't even consider to think about going anything further than what ISO demands. You would be again on the bleeding edge (like with memory overflows).

infradig commented 3 years ago

Printing floating point zero as an integer seems wrong.

UWN commented 3 years ago

Right, separate issue!

UWN commented 3 years ago

But, this works`as expected:

?- number_chars(0.0,Chs).
   Chs = "0.0".
UWN commented 1 year ago

Closable.

UWN commented 1 year ago
?- X is -0.0.
   X = 0.0.