1

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?

2
  • 3
    Have you tried using double instead of float? AFAIK Python uses 64-bit precision floating point numbers Commented Sep 2, 2022 at 13:15
  • Have you tried rounding the value? Commented Sep 2, 2022 at 13:39

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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 )

4 Comments

I am unable to change the Java code, so I need to get the less precise number in Python, rather than increasing the precision in Java.
@Sam As far as I'm aware, Python doesn't have 32-bit float (single/binary32) support, only 64-bit (double/binary64).
@Sam I think you just need to round your number to achieve what you need.
@MarkRotteveel Python doesn't (at least typically), but NumPy does.
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.