comparing char with int data type

Go To Last Post
26 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why does this code not work as expected?

uint8_t hardlimit = 25
uint16_t current_limit = 6000;

if(current_limit < (hardlimit * 100))
{
//Turn off buzzer
}
else
{
//Turn on buzzer

}

If I change the variable hardlimit to an int it works fine, or just hard code the limit.

example

if(current_limit < 2500)

I am not getting it. This has something to do with data types. Can someone explain this to me? How do I solve this issue. Changing the variable hardlimit to a int is not an option.

Thanks

Last Edited: Mon. Jan 10, 2011 - 12:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This smells like an assignment.

Consider the values possible for uint8_t. What's the smallest and largest possible value? What then is the value of multiplying 25 by 100?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The smallest value for hardlimit would be 1 and the largest value would be 255.

The value of hardlimit = 25;

25 * 100 = 2500

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

vimassive wrote:

The value of hardlimit = 25;

25 * 100 = 2500


Wrong. 25 * 100 = 196. Guess why :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The short answer is "it depends". It depends on your toolchain, perhaps, and also on your build options. So expound on those.

Given a "normal" setup, I'm surprised the normal promotion rules did not apply. But then I do all my dev with "promote char to int" turned off.

Quote:

Changing the variable hardlimit to a int is not an option.


It always intrigues us when superlative statements like this are made. What will happen if it is changed? Will the toolchain cease working? Will there be no more chocolate?

You could always cast hardlimit. But that may violate the ritual rules, and you will be cast out into the wilderness.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if you're only allowed to use 1 int for current limit and 1 char for hardlimit, then why not do this?

if ((current_limit / 100) < hardlimit) 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
if(current_limit < ((uint16_t)hardlimit * 100)) 

A cast should force the compilers hand.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ MBedder why 25 * 100 = 196

@ Kartman I tried but still no cigar
if(current_limit < ((uint16_t)hardlimit * 100))

@ nedward I tried but this did not work also
if ((current_limit / 100) < hardlimit)

Will anyone at least explain of point me in the right page on assignment rules I am using the winavr compiler.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

vimassive wrote:
@ MBedder why 25 * 100 = 196

I do know why. Now is your turn :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

why 25 * 100 = 196

You need to have this spelled out. Remember that it all started with "consider the values possible for uint8_t", OK? How many bits is that? Yes, eight. Now, multiply 25 with 100 to get 2500. What is that in binary? Yes, 100111000100. Now take the eight low bits of that (eight bits as in an uint8_t) and convert that to decimal. What do you get?

196.

Quote:

Changing the variable hardlimit to a int is not an option.

Why?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Quote:

Changing the variable hardlimit to a int is not an option.

Why?

Yes, especially given the fact that the only way this calculation can work is if the variable is changed to an int at some point (directly or through a cast). OP, you WILL end up with a 16-bit variable one way or the other, you can't avoid it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Reading the C book is not an option either :D:D:D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, that is what I needed to hear.

hardlimit * 100

25 * 100 = 196

So it seems that we are actually storing the results back into hardlimit which is a char type. Good....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So it seems that we are actually storing the results back into hardlimit

No-one said that.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, since the variable type is char the results would be stored in a char.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The compiler works the way the c standard says. Its under the subject of 'expression evaluation' and 'type promotion'. All arithmetic expressions are evaluated as unsigned integers unless one of the terms is signed. Then everything is cast/promoted to signed and the expression is solved. If one of the terms is long, everything is converted to long and the expression solved. If one of the terms is float, everything is converted to float and the expression is solved. It is then cast to the type of the var on the left side.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Wrong. 25 * 100 = 196. Guess why
Perhaps you are the one that needs to read a good book on C.

25 * 100 = 2500, guess why

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmmmm.... Re-reading this thread I see that I have misread it and typed too fast for my brain. Of-course the C type-promotion should act as usual. So, my previous post is in error (though it might be an interpretation of what MBedder was hinting at).

Sorry for any confusion.

It would be good if you produced a minimal version of code that builds clean and produces the "phenomenon" (the code in your original post is neither complete, nor free from syntax errors).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What promotion are you talking about? Look again at the OP's code:

uint8_t hardlimit = 25
(hardlimit * 100) = ? (put your answer here)

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

What promotion are you talking about? Look again at the OP's code

I did look again. That's when I discovered it won't even build clean. Thus we are in the usual spot, seeking faults in unknown code. A rather meaningless exercise IMO. And what doe the OP mean by

Quote:
Why does this code not work as expected?

Is he actually referring to a build error because of a missing semicolon?

-----

Assuming the missing semicolon is the only thing that differs from the code that OP actually builds, then re the promotion: If I understand the type promotions rules in C correctly then it goes
- The type of hardlimit is uint8_t (in essence an unsigned char)
- The type of the literal value 100 is int
so...
- when the expression is evaluated, the value of hardlimit is promoted to an int.

I did a quick test also, albeit in Visual Studio as I'm not at an avr-gcc-enabled computer right now. In that environment, int's are 32 bits unless you tweak the tool-chain (not sure that you an at all...). Anyway:

    unsigned char hardlimit = 25;

    int soil = sizeof(100);               // Yields 4 - the size of an int
    int sohl = sizeof(hardlimit);         // Yields 1 - the size of an uint8_t
    int soex = sizeof(hardlimit * 100);   // Yields 4 - the size of an int

Apart from int's being 16 bits rather than 32, I'd expect that avr-gcc would behave likewise. So the promotion is to int, since one of the operands of the expression is of type int.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And, from the C99 standard, first on multiplicative operators:

Quote:
The usual arithmetic conversions are performed on the operands. [section 6.5.5]

"The usual arithmetic conversions" is explained earlier:

Quote:
Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions:
[... long part about float values excluded ...]

[...]the integer promotions are performed on both operands. Then the
following rules are applied to the promoted operands:

If both operands have the same type, then no further conversion is needed.

Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank is
converted to the type of the operand with greater rank.
[...]
[section 6.3.1.8]

So, if I'm not misreading this, the uint8_t operand will be promoted to an uint16_t before the expression is evaluated. Likewise, the result will be an uint16_t, which has ample size for holding the value 2500.

Where am I going wrong MBedder?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Look again at the OP's code:
Maybe you should look again. The OP's original code being referred to was:

 if(current_limit < (hardlimit * 100)) 

What you posted is not even code.

Quote:
Where am I going wrong MBedder?
Your not.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Happens :)

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No build errors or warnings. I am trying to figure out why the logic does not work as expected. I am using AVR Studio 4.18 build 684 with WINAVR-20100110.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I feel so ashamed of myself. I started debugging the raw data via a serial monitor software and I figured out that I was one byte off in my mapping (reverse engineering)which explained why things did not work as expected. Thanks everyone for your help it was much appreciated. I have been fighting this one for a week now. I feel so bad. :-(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I feel so ashamed of myself.

Don't. We all do those things. Every mistake is a learning opportunity.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]