1

I am trying to get 20 in the variable nm. But it is returning 19.

How do I fix it? And what is causing this problem?

#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{

    float m;

    int n = 0;
    do {
         m = get_float("Enter:");

        }while(m < 0);
    int nm =(m * 100 );
    while(nm >= 25 ){
        nm = nm - 25;
        n = n + 1;

    }

    printf("%i\n",n);
    printf("%i\n", nm);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    And that, kids, is why we don't *ever* rely on transitive equality when pushing a float through an `int`. – WhozCraig Nov 19 '18 at 19:19
  • 1
    It's very tempting just to close this as a duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Jonathan Leffler Nov 19 '18 at 19:57
  • Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Sean Pianka Nov 19 '18 at 20:50

1 Answers1

1

A 32-bit float can encode about 232 different values exactly. Due to the binary nature of the typical float, 4.2 is not one of them.

Instead m has the value of 4.1999998...

// closest float
4.19999980926513671875
// hoped for value
4.2
// next closest float
4.200000286102294921875

Multiplexing by 100 incurs some rounding and the best answer to m*100 is then 419.999969482421875.

int nm =(m * 100 ); results nm == 419 as assignment of a float to int truncates the fractional portion away.


Consider rounding to the nearest integer rather than truncating via int assignment and use double constants.

#include <math.h>

// int nm =(m * 100 );
int nm = lround(m * 100.0);
// or 
int nm = round(m * 100.0);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256