CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

issue with unsigned 16 bits integer

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
red_one



Joined: 30 Nov 2007
Posts: 10

View user's profile Send private message

issue with unsigned 16 bits integer
PostPosted: Mon Dec 17, 2007 7:55 pm     Reply with quote

type def.
Code:
typedef unsigned int uint16_t;


declaration
Code:
uint16_t x;


initialization
Code:
x = 0xFFFF;


test
Code:
if (x == 0x00FF)
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");



it prints oops and OK all time.
what's wrong ??

I'm using CCS proto board with PIC16F877A mcu and PICC version 4.064


Last edited by red_one on Mon Dec 17, 2007 8:19 pm; edited 1 time in total
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: issue with unsigned 16 bits integer
PostPosted: Mon Dec 17, 2007 8:11 pm     Reply with quote

red_one wrote:

Code:
if (x == 0x00FF);
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");


it prints oops and OK all time.
what's wrong ??


Hint: Look closely at the semicolon after your first "if" statement....

Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Guest








Re: issue with unsigned 16 bits integer
PostPosted: Mon Dec 17, 2007 8:18 pm     Reply with quote

RLScott wrote:
red_one wrote:

Code:
if (x == 0x00FF);
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");


it prints oops and OK all time.
what's wrong ??


Hint: Look closely at the semicolon after your first "if" statement....

Robert Scott
Real-Time Specialties
Embedded Systems Consulting

it's just a past mistyping !
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: issue with unsigned 16 bits integer
PostPosted: Mon Dec 17, 2007 9:33 pm     Reply with quote

red_one wrote:
type def.
Code:
typedef unsigned int uint16_t;



What is an int?
It's a value with no fractional component.
In the context of programming in C it is the internal bus with of the target processor. A PIC microchip has an 8-bit internal bus. So you are declaring a byte variable with the name uint16_t . You actually don't need to do a typedef. int16 is a unsigned 16bit variable.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: issue with unsigned 16 bits integer
PostPosted: Tue Dec 18, 2007 6:47 am     Reply with quote

Anonymous wrote:

Quote:

Code:
if (x == 0x00FF);
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");


it prints oops and OK all time.
what's wrong ??

Hint: Look closely at the semicolon after your first "if" statement....


it's just a past mistyping !


Are you sure it is not in the actual code that is causing the problem? Because it does explain the reported behavior completely.

Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Guest








Re: issue with unsigned 16 bits integer
PostPosted: Tue Dec 18, 2007 9:39 am     Reply with quote

RLScott wrote:
Anonymous wrote:

Quote:

Code:
if (x == 0x00FF);
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");


it prints oops and OK all time.
what's wrong ??

Hint: Look closely at the semicolon after your first "if" statement....


it's just a past mistyping !


Are you sure it is not in the actual code that is causing the problem? Because it does explain the reported behavior completely.

Robert Scott
Real-Time Specialties
Embedded Systems Consulting


I'm sure.

Another issue.

Code:
uint16_t x;
x=0xFFFF;
printf("x=%ld\r\n", x);


it prints x=-1
and doesn't compile when I replace %ld with %d.

%ld is for long integer (4 bytes), isn't it ?

I thought unsigned int16 variables are unsigned 2 bytes integer.
I don't understand what's wrong.

How to have UNSIGNED 16 bits integer ?
Ttelmah
Guest







PostPosted: Tue Dec 18, 2007 9:55 am     Reply with quote

rtfm.....
%ld, is the declarator to print the number as a _signed_ long.
%lu, is the declarator to print an unsigned long.

Best Wishes
Guest








PostPosted: Tue Dec 18, 2007 10:58 am     Reply with quote

Ttelmah wrote:
rtfm.....
%ld, is the declarator to print the number as a _signed_ long.
%lu, is the declarator to print an unsigned long.

Best Wishes


As far as I know unsigned int16 isn't long integer.
why it compiles with %ld ??
frequentguest
Guest







PostPosted: Tue Dec 18, 2007 11:09 am     Reply with quote

A long is an in16 is and unsigned 16-bit integer.

Check out the help file/manual on the basic types in CCS.
frequentguest
Guest







PostPosted: Tue Dec 18, 2007 11:12 am     Reply with quote

Quote:
A long is an in16 is and unsigned 16-bit integer.

Check out the help file/manual on the basic types in CCS.


Wow, I guess I need to start checking a little better before I post. That should read:

A long is an int16 which is an unsigned 16-bit integer...
Ttelmah
Guest







PostPosted: Tue Dec 18, 2007 11:39 am     Reply with quote

The concepts of 'length', and 'sign', are separate. You can have a signed long, or a unsigned long (the default in CCS, is for types to be _unsigned_, unless otherwise specified). Similarly, you can have a normal 8bit value, that is either signed or unsigned. The 'l' specifier, added to the printf, tells the compiler that the value will be a 'long'. The 'u' specifier, says it is dealing with an unsigned type.
The printout definitons, are _distinct_ from the data definitions, and this is a 'weakly typed' language, so errors in typing are _not_ complained about. So:
Code:

int16 uval; //declare an unsigned int16
signed int16 val; //declare a signed int16
float fp_val;

val=-1;
printf("value treated as signed %ld\n\rtreated as unsigned %lu",val,val);
//You will see -1, and 65535 displayed.
uval=val;

fpval=val;
printf("\n\rresult from converting to a float from the signed %f\n\r",fpval);
//You will get -1

fpval=uval;
printf("result from converting the same value stored in an int16 %f",fpval);
//you will get 65535.....


Here you will see the hex value 0xFFFF, treated both as -1, and as 65535, in the first case, switched by the output declaration in printf, and latter, handled 'automatically', because of the data type.

Best Wishes
red_one



Joined: 30 Nov 2007
Posts: 10

View user's profile Send private message

PostPosted: Wed Dec 19, 2007 5:11 am     Reply with quote

Code:
typedef unsigned int16 uint16_t;
uint16_t x = 0xFFFF;



well.
I still have 255 instead of 65535 when wathching in the debugger
Ttelmah
Guest







PostPosted: Wed Dec 19, 2007 9:28 am     Reply with quote

And did you change the debugger settings for the variable, to tell it that this was a 1bit value now, not an 8bit one.
Most default to assuming a value is 8bit, not 16bit.

Best Wishes
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: issue with unsigned 16 bits integer
PostPosted: Wed Dec 19, 2007 8:29 pm     Reply with quote

Anonymous wrote:

Code:
if (x == 0x00FF);
  printf("oops\r\n");
if (x == 0xFFFF)
  printf("OK\r\n");


it prints oops and OK all time.
what's wrong ??

it's just a past mistyping ! [meaning the ";" after the "if"]
I'm sure.


I think you have discovered a compiler bug. Here is the situation.

Your typedef defines a new type, inappropriately named uint16_t, which is actually just an int. On the 16Fxxx family of PICs, an int is 8 bits. So x is only an unsigned 8-bit quantity (0 to 255). The assignment of x = 0xFFFF just assigns the low-order 8 bits to x, or 255. The first comparison, (x == 0x00FF) compares two values that are both expressible in 8 bits, so the comparison yields "TRUE". The second comparison is with an 8-bit x and a 16-bit 0xFFFF. By the rules of C, this should result in promoting the 8-bit quantity to 16-bits and then making the comparison with 16 bits. But I have examined the disassembly listing after compiling this code, and I see that the compiler actually demotes the 0xFFFF down to 8 bits by discarding the high-order byte, and then the comparison takes place with 8 bits, with of course again yields "TRUE". So you were right all along. In fact, you would have gotten a TRUE comparison even if you wrote (x == 0x34FF).

Interestingly, the compiler bug is confined to the case where the 16-bit number is a constant. If the 16-bit number is a variable, then the compiler does the right thing and promotes x to 16 bits before making the comparison.

Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Ttelmah
Guest







PostPosted: Thu Dec 20, 2007 5:06 am     Reply with quote

Yes.
If you look at the top line of the manual entry for 'how are type conversions handled', it says that:
"For example: int8var = int16var; Causes the top byte of int16var to be lost.".
The arithmetical precedence for '==', is actually less that for '=', so it makes a sort of sense....
In fact you have to distinguish here, the behaviour of the 'preprocessor', which is attampting to simplify operations before the main compiler phase, and it simply decides that there is no mathematical operation on the line using int16, so casts everything to int8, before starting.
It really would justify a warning (the compiler does actually generate one, if you use the '>' test, rather than the '==' test, warning that the condition can never be true).
Most compilers, don't actually return 'true' for the first, and 'false' for the second. You have to remember when testing this, that on 90%+ of compilers, the 'default' arithmetic type, is an int16, not int8. If you perform the equivalent test (using a int32 constant, and comparing with an int16 variable), the commonest behaviour is to warn (4), and the rest actually behave as the CCS compiler does (2), but only when dealing with these larger data types... I tried six different 'C' compilers just for interest'.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group