1

i want to ask, how to get correct float value from uint32_t or long variable is devided by 10??

long var3 = 1139399025;
int a = 3;
int b = 10;
void setup() {
  Serial.begin(9600);
  Serial.println((float)a/b,2);
  Serial.println((float)var3/b,2);
}
void loop() {
}

result

0.3
113939904.00

it give 113939904.00 instead of 113939902.50, plase how to fix that?

4
  • what is the value of var3 when it is converted to float?
    – jsotola
    Commented Nov 30, 2022 at 1:07
  • long var3 = 1139399025;
    – mukhlas
    Commented Nov 30, 2022 at 1:11
  • Floats have only limited precision see: cdn.arduino.cc/reference/en/language/variables/data-types/float . You get better precision using a double but only on a 32 bit Arduino (Due etc.). However there will still be some loss of precision.
    – 6v6gt
    Commented Nov 30, 2022 at 2:33
  • I use arduino mega 2560
    – mukhlas
    Commented Nov 30, 2022 at 2:42

1 Answer 1

2

1139399025 is not a floating point number: the largest odd integer that can be exactly represented as a float is 224 − 1 = 16777215. Then, when var3 is cast to float, it gets rounded to the closest float, which is 1139399040. This is quite a small error, especially considering that, in this range, only multiples of 128 can be exactly represented as floats.

Dividing 1139399040 by 10 gives 113939904, which happens to be a float. The floating point division gives then the exact result, which is what gets printed. Indeed, floating point operations do not always give inexact results: sometimes they are exact. However, unless you know what you are doing, exact results only happen by luck. In general, expect each floating point operation to make a relative rounding error in the range of 10−7.

A highly recommended read: What Every Programmer Should Know About Floating-Point Arithmetic.

Edit: If you want to print the value of an integer divided by 10, you can divide the number using Euclidean division. Print the quotient, then the decimal point, then the remainder:

Serial.print(var3 / 10);  // quotient
Serial.print('.');
Serial.println(var3 % 10);  // remainder

As these are all integer operations, there is no rounding error involved. Obviously this trick doesn't work for arbitrary divisors.

6
  • So what should i do?
    – mukhlas
    Commented Nov 30, 2022 at 10:14
  • @mukhlas: Do not use floats. Commented Nov 30, 2022 at 10:17
  • @mukhlas Or use double that provide more significant digits, for this specific case. But in any case you need to understand floating-point, as Edgar suggested. Commented Nov 30, 2022 at 11:13
  • @thebusybee: The AVR microcontrollers (or rather, their port of GCC) do not support double precision floats: their double type is implemented as float32, just like float. Commented Nov 30, 2022 at 12:01
  • Oh, really? Well, then, no luck. :-( Commented Nov 30, 2022 at 13:13

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