Disasters with negative floating point values

Discussion in 'Fallout General Modding' started by Endocore, Dec 26, 2014.

  1. Endocore

    Endocore Look, Ma! Two Heads!
    Modder

    362
    Mar 14, 2010
    I'm not sure what to say about something I found, except that it seems inconsolably bad and I'm hoping one of our programming gurus can make some sense of it, because I have no idea what's going on with Fallout 2's calculations.

    Please try the following examples in a script of your choice:

    Example A:

    Code:
    variable test := 0;
    test := floor(-5.5);
    display_msg("result= " + test);
    
    Output:
    result= 1085276160


    Example B:

    Code:
    variable test := 0;
    test := (-5 / 2);
    display_msg("result= " + test);
    
    Output:
    result= 2147483645

    Any insight will be much appreciated, especially if anyone has a way to work around the problem.
     
  2. darkf

    darkf Caller of the Void Modder

    73
    Jul 12, 2014
    I haven't tried it so I'm going to make an educated guess.

    variable test := 0;

    defines test as having a type int. When you later say test := floor(-5.5), it's going to try to assign the result as an integer. Instead of coercing the float value to an int, it's instead going to interpret the float as an int, hence the weird values you get.

    We can try this experimentally, in C++ for example:

    Code:
    #include <iostream>
    
    
    int main() {
    	float y;
    	*(int*)&y = 1085276160;
    	std::cout << y << std::endl;
    
    
    	*(int*)&y = 2147483645;
    	std::cout << y << std::endl;
    
    
    	return 0;
    }
    
    On my machine (and really any machine with IEEE 754 floats where sizeof(int) == sizeof(float)), I get:

    Code:
    5.5
    nan
    
    I can't explain the NaN, perhaps division does something strange in the VM. The 5.5 is the result of the floor, which is erroneous?

    It could also just be the + operator that does the weird coersion. Anyway, try using variable test := 0.0;
     
  3. Endocore

    Endocore Look, Ma! Two Heads!
    Modder

    362
    Mar 14, 2010
    Thanks :smile:, darkf, you made a good guess and good effort, but in the Fallout 2 scripting language variables are completely untyped (integer/float/string promotion occurs freely as needed). For the record, I had already tried initializing the variables as floats (0.0), but this made no difference (as expected).

     
  4. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    What version of sfall are you using, guys? There was a serius bug in negate operator which resulted in similar problems and was fixed in 3.4.

    If you don't wish to use sfall, try assigning negative value in varaible initializer first (it works slightly different than assignment, uses negative value directly w/o calling "negate" operator):
    Code:
    variable a := -5;
    
    display_msg("result: "+ (a / 2));
    
     
    Last edited: Dec 28, 2014
  5. Endocore

    Endocore Look, Ma! Two Heads!
    Modder

    362
    Mar 14, 2010
    Thanks, phobos2077. I see I'm using sfall 3.2, I'll update to the newer version and check things out. I don't think that other suggestion would work, though. As far as I know, variables can't be initialized at a negative value (I think this is also in Noid's documentation).
     
  6. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    Well, in sfall sslc they can. Not sure if it was Timeslip addition or original behavior (local variable initialization are simply putting values into the stack, sfall compiler specifically checking if there is a minus sign before constant and negates value if it is). In latest compiler you can also initialize locals with complex expressions ;)