Home > Blockchain >  Problem with float and int multiplication in C
Problem with float and int multiplication in C

Time:12-12

I'm using the online compiler https://www.onlinegdb.com/ and in the following code when I multiply 2.1 with 100 the output becomes 209 instead of 210.

#include<stdio.h>
#include <stdint.h>

int main() 
{
    float x = 1.8;

    x = x   0.3;

    int coefficient = 100;

    printf("x: /\n", x);

    uint16_t y = (uint16_t)(x * coefficient);

    printf("y: %d\n", y);

    return 0;
}

Where am I doing wrong? And what should I do to obtain 210?

I tried to all different type casts still doesn't work.

CodePudding user response:

Floating point numbers are not exact, when you add 1.8 0.3, the FPU might generate a slightly different result from the expected 2.1 (by margin smaller then float Epsilon) read more about floating-point numbers representation in wiki https://en.wikipedia.org/wiki/Machine_epsilon

what happens to you is:

1.8 0.3 = 209.09999999... then you truncate it to int resulting in 209

you might find this question also relevant to you Why float.Epsilon and not zero? might be

CodePudding user response:

The following assumes the compiler uses IEEE-754 binary32 and binary64 for float and double, which is overwhelmingly common.

float x = 1.8;

Since 1.8 is a double constant, the compiler converts 1.8 to the nearest double value, 1.8000000000000000444089209850062616169452667236328125. Then, to assign it to the float x, it converts that to the nearest float value, 1.7999999523162841796875.

x = x 0.3;

The compiler converts 0.3 to the nearest double value, 0.299999999999999988897769753748434595763683319091796875. Then it adds x and that value using double arithmetic, which produces 2.09999995231628400205181605997495353221893310546875.

Then, to assign that to x, it converts it to the nearest float value, 2.099999904632568359375.

uint16_t y = (uint16_t)(x * coefficient);

Since x is float and coefficient is int, the compiler converts the coefficient to float and performs the multiplication using float arithmetic. This produces 209.9999847412109375.

Then the conversion to uint16_t truncates the number, producing 209.

One way to get 210 instead is to use uint16_t y = lroundf(x * coefficient);. (lroundf is declared in <math.h>.) However, to determine what the right way is, you should explain what these numbers are and why you are doing this arithmetic with them.

CodePudding user response:

// Online C compiler to run C program online
#include<stdio.h>
#include <stdint.h>

int main() 
{
    float x = 1.8;

    x = x   0.3;

    uint16_t coefficient = 100;

    printf("x: /\n", x);

    uint16_t y = round(x * coefficient);

    printf("y: %u\n", y);

    return 0;
}
  • Related