user62151: I wrote a little program to show my problem:
void setup() 
{
  Serial.begin(9600);

  double K=39.85;
  double a=K*100;
  Serial.print("a= ");
  Serial.println(a);

  long val_long = 0;
  val_long = a;
  Serial.print("val_long= ");
  Serial.println(val_long);
}

void loop() {
}

I get this back from my Arduino uno:
a= 3985.00
val_long=3984

I've been pondering for a long time and can't find the mistake! Why is the long value decremented by one? Can anybody help me please?

user31105: The problem is that float numbers are seldom an exact representation. So the float is stored as the closest number that is exactly representable as a float, namely
10446438 × 2−18 = 39.84999847412109375.
When you multiply this by 100, you get 16322559 × 2−12 = 3984.999755859375.
And than casting to an int or long results in 3984, not 3985.
so whenever you cast a value from a float or double to an int or long, you always should add 0.5 (so all values from [x - 0.5, x + 0.5) are rounded to x assuming x >= 0, thus:
val_long = int(a + 0.5);

Beware of negative values, see therefore https://www.cs.cmu.edu/~rbd/papers/cmj-float-to-int.html
Better is to use the round function, see comment of Edgar Bonet below.
UPDATE
See comment of Lightness Races with Monica
In case it's not wanted to round up, but you still want 39.84999847412109375 to be 39.85, than you have to add a value that has the value of the least significant bit (actually slightly less but that is impossible to define). In most cases, it's best to add half the significance you want. So if you need two decimal accuracy, add 0.005.

62151: <p>I wrote a little program to show my problem:</p>

<pre><code>void setup() 
{
  Serial.begin(9600);

  double K=39.85;
  double a=K*100;
  Serial.print("a= ");
  Serial.println(a);

  long val_long = 0;
  val_long = a;
  Serial.print("val_long= ");
  Serial.println(val_long);
}

void loop() {
}
</code></pre>

<p>I get this back from my Arduino uno:</p>

<pre><code>a= 3985.00
val_long=3984
</code></pre>

<p>I've been pondering for a long time and can't find the mistake! Why is the long value decremented by one? Can anybody help me please?</p>
 31105: <p>The problem is that float numbers are seldom an exact representation. So the float is stored as the closest number that is exactly representable as a float, namely<br>
10446438 × 2<sup>−18</sup> = 39.84999847412109375.</p>

<p>When you multiply this by 100, you get 16322559 × 2<sup>−12</sup> = 3984.999755859375.</p>

<p>And than casting to an int or long results in 3984, not 3985.</p>

<p>so whenever you cast a value from a float or double to an int or long, you always should add 0.5 (so all values from [x - 0.5, x + 0.5) are rounded to x assuming x >= 0, thus:</p>

<pre><code>val_long = int(a + 0.5);
</code></pre>

<p>Beware of negative values, see therefore <a href="https://www.cs.cmu.edu/~rbd/papers/cmj-float-to-int.html" rel="nofollow noreferrer">https://www.cs.cmu.edu/~rbd/papers/cmj-float-to-int.html</a></p>

<p>Better is to use the <code>round</code> function, see comment of Edgar Bonet below.</p>

<p><strong>UPDATE</strong></p>

<p>See comment of Lightness Races with Monica</p>

<p>In case it's not wanted to round up, but you still want 39.84999847412109375 to be 39.85, than you have to add a value that has the value of the least significant bit (actually slightly less but that is impossible to define). In most cases, it's best to add half the significance you want. So if you need two decimal accuracy, add 0.005.</p>
