1. literal 9223372036854775808 is negative

Interestingly if you stick .0 on the end it's alright...

No show-stopper, but mis-parsing numbers has gotta be a biggie/no-no.

Euphoria Interpreter v4.1.0 development 64-bit Windows, Using System Memory Revision Date: 2015-02-02 14:18:53, Id: 6300:57179171dbed

I'd file a ticket, but...

Amusingly, I was just doing something in Go, and found that int(math.Sqrt(float64(-1))) is [also] -9223372036854775808

new topic     » topic index » view message » categorize

2. Re: literal 9223372036854775808 is negative

Windows Calculator does the same thing.

Select Programmer mode and enter 1 << 63 you get -9223372036854775808.

This may not be the Euphoria bug we think it is.

-Greg

new topic     » goto parent     » topic index » view message » categorize

3. Re: literal 9223372036854775808 is negative

ghaberek said...

Windows Calculator does the same thing.

Select Programmer mode and enter 1 << 63 you get -9223372036854775808.

LOL. I must be biased because Phix gets it right....

Of course the calculator is using an int64 rather than a uint64 (in programmer mode, that is, IEEE-754s everywhere else).
In Eu terms (and with some quite hefty poetic licence) it is a bit like #3F + 1 being stored not as the positive #40 but
as the negative #C0 (yeah, I know they don't quite line up). I can only assume the parser is getting a switchover wrong:
I seem to recall but could be imagining this, when it finds a decimal point or when things get too big it simply discards
the int it's been building and starts again in a float. Maybe it is only #8000.., and fine +/-1 or more away from that.

Speaking of which, we found (some time ago) specifying the exact same value as #8000000000000000 works fine, as does
specifying it as 9223372036854775808.0 (!) or power(2,63). Hence it is the Euphoria bug I think it is.

I am going to push a bit harder on this now, because we've just spent a frustrating four weeks trying to figure out the
best way to deal with(/gloss over) this[DONE], when of course the proper thing would be to get it fixed.
Plus I think I fully understand the issue now, just not where the bit of code going wrong is, point me at it if you need help.

new topic     » goto parent     » topic index » view message » categorize

4. Re: literal 9223372036854775808 is negative

ghaberek said...

Windows Calculator does the same thing.

Select Programmer mode and enter 1 << 63 you get -9223372036854775808.

petelomax said...

Of course the calculator is using an int64 rather than a uint64 (in programmer mode, that is, IEEE-754s everywhere else).

Similar to what OE does, down to the int64 (integer) and long 80bits double (atom) parts.

petelomax said...

I seem to recall but could be imagining this, when it finds a decimal point or when things get too big it simply discards
the int it's been building and starts again in a float. Maybe it is only #8000..,

Speaking of which, we found (some time ago) specifying the exact same value as #8000000000000000 works fine, as does
specifying it as 9223372036854775808.0 (!) or power(2,63).

I think you've hit the nail on the head here. If we hit a case that causes the parser to construct as a long double (or a library call in the case of power) then it stores the value correctly as a positive number.

However, if we have a code path that sticks only to integers, then it ends up overflowing to negative.

petelomax said...

Plus I think I fully understand the issue now, just not where the bit of code going wrong is, point me at it if you need help.

I think it's not that straightforward. In my mind the issue here is that the parser in general would need to be able to detect when overflow happens, and automatically promote from integer to atom in those cases.

Matt Lewis did something similar way back on autopromoting from integer to atom when we want to add a delete_routine to a value that'd otherwise be fine to be stored as just a plain integer.

Only, this would be harder as it was fairly simple to detect when delete_routine was invoked and do that promotion in one place, but we might need to throw this overflow checking all over the place in the parser to catch it reliably.

ghaberek said...

This may not be the Euphoria bug we think it is.

petelomax said...

Hence it is the Euphoria bug I think it is.

Debatable... on the one hand, Pete's POV seems the more user friendly one. But to back up Greg's POV, it might end up being a huge amount of work to fix up the issue and afterwards the overall behaviour might still be considered to be inconsistent (e.g. if overflow happens in machine code or a C dll that gets called).

petelomax said...

LOL. I must be biased because Phix gets it right....

Wonder what Phix does differently, and if that's an easy thing to copy over into OE.

petelomax said...

I am going to push a bit harder on this now, because we've just spent a frustrating four weeks trying to figure out the
best way to deal with(/gloss over) this[DONE], when of course the proper thing would be to get it fixed.

I mean, there are other workarounds. Adding a preprocessor that appends all literal integers in the source code with a ".0" so they are promoted by the parser into atoms is one idea that comes to mind.

new topic     » goto parent     » topic index » view message » categorize

5. Re: literal 9223372036854775808 is negative

jimcbrown said...

Wonder what Phix does differently, and if that's an easy thing to copy over into OE.

See https://openeuphoria.org/forum/m/137533.wc

Incidentally, #8000000000000000 probably works despite technically having the same bug, except that (unlike *10) *16 never introduces any error, and while #80..0 + '0' might be wrong that is perfectly cancelled out with the exact same error by -'0', which is not necessarily true for +'2' followed by -'0' (at such close proximity to the hardware limits), or more likely (unlike decimal) you've not going to do that anyway because of the whole 0-9/a-f thing.

PS You're probably right about one thing, I seem to recall that bug needed fixing in about 4 or 5 places in Phix (fewer than first feared, just the one in the compiler itself, but others in things like to_number).

new topic     » goto parent     » topic index » view message » categorize

6. Re: literal 9223372036854775808 is negative

As long as we are comparing languages. Python also does the right thing as evaluating the number as positive. Euphoria:

include std/io.e 
if 9223372036854775808 < 0 then 
  puts(io:STDOUT, "Euphoria: 9223372036854775808 is negative\n") 
end if 

Output:

Euphoria: 9223372036854775808 is negative 

Python:

if 9223372036854775808 < 0:  
  print("Python: 9223372036854775808 is negative\n") 
No Output. (Good)

Similar C + + fails to compile and gives the following error:

cpp.cpp:3:7: warning: integer constant is so large that it is unsigned 
    3 |   if (9223372036854775808 < 0) { 
      |       ^~~~~~~~~~~~~~~~~~~ 
 
The C + + code:
#include <iostream> 
int main() { 
  if (9223372036854775808 < 0) { 
    std::cout << "C++: 9223372036854775808 is negative\n"; 
  } 
} 

Although I think the C + + behavior is not really desirable, I prefer what it does to what Euphoria does right now.

The number is just outside of the range of what a 64-bit Integer can hold, but if it were a valid value, its binary representation would be the same as the one used for -9223372036854775808.

new topic     » goto parent     » topic index » view message » categorize

7. Re: literal 9223372036854775808 is negative

SDPringle said...

Although I think the C + + behavior is not really desirable, I prefer what it does to what Euphoria does right now.

Pro tip: you can avoid the Creole underline formatting by placing a tilde "~" before the "++"

-Greg

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu