Error in ESP32?

When I run this code on an ESP32

bool runOnce = false;

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

void loop() {
  if (!runOnce)
  {
    runOnce = !runOnce;
      
    double distanceDelta =0;
    int ledsPerMeter = 100;

    int factor = 3;
    double constValue = 0.16;
    
    double to = factor * constValue; // works not
    //double to = 0.45; // works!

    double from = to - constValue;
    double a = from - distanceDelta;
    double b = a * ledsPerMeter;
    double c = b + 1;
    int d = c;
    Serial.printf("factor=%d\n", factor);
    Serial.printf("constValue=%lf\n", constValue);
    Serial.printf("to=%lf\n", to);
    Serial.printf("from=%lf\n", from);
    Serial.printf("a=%lf\n", a);
    Serial.printf("b=%lf\n", b);
    Serial.printf("c=%lf\n", c);
    Serial.printf("d=%d\n", d);
    Serial.printf("d+1=%d\n", d+1);
  }
}

I get this output:

factor=3
constValue=0.150000
to=0.450000
from=0.300000
a=0.300000
b=30.000000
c=31.000000
d=30
d+1=31

Notice that "c" has value of 31.0000...
This is correct.
But "d" has the value of "30"
And that´s not correct.

That´s strange. or?

More strange:
When I change

double constValue = 0.15;

to

double constValue = 0.16;

I get these results:

factor=3
constValue=0.160000
to=0.480000
from=0.320000
a=0.320000
b=32.000000
c=33.000000
d=33
d+1=34

Notice that here the value for "d" is correct.

So using 0.15 ends up in a wrong value for "d"
while using 0.16 works fine.

Where is my mistake?

%f is the correct format to use to display a double

c might actually be 30.99999999999999289457264239899814128875732421875 and print will round it up to 31 but assigning it to an int lead to truncation

try

  Serial.printf("c(31.0)=%.50f\n", c);
void setup() {
  Serial.begin(115200);
  double distanceDelta = 0;
  int ledsPerMeter = 100;

  int factor = 3;
  double constValue = 0.15;

  double to = factor * constValue; // works not
  double from = to - constValue;
  double a = from - distanceDelta;
  double b = a * ledsPerMeter;
  double c = b + 1;
  int d = c;

  Serial.printf("factor(3)=%d\n", factor);
  Serial.printf("constValue(0.15)=%f\n", constValue);
  Serial.printf("to(0.45)=%f\n", to);
  Serial.printf("from(0.3)=%f\n", from);
  Serial.printf("a(0.3=)%f\n", a);
  Serial.printf("b(30)=%f\n", b);
  Serial.printf("c(31.0)=%.50f\n", c);
  Serial.printf("d(31??)=%d\n", d);
  Serial.printf("d+1(32)=%d\n", d + 1);
}

void loop() {}

console shows

factor(3)=3
constValue(0.15)=0.150000
to(0.45)=0.450000
from(0.3)=0.300000
a(0.3=)0.300000
b(30)=30.000000
c(31.0)=30.99999999999999289457264239899814128875732421875000
d(31??)=30
d+1(32)=31

double on a esp32 is a 64 bit number, is a 64 bit number required?

@J-M-L

Thank you very much for the extremly fast clarification!
I does not know that something like
%.50f
exists!
This would helped me a lot!

So the solution is then to a "0.5" and than fire an integer over it?

int d = (c + 0.5);

seems to work in the emulator!
But it would be great to get your thoughts about "my" solution.

@Idahowalker

Thanks for your reply.

No it must not.
Variable "constValue" has two digits and there is no division needed. Means I need only two digits after the comma.

What type is then needed or would you take?

Or use https://cplusplus.com/reference/cmath/round/

just 32 bit floats.

Would like to say thank you - in that way that I post my code here ...
(Please notice my included test whether the numbers are fitting.)

double fromMeters = 0;
double toMeters = 0;

double distanceDelta = 0; // This is the distance in meter between the sensor and the first LED of the LED strip.
int ledsPerMeter = 100;   // Provides how many LEDs the LED strip per meter has.

int fromLedNumber = 0;
int toLedNumber = 0;

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

  Serial.println("");

  int oldFromLedNumber = 0;
  int oldToLedNumber = 0;
  for (int rangeSegment = 0; rangeSegment < 128; rangeSegment++) {
    fromMeters = rangeSegment * 0.15;
    toMeters = fromMeters + 0.15;
    
    fromLedNumber = round((fromMeters - distanceDelta) * ledsPerMeter) + 1;
    toLedNumber= round((toMeters - distanceDelta) * ledsPerMeter);
    Serial.printf("Segment %d, from >= %f to < %f meters. distanceDelta %f, LED from %d to %d\n", rangeSegment, fromMeters, toMeters, distanceDelta, fromLedNumber, toLedNumber);

    if (rangeSegment > 0 && oldToLedNumber + 1 != fromLedNumber) {
        Serial.printf("######### Missmatch: last 'toLedNumber' %d, new 'fromLedNumber' %d\n", oldToLedNumber, fromLedNumber);
      }
    oldToLedNumber = toLedNumber;
  }
}

void loop() { }

THANK YOU!

thanks for posting back a full sketch