Not logged inOpenClonk Forum
- - By Caesar [de] Date 2012-03-26 18:20
I'm moving forward on my way to merging floats, I've so far fixed the movement code (may be only partially), implemented a lot of operators for floats and will start changing the arithmetic functions like FnSin soon. I've got a few design choices to make, e.g. I'll make the arithmetic functions return ints when called with ints and floats when called with floats, keeping Isilkor's plan. Also I'll let the precision parameters work as accustomed to prevent existing code from breaking. But consider this:

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.
Parent - - By Clonk-Karl [de] Date 2012-03-26 18:28
I'd suggest to do it the way other programming languagues (C, Python, ...) do it, or there will be more confusion than everything else.

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?
Reply
Parent - - By Newton [de] Date 2012-03-27 17:21
What's SSE?
Parent - - By Link-Mario [de] Date 2012-03-29 17:50
When I looked at this description I had the feeling that you have to use a low-level programming language like Assembler to use SSE.
Reply
Parent - By boni [at] Date 2012-03-29 20:11
You're somewhat right. It's a processor instruction (every assembler line is a processor instruction), so it's not as easy to access as a C++-Library. However, that doesn't mean that there aren't any methods to access them without assembler. ;)
Parent - By Caesar [de] Date 2012-03-29 20:30
You use intrinsics, which are basically wrappers for the assembly instructions with a _mm_-prefix, but that takes away the hassle of writing assembly for all the different compilers and possibly managing register allocations. I've looked at the disassembly, gcc optimizes these functions away, you won't even see that they existed.
Parent - By Isilkor Date 2012-03-29 15:52

> 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.
Reply
Parent - By boni [at] Date 2012-03-26 18:56

>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?
Parent - - By Zapper [de] Date 2012-03-26 20:18

>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
Parent - By Caesar [de] Date 2012-03-26 20:20
That and comparing with inf or nan have convinced me not to do it.
- - By Caesar [de] Date 2012-04-01 11:06 Edited 2012-04-01 11:16
With the c4script standalone, I've reached a state where I think that I can let everyone have a look... If you want to test and see, you should pull via 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.
Parent - - By Günther [de] Date 2012-04-01 17:23

> 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.
Reply
Parent - By Caesar [de] Date 2012-04-02 00:01
Programmatically, I prefer the "modify internal representation"-method. It's basically what I already have, and it works just fine as long as you don't launch clonk.
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.
Parent - By Caesar [de] Date 2012-04-04 17:51 Edited 2012-04-05 13:23
Just tested my syncness script on Win64, 32bit MSVC2010 build, there seems to be no difference between that and lin64/gcc.

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.
- By Caesar [de] Date 2012-05-02 23:32
Little status side-note: Pushed my changes from bitbucket to the official repo. I'm sure I'll learn about some bugs soon.

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill