using sprintf()? isn't that the issue?
with x10, truncating and / 10 as suggested
void setup() {
Serial.begin(115200);
char str_tmp[10];
sprintf(str_tmp, "%2.1f", trunc(6.38 * 10) / 10.0); // ESP or ARM only, float not supported on Uno and similar
Serial.println(str_tmp);
}
void loop() {}
dtostrf() - turn your floats into strings - Programming Electronics Academy
dtostrf (float_value, min_width, num_digits_after_decimal, where_to_store_string)
doesn't round
The sketch of post #26 is uploaded in NodeMCU/ESP8266; there is 6.3 output on the Serial Monitor.
Output:
6.3
6.3
6.3
Anyway, I had to shift the codes in the loop() function to see the output.
void setup()
{
Serial.begin(115200);
}
void loop()
{
char str_tmp[10];
sprintf(str_tmp, "%2.1f", trunc(6.38 * 10) / 10.0); // ESP or ARM only, float not supported on Uno and similar
Serial.println(str_tmp);
delay(1000);
}
@J-M-L
Is there any advantage of using trunc() function instead of (int) casting?
no
Arduino sprintf doesn't support "%f"?
isn't that the issue?
This is it.
divide by 10.0?
I suppose it should be enough to make multiplication an int
(int)(6.38 * 10) * 0.1f
From an efficiency perspective I don’t know, the compiler is smart - it’s about Using math instead of ugly type manipulation and promotion
0.1 - double
0.1f - float
float is cheaper than double
multiplication * is cheaper than division /
Ok! It is understood that float is cheaper than double as float-type variable uses 32-bit space; whereas, double uses 64-bit space.
How is * (multiplication) cheaper than / (division)?
Takes fewer cycles, having said that, compiler would probably convert division by 10 to multiplication internally anyway so it won't make a difference to the final code
Not true!
void setup()
{
Serial.begin(115200);
}
void loop()
{
char str_tmp[10];
dtostrf(6.38, 3, 1, str_tmp); //arg1=value, arg2=#symbols. arg3=#digits after point
Serial.println(str_tmp);
delay(1000);
}
Output:
6.4
6.4
6.4
The ATmega32A/328P takes 2 clock cycles for multiplication; whereas, the said MCU has no div instruction in its list.
Remarkable, the makers of ATmega32A/328P must have found a way how to bend Math
That you have already said in your post #37.
"[...]compiler would probably convert division by 10 to multiplication internally [...]."
The procedure is a decimal shift-left (*10), truncate (remove "100's" decimal place), decimal shift-right (/10). It avoids the rounding up or rounding down.
If you use trunc() function, then it does not matter using /10 or /10.0. If using (int) casting, then /10.0 is a must to get correct result; else, you get 0.0.