almost 0 reports #IND after a math

Previous topic - Next topic

Hemlos

gernot here is the test ...

i put a small project in test.rar too...attached to this message

Code (glbasic) Select
LIMITFPS 40
// use up and down arrows

WHILE TRUE
IF KEY(200 ) THEN gravity=gravity + 0.1
IF KEY(208 ) THEN gravity=gravity - 0.1
IF gravity >=1.0 THEN gravity =1.0
IF gravity <=-1.0 THEN gravity =-1.0
PRINT "gravity="+gravity,10,10
SHOWSCREEN
WEND




[attachment deleted by admin]
Bing ChatGpt is pretty smart :O

Hemlos

#1
Quote from: Ocean on 2009-Jul-06
your test project remains rock-solid within -1 and 1 on my system, both with and without debugger activated.

The bounds isnt the problem.....its the almost 0 number.

This is what is suppose dto happen:
0.1-0.1=0

This test is showing is that, when you go from 0.1 or -0.1 and try to go to zero position, you get a tiny number instead of zero....gernot said it should be zero, and asked for a sample showing it is not.

0.1-0.1=0.00000000000000002775557562

An infinetly small number and i didnt even do anything strange to the algorithm...it is simplly one tenth minus one tenth...and this should be zero.


Bing ChatGpt is pretty smart :O

Kitty Hello

Correct. If you add 0.1, then subtract it, the result will differ from the previous value, since 0.1 can't be displayed in binary form correctly. It's a bit of a problem with floats, so always try some range or > than, < then comparisons.


In your case:
INC gravity, (KEY(200)-KEY(208)) * 0.1
gravity = MAX(0.0, MIN(1.0, gravity ))

Kitty Hello

It's not wise to check against the epsilon of a floating value. It's better to define your own epsilon depending on your problem. E.g. if you want the angle of a triangle, and the angle is very steep, a value of 1E-5 might be too slim for you so you consider it zero, already.
We do this a lot in commercial applications and always define different epsilon values for each problem. For geometic problems in real life (geotechnics in my case) a value of 0.1 mm is the eplsilon, even.

Hemlos

#4
Quote from: Kitty Hello on 2009-Jul-07
Correct. If you add 0.1, then subtract it, the result will differ from the previous value, since 0.1 can't be displayed in binary form correctly. It's a bit of a problem with floats, so always try some range or > than, < then comparisons.


In your case:
INC gravity, (KEY(200)-KEY(208)) * 0.1
gravity = MAX(0.0, MIN(1.0, gravity ))


I wrote a math decimal rounding function while you were sleeping actually, and it works great for a million purposes. Essentially, it produces a number with adjustable right hand precision, which is reusable with litteraly no FPS loss:

Code (glbasic) Select
@FUNCTION Math_RoundDecimal: Real_Number, Decimal_Power //Round Decimal Numbers
// The Decimal Power must be a power of 10, eg, 1 2 3 4, 3=thousands place.
  Real_Number=INTEGER( Real_Number * POW( 10, Decimal_Power ) ) / POW( 10, Decimal_Power )
  RETURN Real_Number
ENDFUNCTION


if gravity >1.0 then gravity=1.0;   if gravity <- 1.0 then gravity=-1.0
Gravity=DecimalRound(Gravity,1)

this keeps it 1.0 to 0.1 or 0, or -0.1 or -1.0.....what ever the predefined range is with a predefined right hand precision for every instance.

And for vectoring, acceleration, velocity, and scaling, I set all the precision with a variable; a right=hand-precision of 5 is good enough to produce some beautiful graphics:

RHPrecision=5
VectorX=DecimalRound(Gravity,RHPrecision)

This makes it bulletproof, preventing tiny numbers from crashing the memory slot.


This is the method im using in the toy particle engine, in the showroom. You can see it in action with the Gravity value showing on the screen.


Question:
I want the PE to be useable on 4 bit machines:
4 byte (32 bit) floating point numbers on the "small" systems, is 10 digits?
So a left and righthand precision of 5 is going to allow thier processors to work with my code?
EG: 12345.98765, or 0.00001 ?

Bing ChatGpt is pretty smart :O

FutureCow

#5
If I'm reading correctly that
Quote0.1 - 0.1 will not equal 0

Can this problem with floats please be documented in the manual for the next release? I can understand from a technical perspective that floats would be approximated causing the problem, but on the other hand I'm absolutely astounded that such a simple maths problem wont work!  :S
Is there a way to specify (through extern C commands perhaps?) the number of decimal places in a float to get around the issue (So you don't have to use Hemlos's code for every calculation)?

This has got me shaking my head in wonder!  :O

Hemlos

#6
Quote from: FutureCow on 2009-Jul-10

Is there a way to specify (through extern C commands perhaps?) the number of decimal places in a float to get around the issue (So you don't have to use Hemlos's code for every calculation)?

This has got me shaking my head in wonder!  :O

Sorry to scare you, but the solution is simple..

My way is better than C handling it, because you can choose when to round them.
You dont need to round unless you divide/crunch majorly small numbers with sin and cos for example.

In any case a simple if cow<0.1 then cow=0 ..makes it "bulletproof" and stable without internal processes adding extra math to every calculation...the math side is slow enough.
Bing ChatGpt is pretty smart :O