Disasters with negative floating point values

Endocore

Look, Ma! Two Heads!
Modder
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.
 
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;
 
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).

Noid said:
There are three types of data that can be assigned to a variable - integers, floating point numbers and strings. Variables are untyped, so a variable that previously contained data of one type, can be reassigned to contain data of a different type.
 
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:
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).
 
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).

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 ;)
 
Back
Top