Math problem in ESP32?

Hello. Why when performing the following mathematical operation with float, the result is -0.0?
I don't make sense of the "-" sign.
In the following code you can see the result:

float val1 = -0.1;
float val2;

void setup(){
Serial.begin(115200);
}

void loop(){
val2 = val1 + 0.1;
Serial.println(val2);
}

What does it print when you increase the number of decimal places
Serial.println(val2, 8);
Leo..

In C++, a floating-point literal defaults to type double. On the smaller Arduino platforms like Uno, double is the same as float. But on ESP32, it's the normal size, 64 bits.

void setup() {
  Serial.begin(115200);
  auto f0 = 0.1;
  float f1 = -0.1;
  Serial.println(sizeof(f0));
  Serial.println(sizeof(f1));
  Serial.println(f1 + 0.1);
  Serial.println(f1 + (float) 0.1);
  Serial.println(f1 + 0.1, 15);
  Serial.println(f1 + (float) 0.1, 15);
}

void loop() {
  delay(10);
}

produces

8
4
-0.00
0.00
-0.000000001490116
0.000000000000000

on ESP32. If you want to work in float to save memory at the cost of precision, you need to use the f suffix, e.g. 0.1f

0.1 is about 0.100000000000000005551
0.1f is only 0.100000001490116119385

1 Like

Thanks for the answers.
Part of the code I use is the following:

float can2volt = 0.0F;

void setup() {
Serial.begin(115200);
}

void loop() {

 if (can2volt > 4.9) {
        can2volt =  -5.1;
      }
      can2volt = can2volt + (float) 0.1;
      //tft.drawString(String(can2volt, 1), 270, 71, GFXFF);
      Serial.println(String(can2volt,1));

delay(50);
}

Still showing -0.0
I have tried various combinations with (float) , F and the result is the same.
What is it that I am missing?

It is a rounding error. The result of your calculation is very close to zero but slightly negative. Hence the - sign.
Remember that 0.1 cannot be represented in float representation as precise as in decimal presentation. Like 1/3 cannot be represented in decimal format (at least not without an infinite amount of threes after the .
You could add an if to test for very small negative value and replace with 0.0...

if (x<0) {
  if (x>-0.0001) {
       x=0.0;
   }
}
1 Like

That this is not a math problem. The ESP32 and code are functioning as designed.

Why do you care that the result is a very tiny negative number?

See Signed zero - Wikipedia

The IEEE 754 standard for floating-point arithmetic (presently used by most computers and programming languages that support floating-point numbers) requires both +0 and −0. Real arithmetic with signed zeros can be considered a variant of the extended real number line such that 1/−0 = −∞ and 1/+0 = +∞; division is undefined only for ±0/±0 and ±∞/±∞.

Negatively signed zero echoes the mathematical analysis concept of approaching 0 from below as a one-sided limit, which may be denoted by x → 0−, x → 0−, or x → ↑0. The notation "−0" may be used informally to denote a negative number that has been rounded to zero. The concept of negative zero also has some theoretical applications in statistical mechanics and other disciplines.

Thank you very much everyone for the responses. And I stay clear. I have fixed it as indicated by build_1971.