Fl crashes on -9223372036854775808LL but accepts 2LL^63

Issue #28 resolved
Eric Hivon created an issue

Some IDL codes, for instance https://github.com/wlandsman/IDLAstro/blob/master/pro/mrdfits.pro (line 982)
use the literal value -9223372036854775808LL, which is accepted in IDL, but makes FL crash with the error
\% Error: number too big: 9223372036854775808
while FL would accept 2LL^63 which has the same numerical value.

Comments (4)

  1. Lajos Foldy repo owner

    I think the bug is in IDL. “-9223372036854775808LL” is parsed (both in IDL and FL) as two tokens, a unary minus and a signed integer. 9223372036854775808LL is too big for a 64 bit signed integer, the valid range is from −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

    Try this:

    IDL> var=9223372036854775808LL
    IDL> help, var
    VAR LONG64 = -9223372036854775808

    IDL silently assigns a big negative value to var, instead of the big positive value. In FL, you get an error:

    If I compile FL with a sanitizer, I get a warning for 2LL^63, too (signed overflow, and that is undefined in C/C++).

    Here is a minimal Fortran example:

    integer(kind=8) x
    x=2
    write (*,*) x**63
    stop
    end

    Compiling this with gfortran -fsanitize=undefined a.f I get a runtime error:

    a.f:3:23: runtime error: signed integer overflow: 134217728 * 68719476736 cannot be represented in type 'integer(kind=8)'

    x=-9223372036854775808gives a compile time error:

    2 |       x=-9223372036854775808
    |                             1
    Error: Integer too big for its kind at (1). This check can be disabled with the option ‘-fno-range-check’

    So, if it is an error in Fortran, it should be an error in IDL, too.

    The proper way to assign -9223372036854775808 to a 64 bit signed integer is: var='8000000000000000'xll

    Or var=-9223372036854775807ll-1ll

  2. Lajos Foldy repo owner

    The 32 bit version gives an error even in IDL, so the missing error for the 64 bit integer is really an IDL bug:

    IDL> help, -2147483648l
    
    help, -2147483648
           ^
    % Long integer constant must be less than 2147483648.
    

    The 64 bit version gives a different result in GDL:

    GDL> help, -9223372036854775808ll
    <Expression>    LONG64    =                      1
    

    -9223372036854775807-1 works everywhere.

  3. Log in to comment