Thread: unsigned char & signed char

  1. #1
    Registered User
    Join Date
    May 2004
    Posts
    70

    unsigned char & signed char

    i do not understand how unsigned chars work
    in the code
    Code:
    #include <stdio.h>
    
    
    int main(int argc,char **argv)
    {
    
    	char input_char;
    	char saved_char;
    	int i,rotate,temp;
    	int input_array[8];
    	int rotate_array[8];
    
    
    	printf("What is the input character?");
    	scanf("%c",&input_char);
    
    	saved_char=input_char;
    
    	for(i=0;i<8;i++)
    	{
    		if((input_char&1)==1)
    			input_array[i]=1;
    		else
    			input_array[i]=0;
    
    		input_char>>=1;
    	}
    
    	printf("\n\nArray is\n");
    	for(i=7;i>-1;i--)
    		printf("%d",input_array[i]);
    
    	printf("how many bits rotation");
    	scanf("%d",&rotate);
    
    	for(i=0;i<rotate;i++)
    	{
    		if((saved_char&1)==1)
    			temp=1;
    		else
    			temp=0;
    
    		saved_char>>=1;
    		
    		if(temp==1)
    			saved_char|=0x080;
    		else
    		{}
    
    		
    	}
    
    	for(i=0;i<8;i++)
    	{
    		if((saved_char&1)==1)
    			rotate_array[i]=1;
    		else
    			rotate_array[i]=0;
    
    		saved_char>>=1;
    	}
    	printf("\nAfter rotation\n\n");
    
    	for(i=7;i>-1;i--)
    	{
    		printf("%d",rotate_array[i]);
    	}
    	
    	
    
    
    	getch();
    
    
    	return 0;
    }
    
    
    
    #if 0
    
    #define FALSE 0
    #define NULL 0
    
    
    
    
    typedef struct {
    	int dataitem;
    	struct listelement *link;
    } listelement;
    
    void Menu (int *choice);
    listelement * AddItem (listelement * listpointer, int data);
    listelement * RemoveItem (listelement * listpointer);
    void PrintQueue (listelement * listpointer);
    void ClearQueue (listelement * listpointer);
    
    
    
    
    
    int main(void)
    {
    	listelement listmember, *listpointer;
    	int data,choice;
    	int i,number_of_data;	
    listelement *lp_temp;
    	listpointer=NULL;
    
    	printf("How many numbers are required?");
    	scanf("%d",&number_of_data);
    
    	data=0;
    
    	for(i=0;i<number_of_data;i++)
    	{
    		listpointer = AddItem(listpointer,data);
    	}
    
    
    
    
    
    	lp_temp=listpointer;
    
    	while(listpointer != NULL)
    	{
    		printf("What is the data item to be added ");
    		scanf("%d",&data);
    		listpointer->dataitem=data;
    		listpointer=listpointer->link;
    	}
    	listpointer=lp_temp;
    
    	PrintQueue(listpointer);
    
    getch();
    
    
    
    #if 0
    
    	do{
    		Menu (&choice);
    		switch(choice) 
    		{
    		case 1:
    			printf("What is the data item to be added ");
    			scanf("%d", &data);
    			listpointer = AddItem(listpointer,data);
    			break;
    
    		case 2:
    			if (listpointer == NULL)
    				printf("Queue is empty");
    			else
    				listpointer=RemoveItem (listpointer);
    			break;
    		case 3:
    			PrintQueue(listpointer);
    			break;
    
    		case 4:
    			break;
    
    		default:
    			break;
    		}//end switch(choice)
    	} while(choice !=4);
    
    	ClearQueue(listpointer);
    
    #endif
    	
    	return 0;
    }
    
    
    
    void Menu (int *choice) 
    {
    
    	char local;
    
    	printf ("\nEnter\t1 to add item,\n\t2 to remove item\n\t3 to print queue\n\t4 to quit\n");
    
    
    	do {
    
    		local =getchar ();
    
    		if ((isdigit (local) == FALSE)  && (local != '\n')) {
    			printf ( "\nYou must enter an integer(1-4)\n");
    		}
    
    	}while (isdigit ((unsigned char) local) == FALSE);
    	*choice = (int) local - '0';
    
    }
    
    listelement* AddItem (listelement * listpointer, int data)
    {
    	listelement *lp=listpointer;
    	if(listpointer != NULL) {
    		while(listpointer ->link!= NULL)
    				listpointer=listpointer->link;
    		listpointer ->link=(struct listelement *)malloc(sizeof (listelement));
    		listpointer=listpointer->link;
    		listpointer->link= NULL;
    		listpointer->dataitem=data;
    		return lp;
    	}
    	else
    	{
    		listpointer =(struct listelement *)malloc(sizeof (listelement));
    		listpointer->link=NULL;
    		listpointer->dataitem=data;
    		return listpointer;
    	}
    }
    		
    
    listelement* RemoveItem (listelement * listpointer)
    {
    	listelement *tempp;
    	printf("Element removed is %d\n", listpointer->dataitem);
    	tempp=listpointer->link;
    	free(listpointer);
    	return tempp;
    }
    
    void PrintQueue (listelement * listpointer)
    {
    	if(listpointer == NULL)
    		printf("queue is empty");
    	else
    		while( listpointer != NULL)
    		{
    			printf("%d\t",listpointer->dataitem);
    			listpointer=listpointer->link;
    		}
    		printf("\n");
    }
    
    void ClearQueue (listelement *listpointer)
    {
    	while(listpointer != NULL)
    		listpointer = RemoveItem (listpointer);
    }
    
    
    
    
    
    
    
    #endif
    saved_char behaves funny when declared as signed char
    in the line
    saved_char|=0x080;
    say if we have 'a' which is 97, the first right shift moves it to 48, but when i bitwise OR it with 1, i get -80 instead of -48 as i had assumed.

    with unsigned it works perfectly, it comes up with 176.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >saved_char behaves funny when declared as signed char in the line
    >saved_char|=0x080;
    char on your machine is probably 8 bits then. 0x080 is 128 yet the guaranteed range for signed char (when CHAR_BIT is 8) is -127 to 127. 128 will overflow a signed char, resulting in undefined behavior. The range of unsigned char is 0 to 255, so it can hold 0x080 without any problem. If you need both negative values and values outside the range of signed char then you should be using int instead.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    May 2004
    Posts
    22
    See Unsigned doubles the range here. It not only works for chars but also for ints,floats also.

    Any beginner book should help you clarify these.

    for eg say
    Code:
    int i;
    means the range allocated to integer variable i here is btw -32768 and 32767.

    now saying
    Code:
    unsigned int i;
    will double the range of integer i (which cant be a negative number now) to 32767+32768 = 65535 .

    so also you can declare unsigned doubles,floats etc.

    Hope this helps you.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by codomaniac
    See Unsigned doubles the range here. It not only works for chars but also for ints,floats also.

    Any beginner book should help you clarify these.
    No. It doesn't. You cannot have an unsigned float or unsigned double.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >means the range allocated to integer variable i here is btw -32768 and 32767.
    This is only true if sizeof(int) is two on a two's complement machine. The latter is likely, but the former isn't in this day and age where the natural size of int is typically 32 bits rather than 16. The C standard guarantees a minimum range of -32767 to 32767 for int, so you can get away with changing your lower bound to -32767 and adding the word minimum.
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    May 2004
    Posts
    22
    oh sorry for typos and thanks to you guys for pointing out my mistakes :O

    You people really rock!

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Shouldn't that be -128 and - 32768 ??
    Nope. That's only the case on a machine that uses a two's complement bit representation. Other representations such as one's complement and sign magnitude differentiate between +0 and -0 but can only go to -127 whereas two's complement only has one representation for 0 and can use up the extra spot by adding one more negative value, -128. Because of this, the C standard can only portably guarantee a union of all the available ranges, -127 to 127 for 8 bit signed quantities.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    May 2004
    Posts
    22
    Quote Originally Posted by Prelude
    This is only true if sizeof(int) is two on a two's complement machine.
    Example please for a two complement machine. In linux int is of 4 bytes size isnt it?

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Example please for a two complement machine.
    I don't know of any mainstream machines that aren't two's complement. Like I said before, it's usually safe to assume two's complement, but it still isn't blessed by the standard.

    >In linux int is of 4 bytes size isnt it?
    As far as I know.
    My best code is written with the delete key.

  10. #10
    Registered User
    Join Date
    May 2004
    Posts
    70
    i thought it was a bitwise operation, so the sign would be ignored.

    i thought since the char say holding the value a would be 97 in decimal and 01100001 and when you ORd with 0x80 10000000
    you would get

    11100001 in 2 complement that would be -98(?)

  11. #11
    /*enjoy*/
    Join Date
    Apr 2004
    Posts
    159
    attention ....

    Code:
    #include <stdio.h> 
    #include <conio.h>

  12. #12
    /*enjoy*/
    Join Date
    Apr 2004
    Posts
    159

    Talking atttention

    attention ..............

    Code:
    #include <stdio.h> 
    #include <conio.h>

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by enjoy
    attention ..............

    Code:
    #include <stdio.h> 
    #include <conio.h>
    [edit]Good catch. I didn't see getch in there, though I did rant about it. [/edit]

    [petpeeve]
    conio.h is basicly a DOS header file. It's one key function that people seem to use it for, is getch. Personally, since all it seems to be used for is a pause before the program ends, I don't see the need for it. Simply by changing getch to getchar, you can avoid the entire conio.h header.
    [/petpeeve]

    Quzah.
    Last edited by quzah; 05-28-2004 at 03:15 PM.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    First, learn how to think in binary.

    Then learn what two's complement is.

  15. #15
    Registered User
    Join Date
    May 2004
    Posts
    70
    is there any difference between getch and getchar

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. A Question About Unit Testing
    By Tonto in forum C++ Programming
    Replies: 2
    Last Post: 12-14-2006, 08:22 PM
  3. Replies: 7
    Last Post: 06-16-2006, 09:23 PM
  4. convert maybe maybe not..
    By pico in forum C Programming
    Replies: 7
    Last Post: 03-15-2005, 10:13 AM
  5. ANY BODY WILLING TO HELP ME WITH Microsoft Visual C++
    By BiG pImPiN fOoL in forum C++ Programming
    Replies: 12
    Last Post: 11-04-2001, 06:03 PM