float returns wrong value?? SOLVED

Started by spook1, Mon 28/01/2008 22:17:44

Previous topic - Next topic

spook1

In my gam,e the player can move pistons of a lock by connecting a battery to some coils. I mcalculate the current through the coil, and move piston proportionally to this current.
A snip of the script is given below.
At startingpoint the A_dx  value equals -1. I do not understand that, since

I_PistonA = -240
A_DX = -70
MaxPistonCurrent = 10 000 000  (ten million!!)

So how can A_dx = A_DX * I_PistonA / MaxPistonCurrent equal -1??

That would mean that: -1 = 70*240/10000000 . It should read 0.00168!

can anyone help with a suggestion??


Code: ags

  //first set the max movement for full Piston Current
 
  int A_DX = -70;  // means 70 pixels for full movement outward of the disk at max current
  float Zero = IntToFloat(0); 
  float A_dx = Zero;  // because I need much more parameters to be set to Zero later on
 
  //now calculate the actual movement in x direction:
  
  A_dx = IntToFloat(A_DX) * (IntToFloat(I_PistonA) / IntToFloat(MaxPistonCurrent) );

 // and finally move
  
  object[2].SetPosition(36  + FloatToInt(A_dx), 113 );




Snarky

I don't see the initialization of I_PistonA there. You're sure it's correct?

spook1

#2
Hi Snarkey,

Yes, when looking in the debugger I can see that I_PistonA is -240, the other values are also shown in the debug Gui. (these are initiated in the init() function, elswhere in the script.)

I have a debug- gui set up to display these values. It show also this annoying -1 instead of 0.00168 :-(

thanks for your interest in my problem. Would know of any more suggestions?

Pumaman

Are you sure that the I_PistonA and MaxPistonCurrent are set as you say? Put a Display in just to be sure.

I pasted the following code into my script and it correctly displayed 0.00168:

Code: ags

int A_DX = -70;  // means 70 pixels for full movement outward of the disk at max current
float Zero = IntToFloat(0); 
int I_PistonA = -240;
int MaxPistonCurrent = 10000000;
 
//now calculate the actual movement in x direction:
  
float A_dx = IntToFloat(A_DX) * (IntToFloat(I_PistonA) / IntToFloat(MaxPistonCurrent) );
Display("Result: %f", A_dx);

Snarky

Whether or not there's something else going on here, I would suggest that you change the association of the calculation, like so:

  A_dx = (IntToFloat(A_DX) * IntToFloat(I_PistonA)) / IntToFloat(MaxPistonCurrent);

(The parentheses are different.)

It's better to multiply first before you divide, because when you divide by a number as large as ten million, you'll get something very close to 0, and rounding errors might affect your result significantly. In fact, single-precision floats (which I guess AGS uses?) only have about 7 digits of precision, and you're dangerously close to that in the intermediate value. I'm not sure what happens in AGS if a calculation underflows, but it's not unthinkable that it defaults to -1.

Kweepa

There is no way this calculation will underflow. The 7 digits of precision refers to the mantissa. The division here will only affect the exponent. You usually only need to worry about precision when subtracting similar large numbers.

So I suggest posting your init() function and the code that sets up your debug gui.
Still waiting for Purity of the Surf II

Snarky

Good point. I should have thought it through more carefully.

Khris

Something completely unrelated:
To set a float to zero, just call
float x = 0.0;

spook1

Thanks for all these help during my night sleep.

I see one difference in the debug message I use:

I stated:

Display("A_dx = %d", FloatToInt(A_dx);

instead of

Display("Result: %f", A_dx);

Can it be that FloatToInt rounds off in a special way?

I'll look into it after I come back from work; have to make breakfast for my kids now ;-)

CU

spook1

Just checked in my boss' time.
It was eRoundnearest I forgot in the FloatToInt.
Now it works allright,

Thanks for thinking along with me last night ;-)

SMF spam blocked by CleanTalk