0

I am trying to use 256 as a constant in C with #define. That equals 255 + 1 (which is 0xff + 1). And since in limits.h, UCHAR_MAX is 255, 256 should be equivalent to UCHAR_MAX + 1. So I write:

#include <limits.h>
#define BASE_NUM ((int)UCHAR_MAX)+1

So, when I do printf("%f",1000.0/(float)BASE_NUM);, it prints 4.921569, which is wrong (it would only be correct if BASE_NUM was 203.187).

However, by writing printf("%f",1000.0/((float)UCHAR_MAX+1));, I get 3.906250 as the output, and it is indeed correct. Therefore, BASE_NUM must not be equal to 256, but astonishingly, printf("%d",BASE_NUM); prints 256, which is clearly a contradiction, as BASE_NUM must not actually be 256.

I guess it has something to do with an overflow when I do the sum at the definition of the constant, but I really can't see what the problem exactly is, given that I am casting UCHAR_MAX to an int before adding anything to it, so there should be no overflow.

Aldan Creo
  • 686
  • 1
  • 5
  • 14

2 Answers2

1

Wrap your #define in another set of parenthesis:

#define BASE_NUM (((int)UCHAR_MAX)+1)

Explanation:

Whenever you're having trouble with macros, just copy-paste their definition tho wherever you're using them and then evaluate from there:

printf("%f", 1000.0 / (float) ((int)UCHAR_MAX) + 1);

  • First, UCHAR_MAX is cast to an int and becomes 255. (here the cast is unnecessary as the constant 255 is already treated as an int by the compiler).
  • Then it is cast to a float and becomes 255.0.
  • Then, because division takes precedence over addition in C, 1000.0 is divided by 255.0
  • And finally 1 is converted to a float, becomes 1.0, and gets added to the result of the division (1000.0 / 255.0 + 1.0) == 4.92.
bool3max
  • 2,748
  • 5
  • 28
  • 57
  • On a side note flagging your question as a duplicate was a stupid decision by whoever did it. – bool3max Nov 30 '19 at 23:12
  • Indeed, your explanation solved the problem, thanks a lot! I personally don't think this is a duplicate, either, as I tried searching before and didn't find anything like my question, but I guess there may be another related question. – Aldan Creo Nov 30 '19 at 23:38
  • Please accept the answer if it did indeed help you! Also, yeah, your question being a duplicate doesn't make sense. You had a problem and you weren't aware of the cause, whereas the author of the linked question was asking exactly about the need for parenthesis inside of macros. – bool3max Nov 30 '19 at 23:42
  • 2
    Anyone is free to nominate the question for reopening if they feel the closure was inappropriate. In general (at least as far as I'm concerned) (a) a "duplicate" question needn't match exactly as long as the answer is the one the questioner needs, and (b) marking a question as a duplicate is in no way a criticism of the questioner for not having found that prior question; it merely says "here's your answer", and keeps people from wasting time re-answering. – Steve Summit Dec 01 '19 at 01:00
  • Also there are often questions that often have trivial superficial - and wrong answers and often a better way in the canonical duplicate. – Antti Haapala -- Слава Україні Dec 01 '19 at 03:44
  • everything relates to your issue is answer in the other question, so definitely it's a duplicate. You couldn't find it because you used the wrong keyword. But next time read [read through the whole macro section in your C book before asking](https://stackoverflow.com/q/562303/995714) – phuclv Dec 01 '19 at 04:44
0

Preprocessor left your printf like this:

printf("%f\n", 1000.0/(float) ((int)(0x7f * 2 + 1))+1);

which is interpreted as: (1000.0/UCHAR_MAX) + 1

JL. Sanchez
  • 371
  • 1
  • 7