Home > Software engineering >  Java v Python floating point arithmetic
Java v Python floating point arithmetic

Time:09-03

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.13044776f 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

  • Related