I am broadcasting a fixed value float over a HC-12 radio which is then received by another HC-12 radio. I am then trying to convert that String to a Float which requires 6 decimal places. However, when I print the String value out and then the Float value out, I get two different answers.


    String lat=getValue(_msg, '|', 6); // Function to get lat value from incoming message
    Serial.println(lat.toFloat(), 6);

This then results in the following values being displayed to the user:


The value 51.507401 is the correct value, so I would ideally like the float value to be the same.

  • A float is only an approximation. That is as close as it can get.
    – Majenko
    Jul 12, 2020 at 16:33
  • Is there anyway to get closer? Even .toDouble() gives the same result Jul 12, 2020 at 16:34
  • There is no double on an Arduino. It's all float.
    – Majenko
    Jul 12, 2020 at 16:34
  • I would suggest not working in any form of floating point. Instead work in a fixed point. Use long and use the value x 1,000,000 or something like that.
    – Majenko
    Jul 12, 2020 at 16:35
  • Store 51.507401 degrees as 51507401 microdegrees
    – Majenko
    Jul 12, 2020 at 16:36

1 Answer 1


It seems the toFloat() method is being a bit sloppy in its conversion. The float closest to 51.507401 is 51.5074005126953125, which is only 0.13 ulps off. The number you got is the float right before it, namely 51.507396697998046875, which is 1.13 ulps off. Alas, the avr-libc functions atof() and strtod() make the same error.

I would suggest first considering whether the error is really significant for your application: it is only about 48 cm on the surface of the Earth. If this level of accuracy is relevant for you, then follow Majenko's suggestion and use an integer count of microdegrees.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.