The operators
==
, !=
, !
and conversion to/comparison with boolean are not safe to use with floats. I'm thinking about letting ==
return false
, !=
return true
, !
return false
and conversion to boolean return false
. (Yep, that would make !0.0 == 0.0
) I'd probably also issue a warning. For equality comparisons between floats and ints, I could imagine rounding.Opinions on that? The aim is to prevent people from doing things like
for(var f = 0; f != 7.0; f+=0.7)
while not bothering anyone writing sane code with non-standard float-behavior.
One other thing I was wondering: The use of SSE to keep floating point operations synchronous is a nice idea in theory, but have there been any tests yet that it also works in practise?
> The use of SSE to keep floating point operations synchronous is a nice idea in theory, but have there been any tests yet that it also works in practise?
Probably not. If it doesn't work though, there's free soft float libraries on the net which could be dropped in as a replacement.
>The operators ==, !=, ! and conversion to/comparison with boolean are not safe to use with floats. I'm thinking about letting == return false, != return true, ! return false and conversion to boolean return false. (Yep, that would make !0.0 == 0.0) I'd probably also issue a warning. For equality comparisons between floats and ints, I could imagine rounding.
If you don't want people to use it, I'd rather issue an error than a warning. A error has more of a "you can't do that" feeling to it, which would be more appropriate here?
>The aim is to prevent people from doing things like for(var f = 0; f != 7.0; f+=0.7) while not bothering anyone writing sane code with non-standard float-behavior.
I would rather just always give a warning but let comparison operators behave as expected.
I could imagine a situation like
var f = 1.0;
if(InDanger()) f = 0.5;
else if(IsHungry()) f = 0.3;
// nothing altered the expected outcome?
if(f == 1.0) BeExcited();
also, I give you a 8.299069400001 / 10 for the effort on the floating points
hg pull http://bitbucket.org/caesar/openclonk/ -r floating-point
unless you want to have a lot of nasty stuff in your hg history.I've also made a random script to test syncness, the output should be equal to 1B1B1B1B0I0I0I0I0I0Ic064e1c0Fc0189680F0I0F0F0Fbf800000F0F3f800000Fc0400000Fc402d50bFbf189680F0F0F0Fbf189680F0Fbf989680F0F3f989680F0Fbf189680F0F0F0F0F1B1B1B1B1B1B1B0I0F0I0F0F0F0F0FffffffffF40490fdbFba6b8000F42bbb781F387d6000F3b95e000F3a3b0000F39f00000F38800000F3b960000F3a380000F39f00000F38800000F3b960000F3a400000F39f00000F38800000F3b960000F3a380000F39f00000F3ad419efF
Note:
- Model animations are broken. You can fix that by commenting out https://bitbucket.org/caesar/openclonk/changeset/7df17ef06b01#chg-src/script/C4AulExec.cpp which is responsible for converting floats to ints when the function specifies it. I haven't made my mind up how to fix that properly.
- MinGW won't build SSE stuff properly. It fails to align __m128 C4Real::value to 16 bytes but uses movaps instead of movups. It would be nice if anyone could come up with a workaround for that... If you fix the bytecode manually, it should work though.
- Nothing is documented
- Most functions and all operators work on the basis: Take no float as parameter: return int, else return float. Exceptions: Angle(), always returns float unless iPrec is set to something non-float which evaluates to true; Random(): returns floats in [0;1[ when parameter is false, nil, 0 or 0.0;
- Array access with floats behaves weird. I'm not sure whether I should fix that...
- You can't start Crash because it uses a Game.txt which sets the X and Y coordinates to /[0-9]+/, and the StdCompiler won't parse that because it expects Floats not Ints...
If you just want to toy around a little, c4scr in #openclonk is loaded with floats.
> Model animations are broken. You can fix that by commenting out https://bitbucket.org/caesar/openclonk/changeset/7df17ef06b01#chg-src/script/C4AulExec.cpp which is responsible for converting floats to ints when the function specifies it. I haven't made my mind up how to fix that properly.
The current philosophy of C4Value type conversions is to convert at the last possible step, and not modify the internal representation at all. For example, if a function specifies that it wants an object, the parameter will be checked and rejected if it is not an object, but the type tag will remain proplist. Currently this only requires modification of the bit representation of the value for _getBool. (_getObj could as well cheat and reinterpret_cast since C4Object doesn't inherit from multiple classes, but we have enough hacks already.)
I'd recommend that you either totally switch back to the "modify the internal representation" model of typechecks, or maintain the current model and have _getInt and _getFloat convert from float/int when necessary. (I'd do the latter, but then I'm the one who switched the engine from the modify to the check-only model.) In any case you shouldn't need to add more typecheck/conversion functions to C4Value - CheckParConversion and CheckConversion are called at the appropriate places. The engine only calls the _get functions after a Check(Par)Conversion has succeeded, so _getFloat would only have to worry about integers and bools, but not the various pointer types.
But I'd like to honor the fact that coordinates and rotation are stored by floats internally with the right return types of GetX, etc. Which makes a lot of functions in script request an int parameter but actually wanting a numeric or float one. (There are currently more than 1000 functions taking typed int parameters.) I'll be cut off from the internet next week, so I guess I could visit each and every one of them. The question is, do I want to touch that much of the code? The other option is to force everyone who wants to enforce types use
Int(num)
and Float(num)
.I've even got two more options, just mentioning: I could also add #strict-parameters which new scripts could use or add a parameter type modifier "conv" (or something alike) so you would write func
bla(conv float fp)
.Also, should I error on array access with floats? It would be a inconsistent, but it feels right.
Edit: Same machine, 64 bit MSVC build, seems to be in sync, too.
Does anyone want to write a more aggressive test?
Edit2: Test with mingw32, equal output.
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill