|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Integer Representation - Huh?!
Not sure if I missed something in my CIS classes, but can someone offer some insight into this behavior?
Code:
int foo;
foo = 127 + 127;
printf ("%16b | %d \r\n", foo, foo);
// prints: "1111 1111 1111 1110 | -2"
It would seem that it might be treating the literal values as an 8 bit integer and then padding with the most significant digit to get to 16 bits. "it" may be printf, or the compiler/CPU... ? This code is my work around: Code:
unsigned char foo;
foo = 127 + 127;
printf ("%16b | %d \r\n", (int)foo, (int)foo);
// prints: "0000 0000 1111 1110 | 254"
// This also works, keeping all my data types at (int)
// This also implies it's a bug in how the chip/compiler represents literal values
int foo;
foo = (int)(unsigned char)(127 + 127);
printf("%16b | %d \r\n", foo, foo);
Any insights? I'd like to just use one data type (int) everywhere, but this is hanging me up, since it becomes difficult to debug the output. Last edited by Joe Johnson : 21-02-2004 at 21:57. Reason: Typo in the Title |
|
#2
|
|||||
|
|||||
|
Re: Interger Representation - Huh?!
Quote:
2.7 ISO DIVERGENCES 2.7.1 Integer Promotions ISO mandates that all arithmetic be performed at int precision or greater. By default, MPLAB C18 will perform arithmetic at the size of the largest operand, even if both operands are smaller than an int. The ISO mandated behavior can be instated via the -Oi command-line option. For example: Code:
unsigned char a, b; unsigned i; a = b = 0x80; i = a + b; /* ISO requires that i == 0x100, but in C18 i == 0 */ For example: Code:
#define A 0x10 /* A will be considered a char unless -Oi specified */ #define B 0x10 /* B will be considered a char unless -Oi specified */ #define C (A) * (B) unsigned i; i = C; /* ISO requires that i == 0x100, but in C18 i == 0 */ ===== It is confusing. I think you could cast the literal as an (int): Code:
foo = (int)127 + (int)127; Code:
foo = 127L + 127L; Last edited by Joe Johnson : 21-02-2004 at 21:58. |
|
#3
|
||||
|
||||
|
Re: Interger Representation - Huh?!
just make sure you cast all of the variables you pass to printf as (int).
Last edited by Joe Johnson : 21-02-2004 at 21:59. |
|
#4
|
||||
|
||||
|
Re: Interger Representation - WTF?
gnormhurst,
Thank you for that incredibly detailed, quick, and accurate post. I'll make sure to read the C18 tech docs as soon as I can find the time. So far I've been very happy with how compliant the compiler is. I think you hit the nail on the head. I hacked a macro to manipulate the datatypes I wanted to work with, but I *hate* macros. I think I might just use the command line option you mentioned, after I research it's overall implications. deltacoder1020, If you look over my examples, the type of data I was passing to printf was already int. re-casting it inside the printf statement won't change anything. |
|
#5
|
||||
|
||||
|
Re: Interger Representation - Huh?!
sry about that, perhaps I was unclear - essentially, MCC18 casts any constant from 0-255 as a unsigned char, so you may want to cast the constants as well.
Last edited by Joe Johnson : 21-02-2004 at 22:00. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|