I am trying to convert some Java code to Python, but seem to be running into issues with floating point precision.
I am unable to change the Java code, so the solution needs to be in the Python.
Java code:
float Ax = -0.13044776f;
float Ay = -0.17653446f;
float Az = 9.8041935f;
final float Ex = -40.55481f;
final float Ey = -22.624207f;
final float Ez = -57.284546f;
float Hx = Ey * Az - Ez * Ay;
In Java Hx
has a value of -231.9248
Python code:
Ax = -0.13044776
Ay = -0.17653446
Az = 9.8041935
Ex = -40.55481
Ey = -22.624207
Ez = -57.284546
Hx = float(Ey * Az - Ez * Ay)
In Python Hx
has a value of -231.92479960650965
Why is there more points of precision in Python, and how can I replicate the Java behaviour?
CodePudding user response:
As others have said: Instead of float
use double
as it has more precision to match the precision that Python is using. Also note that you will need to change your literals to not be declared as floats
(like -0.13044776
f
is)
double Ax = -0.13044776;
double Ay = -0.17653446;
double Az = 9.8041935;
final double normsqA = (Ax * Ax Ay * Ay Az * Az);
final double g = 9.81;
final double freeFallGravitySquared = 0.01 * g * g;
final double Ex = -40.55481;
final double Ey = -22.624207;
final double Ez = -57.284546;
double Hx = Ey * Az - Ez * Ay;
System.out.println(Hx);
// result: -231.92479960650965 matching Python exactly
CodePudding user response:
Change float
to double
in you Java code. Now Hx
will contain -231.9247949756118
when you keep the f
suffix in your numbers or -231.92479960650965
if you remove it. You need to understand that floating point numbers have an intrinsic imprecision. In Java, if you need exact precision, you will need to use the BigDecimal
class:
BigDecimal Ax = new BigDecimal( "-0.13044776" );
BigDecimal Ay = new BigDecimal( "-0.17653446" );
BigDecimal Az = new BigDecimal( "9.8041935" );
BigDecimal normsqA = Ax.multiply( Ax ).add( Ay.multiply( Ay ).add( Az.multiply( Az ) ) );
BigDecimal g = new BigDecimal( "9.81" );
BigDecimal freeFallGravitySquared = new BigDecimal( "0.01" ).multiply( g ).multiply( g );
BigDecimal Ex = new BigDecimal( "-40.55481" );
BigDecimal Ey = new BigDecimal( "-22.624207" );
BigDecimal Ez = new BigDecimal( "-57.284546" );
BigDecimal Hx = Ey.multiply( Az ).subtract( Ez.multiply( Ay ) );
System.out.println( Hx );
Now, Hx
contains -231.92479960650966
.
EDIT: I think I misunderstood your question.
I think you can round the value in Python to "simulate" the less precision that you need. Something like:
Hx = round( float(Ey * Az - Ez * Ay), 4 )
CodePudding user response:
I've answered my own question with the knowledge that others have shared here.
numpy
has a float32
data type https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.float32
Python code
Ax = float32(-0.13044776)
Ay = float32(-0.17653446)
Az = float32(9.8041935)
Ex = float32(-40.55481)
Ey = float32(-22.624207)
Ez = float32(-57.284546)
Hx = Ey * Az - Ez * Ay
Hx
is now -231.9248