Hi all.
I am using Arduino IDE and ESP32.
The code below is showing an incorrect result in the last Print statement. I suspect it is the conversion from float to int the problem.
Please can you see why is this happening?
Regards
float Vin = 1;
void setup()
{
Serial.begin(9600);
print_int();
}
void print_int()
{
Vin = Vin * 0.1; //Here Vin=0.1
int int_1 = Vin * 1000;
Vin = Vin * 0.1; //Here Vin=0.01
int int_2 = Vin * 1000;
Vin = Vin * 0.1; //Here Vin=0.001
int int_3 = Vin * 1000;
Serial.println("");
Serial.println(int_1); //This prints 100
Serial.println(int_2); //This prints 10
Serial.println(int_3); //This prints 0 - It should be 1
//Sanity check here
Serial.println(String(Vin,3)); //Last Vin is 0.001
}
Has the result of 0.99999994039535522460 which is then converted to a integer.
I call this cheating:
String(Vin,3)
Try that with 20 instead of 3.
If you are using a ESP32, please use 'double'.
If you convert a floating point number to a integer, use rounding.
Try to keep floating point numbers as floating point numbers. I prefer to use them for weight, length, speed, and so on. If you print a floating point number to the Serial Monitor, then use the second parameter to print more digits after the dot.
A 'float' uses 32-bits and a 'double' uses 64-bits, so it is more accurate.
However, you should write your sketch in such a way that you get the result that you expect.
A float can be 0.99 and a double can be 0.9999, but both turn to zero when cast to a integer.
Some prefer to do calculations with (long) integers as much as possible.
I prefer to use float or double throughout the whole sketch for real world units.
Every time that you convert something, you have to know what you are doing.
Did you know that the first line of your sketch has a conversion ?
float Vin = 1;
When the compiler sees a "1", then it reads it as a integer, after that it is converted to float for 'Vin'.
This has no conversion, everything is floating point:
double Vin = 1.0;
I do that also for myself, to remind myself that 'Vin' is a floating point variable.
Vin *= 123; // not good for me, I could forget that Vin is a floating point
Vin *= 123.0; // good, it shows clearly that it will be a floating point calculation.
I completely agree with @Koepel but let me say I don't get the point. Your code seems to be a sample one, ok, but I've never had the need to do such decimal divisions except, for example, if you need to get a portion of a float value (e.g. two digits from the integer part and two from the decimals) but many alternative ways exist...
Ok, but I still can't get why you need that kind of divisions. If you want and still have trouble with some calculations, conversions, or output, post here real code or snippets and we'll give it a try.
As side note, strangely the first code you posted here seems to run correctly on an UNO at least under TinkerCAD where I tested it, the last print correctly gives me 1 while ESP32 gives 0.
I haven't investigated that but maybe it's just a matter of specific architecture float precision.
PS: there's no need to convert everything into "String" class, the last print shows exactly the same value with Serial.println(Vin,3);.
Understood.
Hoover there is no code yet.
The code you have seen was to test how my ESP32 would handle those conversions.
I am new to the ESP32.
Regards.
Got it.
Anyway, you don't only need to better understand conversions (implicit or explicit casting), but I suggest you to study also how data are stored on the specific architecture (e.g. an ESP value is stored differently from a UNO, and ESP8266 is different from ESP32), variable types constraints (e.g. on UNO float and double are the same), and, in this case, floating point storage size, precision digits, and arithmetic).