What does 0xFE mean in a C program? - c

In the given program below,
void main()
{
int x=0xFE;
int y=0xF3;
.....
}
What values are assigned by x=0xFE and y=0xF3? What does 0x represent?

Writing a value with 0x before means it is written in hexadecimal notation, where the numbers 0-9 and additional "number" A-F are used to get a number system with the base 16. The big advantage of this is that each hexadecimal digit represents exactly 4 bits.
0xFE = 254
0xF3 = 243
So x = 254 and y = 243.

Numbers can be represented in different ways. In C, you can use decimal (e.g. 243), octal (e.g. 0363) or hexadecimal (0xF3).
If you write 243, you mean
243 = 2*10^2 + 4*10^1 + 3*10^0 = 2*100 + 4*10 + 3 = 243
where ^ means "to the power of". That means our normal numbers are base 10, or decimal. Hexadecimal uses base 16, and the digits are 0123456789ABCDEF, where 0=0, ... 9=9, A=10, B=11, ... F=15. So 243 can also be written as
0xF3 = 15*16^1 + 3*16^0 = 15*16 + 3 = 243
That is what you see. In other words, 0xF3 is just another way to write 243, and 0xFE is another way to write 254 (15*16 + 14 = 254).
The advantage is that each hexadecimal digit represents 4 bits, so 2 hexadecimal digits can be used to display a byte. If you know that 0x0 is 0000 in binary, and so on, up to 0xF, which is 1111 in binary, an experienced user can easily "see" the bits in a byte.
FWIW, octal is in base 8, so the only digits are 01234567. I have always found it a bit awkward to use.

The values are in hexadecimal since they are preceded by the 0x identifier.
To convert the values, you can use your computer calculator on programmer mode or google.
http://screensnapr.com/v/aQEPYk.png

Related

c: convert hex to same value decimal number

i have
UINT8 year = 0x15;
and I want to get decimal value 15 in UINT8 decYear from year. How can I do it ? thankyou
background: I am ready day, month, year. I get value back 0x15, 0x10, 0x13 respectively for today. and I want to convert them to decimal values
The representation you are using is called Binary Coded Decimal and it's an old way of encoding values.
To get a "proper" decimal value you need to know how binary values work, and how to use the bitwise operators in C.
Lets say you have the BCD encoded value 0x15, this is binary 00010101. As you can see the 1 is stored in the high nibble and the 5 in the low. Getting them out by themselves is an easy bitwise-and operation:
int year = 0x15;
int high_nibble = year & 0xf0; // Gets the high nibble, i.e. `0x10`
int low_nibble = year & 0x0f; // Gets the low nibble, i.e. `0x05`
Now you have two variables, one containing 0x10 and the other 0x05. The hexadecimal value 0x05 is the same as the decimal value 5, so nothing needs to be done with it. The other value needs some work to make it the decimal 10. For this we simply shift it down four bits (00010000 will become 00000001) doing
high_nibble >> 4
and to "convert" it to decimal you multiply the value by 10 (1 * 10 == 10), and finally add the 5.
To put it all together into a single expression:
int decYear = ((year & 0xf0) >> 4) * 10 + (year & 0x0f);
In this specific case you can use this
UINT8 year = 0x15;
UINT8 yearD = year%16+ (year/16)*10;
There's better solution using BCD encoding
UINT8 yearD = ((year>>4)&0x0f)*10+ (year&0x0f);
Explanation:
Binary representation of 0x15 is ‭00010101‬. We have high nibble with 1 (0001) and low nibble 5(0101). So final result is higher nibble value *10 + value of lower nibble. To get high nibble value we do 4 shift right then bitwise AND with 0x0f, 4 right shift take high nibble value to lower nibble and bitwise and with 0x0f clear upper nibble, which is the real value of upper nibble. And to get lower nibble value we need to clear higher nibble value to do so we use year&0x0f.
Firstly: 0x15 is 21 (5 x 16 ^ 0) + ( 1 x 16 ^ 1 ), not 15.
Secondly, try:
UINT8 year = 0x15;
printf("%d",year);
This is because, no value is saved as hex or decimal, but as binary, ultimately. The hex you used is but a representation for your system to be translated to binary, like 21 would be.
Making it output 15 would probably be very difficult and make the fact that you even entered it in hex superflous. Its like entering 21 and asking for us to contrive a way for the system to know you meant 15
If you get a value in hex as return from something, try converting it into a string and just cutting off the 0x part of it.
For example, if you get 0x15 as value, just read it in as string, and cut the 0x off with string operations.
A "hexadecimal value that contains no letters" is Binary Coded Decimal (BCD). You can convert BCD to decimal like this
#include <stdio.h>
#include <stdint.h>
uint8_t bcd2dec(uint8_t bcdval)
{
return (bcdval >> 4) * 10 + (bcdval & 0xF);
}
int main(int argc, char *argv[])
{
printf("Day %u\n", bcd2dec(0x13));
printf("Month %u\n", bcd2dec(0x10));
printf("Year %u\n", bcd2dec(0x15));
return 0;
}
Program output:
Day 13
Month 10
Year 15
So if I understand correctly, you want to get 15 from 0x15.
You can use the following method:
char buffer[4];
UINT8 year = 0x15;
sprintf(buffer, "%x", year);
if you print buffer, you get "15" as a string. You can then do:
UINT8 decYear = atoi(buffer);
If 0x15 (in hexadecimal) does represent 15 (in decimal) then you are likely dealing with input in BCD format.
In such a case converting from BCD to decimal(1) is done by extracting each nible of the input and adding them properly.
Our input is a byte of 8 bits.
The 4 less significative bits (the lower nibble) represent the units, a number from 0 to 9. Values from A to F (hexadecimal) are never used.
The 4 most significative bits (the upper nibble) represent the tens. Also a number from 0 to 9.
If you extract them you get the decimal(1) value by the formula : tens*10 + units.
We can get the lower nibble with a binary mask : year & 0x0F
And the upper nibble with a right shift and the same binary mask : (year>>4) & 0x0F
The whole code is :
UINT8 year = 0x15;
assert ( ( (year>>4) & 0x0F ) < 10 ); // Ensure top nibble correctness
assert ( (year & 0x0F) < 10); // Ensure low nibble correcness
int yearBin = ( (year>>4) & 0x0F ) * 10 + (year&0x0F);
printf("%d\n", (int)yearBin); // Print yearBin in decimal : 15 will be printed
printf("%x\n", (int)yearBin); // Print yearBin in hexadecimal :
// 0x15 will not be printed. 0xF will be printed.
(1) Actually, we are not converting from BCD to decimal. We are converting from BCD to binary (most likely in 2-complement). It is the choice of conversion parameters in printf what makes it be printed in decimal.

When making binary masks for working and isolating bits and bytes, what's the fastest way to convert from Binary to Hex?

Assume I have the following binary string:
110110010110
From which I need only the 4th 5th and 6th bits, we've learned to use a mask like this
000000111000
So with the binary & operation I will get the bits I wanted and all I have left to do is shift them to the right.
Since C does not work with plain binary numbers we were told it's easiest to convert the binary mask string to a hexadecimal number. My lecturer used a super quick method to convert a binary string to a hexadecimal number.
What is the easiest and correct way to create those masks?
Each set of four bits corresponds to one hex 'digit'. Learn those, then just start converting blocks of four from right to left. (If you're converting a bit string that's not a multiple of four bits, then just add zeros to the left end until it is for the last conversion.)
0000 : 0x0
0001 : 0x1
0010 : 0x2
0011 : 0x3
0100 : 0x4
0101 : 0x5
0110 : 0x6
0111 : 0x7
1000 : 0x8
1001 : 0x9
1010 : 0xA
1011 : 0xB
1100 : 0xC
1101 : 0xD
1110 : 0xE
1111 : 0xF
For string to string? Grab 4 bits, find the number (0-15) then use as index for a table lookup. For a mask:
hex_digit = val & 0x0F;
Shift down 4 bits with:
val = val >> 4;
In my opinion, it would be helpful to cut your big string into smaller pieces of four bits, starting from the end (least significant bit). For example, your binary number 110110010110 could be written as 1101 1001 0110. If you have a number that can't be properly cut into pieces of four bits, say 1000011010, you should write it as 10 0001 1010.
Now, it's much more simple. In hexadecimal notation, 0 is 0 and f is 15. You start counting from zero, but instead of using 10 symbols, you now use 16. So it goes 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f.
You can replace each group of bits with its hexadecimal symbol! In your example (i.e. 1101 1001 0110) it would be d96, while in my example (i.e. 10 0001 1010) it would be 21a. For every one you find in a binary string, you add 2 ^ (position - 1) to your result, where position = 1 for the least significant bit. For example in 0110 you have 1 in position 2 (i.e. 2 ^ (2 - 1) = 2 ^ 1 = 2) and in position 3 (i.e. 2 ^ (3 - 1) = 2 ^ 2 = 4), so it is 2 + 4 = 6. Now, simply prepend 0x to tell the compiler that what follows is a Hexadecimal number and it becomes 0xd96.
In any case, writing a number as it is means it is in decimal notation, prepending a 0 suggests it is octal and prepending a 0x suggests it is a hexadecimal.
I hope this helps! :D

How is this bitwise AND operator masking the lower seven order bits of the number?

I am reading The C Programming Language by Brian Kernigan and Dennis Ritchie. Here is what it says about the bitwise AND operator:
The bitwise AND operator & is often used to mask off some set of bits, for example,
n = n & 0177
sets to zero all but the low order 7 bits of n.
I don't quite see how it is masking the lower seven order bits of n. Please can somebody clarify?
The number 0177 is an octal number representing the binary pattern below:
0000000001111111
When you AND it using the bitwise operation &, the result keeps the bits of the original only in the bits that are set to 1 in the "mask"; all other bits become zero. This is because "AND" follows this rule:
X & 0 -> 0 for any value of X
X & 1 -> X for any value of X
For example, if you AND 0177 and 0545454, you get
0000000001111111 -- 0000177
0101010101010101 -- 0545454
---------------- -------
0000000001010101 -- 0000154
In C an integer literal prefixed with 0 is an octal number so 0177 is an octal number.
Each octal digit (of value 0 to 7) is represented with 3 bits and 7 is the greatest value for each digit. So a value of 7 in octal means 3 bits set.
Since 0177 is an octal literal and each octal number is 3 three bits you have, the following binary equivalents:
7 = 111
1 = 001
Which means 0177 is 001111111 in binary.
It is already explained that the first '0' used for octal representation of a number in ANSI C. Actually, the number 0177 (octal) is same with 127 (in decimal), which is 128-1 and also can be represented as 2^7-1, and 2^n-1 in binary representation means take n 1's and put all the 1's to the right.
0177 = 127 = 128-1
which is a bitmask;
0000000000000000000000001111111
You can check the code down below;
Demo
#include <stdio.h>
int main()
{
int n = 0177; // octal representation of 127
printf("Decimal:[%d] : Octal:[%o]\n", n, n, n);
n = 127; // decimal representation of 127
printf("Decimal:[%d] : Octal:[%o]\n", n, n, n);
return 0;
}
Output
Decimal:[127] : Octal:[177]
Decimal:[127] : Octal:[177]
0177 is an octal value each digit is represented by 3 bits form the value 000 to 111 so 0177 translates to 001111111 (i.e 001|111|111) which if you consider in 32 bit binary ( can be 64 bit too except the remainder of the digits are populated as per the MSB i.e sign bit in this case value 0) form is 0000000000000000000000001111111 and and performing a bitwise with it for a given number, will output the lower 7 bits of the number turning of rest of the digits in the n-bit number to 0.
(since x&0 =0 & x&1=x e.g 0&0=0 ,1&0=0, 1&1=1 0&1=1)

Why are decimal numbers used in bitmasks?

This is a pretty basic question, and I'm sure that there's an easy answer to it, but I don't know the search term I should be using to look for an answer. Here it goes:
I'm trying to understand how bitmasks work. On Linux systems there's:
struct stat
that has a st_mode member that's used to determine whether the file being inspected is a regular file, a directory, a symbolic link, and others. So, it's possible to write a simple function that you can pass a name to and get whether or not the name represents a directory:
16 int isadir( char *name )
17 /*
18 * calls stat, then masks the st_mode word to obtain the
19 * filetype portion and sees if that bit pattern is the
20 * pattern for a directory
21 */
22 {
23 struct stat info;
24
25 return ( stat(name,&info)!=-1 && (info.st_mode & S_IFMT) == S_IFDIR );
26 }
When I look at the bitmask, I see it's represented as follows:
/* Encoding of the file mode. */
#define __S_IFMT 0170000 /* These bits determine file type. */
I thought bitmasks could only have 0s and 1s. Why is there a 7 in the mask?
Numbers starting with a leading 0 are octal numbers — this is standard C syntax.
And these can be useful for bitmasks, especially to represent Unix permissions.
A byte is 8 bits, and can be expressed in decimal (0 to 255), octal (000 to 377), hexadecimal (00 to FF) or binary (00000000 to 11111111). Let's number the bits, from bit 0 to bit 7:
76543210
Actually a number may be expressed in any base, but mainly octal and hexadecimal are convenient when one want to break down the number into bits ; expressing a byte in octal is easier as
z y x
76543210
x is bits 0 to 2, y is bits 3 to 5 and z is bits 6 and 7.
Thus in your exemple, 017 octal number is
0 1 7
00 001 111
Numbers expressed in octal base (8-base) are easier to be converted to binary. (in hexa that would be 0F).
In C (...), octal literal numbers start with a leading zero (0...), and in hexadecimal they start with leading 0x (0x...). As it is easier to visualize bits of numbers expressed in octal,
022 & 017
gives in binary
"00 010 010" &
"00 001 111"
result can be found out easily
"00 000 010"
In decimal, that would be 18 & 15.

Converting Decimal to Hexadecimal and Octal

Show how to write a constant in C, whose decimal value is 65 as
a. a hexadecimal constant
65/16 = 1 r1
1/16 = 0 r1
Hexadecimal constant = 11
b. an octal constant (in C)
65/8 = 8 r1
8/8 = 1 r0
1/8 = 0 r1
Octal constant = 101
Is this the right way to convert constants in C?
You just need a while loop and a string. As this is homework, I do not think I should say more than that.
The method is to divide by the base until the result is less than the base.
So 65/8 gives 8 r1 but you don't stop there because the result is 8 not less than 8
You divide by 8 again and get 1
It should be
65/64 = 10 r 1 where 64 = 8x8 = octal 10
I don't think I've said too much
Maybe I am misunderstanding the questions, but it seems like you are being asked how hex and oct constants are represented in C, not how to implement an algorithm to convert dec to hex and oct.
If that is the case:
hex numbers are represented by a preceding 0x or 0X
oct numbers are represented by a preceding 0
int hex = 0x41;
int oct = 0101;
Of course, you can verify this by printing our the values in decimal:
printf("%d\n", hex);
printf("%d\n", oct);

Resources