0

I'm trying to set my temperature measurements to two decimal places. Currently what I get are six decimal places. Here is my code:

#include "math.h"

...

(in loop)
temp1 = sensors.getTempCByIndex(0);
     temp1 = roundf(temp1*100)/100;

Once I push temp1 to Firebase realtime database there are sic decimals, such as 26.059999. I'm using dsb20 sensor for temperature measurements. What could be wrong?

Thanks for your help in advance!

3
  • 1
    Is temp1 a float or a double? How do you transmit it to Firebase? Apr 16, 2021 at 18:28
  • @EdgarBonet temp1 is defined as a float. This is how I am pushing it to Firebase (using the esp32Firebase library: ` arr.set("/[0]", temp1); arr.set("/[1]", tms); Firebase.push(firebaseData2, "Devices/602", arr)`
    – Nina
    Apr 16, 2021 at 20:13
  • Did you try using a double? Apr 16, 2021 at 20:26

3 Answers 3

2

In addition to Majenkos answer:

A float cannot take any decimal number. It has a limited change and a limited resolution in that range you could say. So if often happens, that the flat (rounded) value is not a valid float. This is the case for 26.05. There is no valid float value, that is exactly 26.05. So the nearest valid float value is chosen. The following code would always print 26.059999:

float i = 26.05;
Serial.println(i);

since the variable i contains the float number 26.059999 (nearest valid float value to 26.06). That is the reason, why mostly the rounding of floats is only done directly with the outputting/printing. In that stage the number is not longer bound to the limitations of the float type (since it is internally not again saved in that type).

2
  • Thanks for your reply. The problem is that I need to use the number for further calculations and also to push it to Firebase Realtime Database. Therefore, is there a similar solution without serial print?
    – Nina
    Apr 16, 2021 at 18:56
  • As Majenko wrote you can use the int datatype. But it is unclear to me, why you really need to reduce to 2 decimal places in your database. If you are doing further calculations with that data the extra digits will not hurt. Or are you then just displaying that data form the database? Then the best way would be to round in that displaying program. Or you could send the data to firebase as a string. Then you can do the same rounding as with Serial.print() while constructing the string. Though I don't see the use in that.
    – chrisl
    Apr 16, 2021 at 19:02
1

float variables don't have a number of decimal places: that's how they get their name: "floating point" - the decimal point floats around as needed.

It's only when you output the value that it's rendered with a fixed (or limited) number of decimal places. Using Serial.print() the second digit is the number of decimal points:

Serial.println(temp1, 6); // 26.059999
Serial.println(temp1, 2); // 26.06
3
  • Thanks for your reply @Majenko. The problem is that I need to use the number for further calculations and also to push it to Firebase Realtime Database. Therefore, is there a similar solution without serial print?
    – Nina
    Apr 16, 2021 at 18:55
  • 2
    Use an integer but work with a multiple of your value. For two decimal places multiply it by 100, store it in an integer. When you then want to print it divide it by 100 again.
    – Majenko
    Apr 16, 2021 at 18:56
  • This is my code, but it still doesn't work: ``` float temp2 = sensors.getTempCByIndex(0); int temp3 = roundf(temp2*100); float temp1 = temp1/100;```.
    – Nina
    Apr 16, 2021 at 19:30
0

one can convert to n decimals with the String Class

float num = 3.14159
String str1 = String(num, 1) // 3.1
String str2 = String(num, 2) // 3.14
String str3 = String(num, 3) // 3.141

Your Answer

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

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