3

I am trying to perform division using floats in C. To demonstrate what I mean, you can run the following code.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define TEST 20.0 / 65536.0

int main() {
    float a = 11.147;
    printf("%f\n", a);

    float b = 20.0 / 65536.0;
    printf("%f\n", b);

    float c = a/b;
    printf("%f\n", c);

    int d = (int) c;
    printf("%d\n", d);
    
    float e = a/(float) TEST;
    printf("%f\n",e);

    printf("%f\n", TEST);
    
    return 0;
}

The code above gave the following results

11.147000
0.000305
**36526.492188**
36526
**0.000009**
0.000305

The value I highlighted should be the same because it is the results of the same formula. The only difference is I use #define to define the divisor for the latter, which gave the incorrect value.

I am clueless as why this happens, can somebody please explain why I get this results? Thank you.

Andi Ilmy
  • 43
  • 3
  • 7
    [Is there a good reason for always enclosing a define in parentheses in C?](https://stackoverflow.com/questions/9081479/is-there-a-good-reason-for-always-enclosing-a-define-in-parentheses-in-c) – qrsngky May 30 '23 at 04:07
  • 1
    `20.0` etc are constants of type `double`. You should not mix float and double just for the heck of it. In fact it is very unlikely that should be using `float` in the first place if coding on a PC. The only application for `float` is pretty much 32 bit MCUs which have a 32 bit FPU but no hardware support for 64 bit floating point, in which case using `double` would be wrong. – Lundin May 30 '23 at 06:26
  • @Andi Ilmy, why does code have `float a = 11.147` and not `doublet a = 11.147`? – chux - Reinstate Monica May 30 '23 at 10:01

1 Answers1

14

By definition, define replace the raw code of wherever the references are. #defines are replaced before constant evaluation in compile time. So by writing

#define TEST 20.0 / 65536.0
float e = a/(float) TEST;

it is interpreted as:

float e = a/(float) 20.0 / 65536.0;

which mathematically equals a / 20 / 65536 and not a / (20 / 65536).

For your desired result, the #define should be written as: #define TEST (20.0 / 65536.0) (notice the parentheses).

JamieNguyen
  • 291
  • 3
  • 15