Menu

#1005 gcc -Wc -Ofast ulongint from negative float

open
nobody
None
compiler
2024-06-04
2024-05-27
c Rex
No
'' zeros, or max ulongint with -2 loop start

for x as single = -1 to 0
  print culngint(x - 1)
next

FreeBASIC Compiler - Version 1.10.1 (2023-12-24), built for linux-x86_64

Discussion

  • c Rex

    c Rex - 2024-05-27

    bringing to attention .. regular fbc i see no error

     
  • Jeff Marshall

    Jeff Marshall - 2024-06-01

    I would guess that the direct conversion from float to unsigned should work correctly for positive floats to unsigned integer where number ranges are valid.

    If you are expecting conversion from a single '-1' to be the max value of a ULONGINT, try converting to LONGINT first.

    for x as single = -1 to 0
      print culngint(clngint(x - 1))
    next
    

    This should force handling x as a single and doing the conversion at run-time - mainly because fbc will insert asm code, preventing gcc from optimizing it away.

    For the direct float to unsigned integer conversion looks like fbc optimizes using gcc's __builtin_nearbyintf() to do the conversion, and looks like gcc optimizes the program at compile time by unrolling the loop, moving around expressions, and other integer optimizations, which has the effect of doing all conversions and expressions at compile time and only writing constants to the final assembly.


    Here's what I think:

    The floating point value is out of range for a direct conversion to an unsigned integer type and in combination with an unrolled loop and other integer optimizations we get different behaviour than the conversion to LONGINT -> ULONGINT at run-time (or if the loop was more iterations and not unrolled, or (x-1) was (x-variable) instead, etc.

    I believe this is undefined behaviour in C; and gcc compiler does not raise any warnings about this at compile time.

    gcc's handling of Floating Point --> C99 Annex F.4 --> C99 6.3.1.4p1

    https://gcc.gnu.org/onlinedocs/gcc/c-implementation-defined-behavior/floating-point.html
    https://port70.net/~nsz/c/c11/n1570.html#F.4
    https://port70.net/~nsz/c/c11/n1570.html#6.3.1.4p1

     
  • c Rex

    c Rex - 2024-06-04

    perhaps i will join gcc forum.

    anyway, this was my use case

    '' custom rng initialize
    sub set( _a as longint = 1, _b as longint = 0 ) '' changed to longint after i id'd culprit
      a = _a:  b = _b
    
    '' rng-based waveform
    sub chaos_wave( byref f as double, i as double )
    
      rng.set int(i)      '' seed
      f = rnd
    
      rng.set int(i) + 1  '' seed-in-sequence
      f = f + (i - int(i)) * (rnd - f)  '' linear interp
    

    chaos_wave retval, neg10_to_positiv10

    using set( .. as ulongint, .. ), chaos_wave output was like
    -------\/\/\/\

     

    Last edit: c Rex 2024-06-04

Log in to post a comment.

MongoDB Logo MongoDB