0.0 ? "foo" : "bar" returns bar

15 views
Skip to first unread message

陈圣麒

unread,
Apr 19, 2020, 8:57:57 PM4/19/20
to LDMud Talk
0.0 ? "foo" : "bar" returns bar
That seems highly unreasonable

Stephan Weinberger

unread,
Apr 19, 2020, 9:23:36 PM4/19/20
to ldmud...@googlegroups.com
On 20.04.20 02:57, 陈圣麒 wrote:
> 0.0 ? "foo" : "bar" returns bar
> That seems highly unreasonable
>
Hello,

Never do equality comparison on floating point numbers; floating point
is not an exact representation. It is also not unambiguous (i.e. there
is more than one way to store the same number; but == only compares the
bit patterns, so it may fail). This is independent of the programming
language, it's an inherent property of floats.

If you need to compare a float x to a specific value, you have to use
something like:

(abs(x-value) < 0.0001) ? "foo" : "bar";

i.e. check if x is within a small environment around the value.

cya
  Invisible@Beutelland


Croft

unread,
Apr 20, 2020, 2:11:23 AM4/20/20
to ldmud...@googlegroups.com
So 0.0 == 0 returning 1 is highly unreasonable?

Why?

Am Mo., 20. Apr. 2020 um 02:57 Uhr schrieb 陈圣麒 <seik...@gmail.com>:
0.0 ? "foo" : "bar"  returns bar
That seems highly unreasonable

--
You received this message because you are subscribed to the Google Groups "LDMud Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ldmud-talk+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ldmud-talk/6f4ed761-7896-4f47-9b4e-6e771709f748%40googlegroups.com.

Malcolm Tester

unread,
Apr 20, 2020, 3:28:01 AM4/20/20
to LDMud Talk
I would ask which version of the driver is this?  On 3.4.2 (a little older than current I know), I ran this test:
~/temp>cat float_test.c
int
test
() {
   
return 0.0 == 0;
}
string
test2
() {
   
return (0.0 ? "foo" : "bar");
}

And test() returns 1, and test2 returns "foo".

I have to admit though, I would have expected opposite results.  In purely technical terms, 0.0 is not the same as 0, unless you type cast it to an int, which is probably what the driver is doing.  And I don't understand how 0.0 would evaluate to a true expression in the second test.

-Malc


On Monday, April 20, 2020 at 12:11:23 AM UTC-6, Croft wrote:
So 0.0 == 0 returning 1 is highly unreasonable?

Why?

Am Mo., 20. Apr. 2020 um 02:57 Uhr schrieb 陈圣麒 <seik...@gmail.com>:
0.0 ? "foo" : "bar"  returns bar
That seems highly unreasonable

--
You received this message because you are subscribed to the Google Groups "LDMud Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ldmud...@googlegroups.com.

Gnomi

unread,
Apr 20, 2020, 6:45:55 AM4/20/20
to ldmud...@googlegroups.com
In LPC only the number 0 is considered false, everything else is true.
The number 0 is special in that regard, that every type can have this value,
even floats:

float f = 0;
is different from
float f = 0.0;

To check, try get_type_info(f).

Since LDMud 3.2.9 comparisons of floats with integers are done by converting
the integer to a float and comparing both floats. This comfort feature is
not without dangers. On 64-bit systems the integers have a higher precision
than the floating points numbers. Something like this will not work as
expected:
float f = __INT_MAX__ + 1.0;
if (f <= __INT_MAX__)
return to_int(f);

Therefore I'm not sure that this comparison of ints against floats was a
good idea.

For boolean evaluation floats are still not compared against 0.0, because
this would introduce further ambiguities. See for example:
float f = 0.15 + 0.15 - 0.1 - 0.2;
You might think, that f should be 0.0, but my CPU calculates -2.77556e-17.
You see that comparisons of floats with integers therefore needs an error
margin, but this margin is depending on the circumstances. I don't think
that the LPC virtual machine should guess this margin for the comparison.

The treatment of 0.0 in boolean expressions as true forces the programmer
to think about these edge cases and handle them.

Regards,
Gnomi.

陈圣麒

unread,
Apr 20, 2020, 7:56:50 AM4/20/20
to LDMud Talk
thank you

Malcolm Tester

unread,
Apr 20, 2020, 12:32:30 PM4/20/20
to LDMud Talk
Great explanation, thanks Gnomi!

陈圣麒

unread,
Apr 21, 2020, 3:38:28 AM4/21/20
to LDMud Talk
Basically if(X) and if(X == 0) uses two different set of logic to compare stuff, in if(X) , only int value 0 is being treated as false, and float 0.0 is not. this is an clear inconsistency between LPC and C language

Stephan Weinberger

unread,
Apr 21, 2020, 12:45:40 PM4/21/20
to ldmud...@googlegroups.com

On 21.04.20 09:38, 陈圣麒 wrote:
> Basically if(X) and if(X == 0) uses two different set of logic to compare stuff, in if(X) , only int value 0 is being treated as false, and float 0.0 is not. this is an clear inconsistency between LPC and C language
>
First of all: who said that C and LPC must behave the same? :-)

But also in C this will (in most cases) only work if you explicitly set
X = 0.0f (which is defined as 'all bits 0' in IEEE floats). Try for
example "if (1.0 - 1.0)"... this will *not* work reliably (it will
depend on the exact implementation of floats in libc and hardware of the
machine). Hence it's best to avoid this sort comparison altogether.


cu

  Invisible@Beutelland


Reply all
Reply to author
Forward
0 new messages