Single floating point decimal to binary in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write C program that initializes a variable of type float to 1000.565300 and extracts relevant fields of the IEEE 754 representation. I should extract the sign bit (bit 31), the exponent field (bits 30 to 23) and the significant field (bits 22 to 0). I should use bit masking and shift operations to extract these fields. My program should keep the extracted fields in 32-bit unsigned integers and should print their values in the hexadecimal and binary formats. And here is my program. I do not know how to bit masking

Well, one easy way to do all this is:
Interpret a float bits as an unsigned: uint32_t num = *(uint32_t*)&value
It means: I want to treat the address of value as the address of a 32 bit unsigned and then I want to take the value stored at that address
Sign: int sign = (~(~0u>>1)&num) ? -1 : 1 //checks if first bit of float is 1 or 0 , if it's 1 then it's a negative number
exp part: uint32_t exp = num&0x7F800000
mantissa : uint32_t mant = num&0x007FFFFF
If you don't know masks :
0x7F800000 : 0 11111111 00000000000000000000000
0x007FFFFF : 0 00000000 11111111111111111111111
As for printing bits , you can use this function:
void printbits(uint32_t num)
{
for(uint32_t m=~(~0u>>1);m;m>>=1) // initial m = 100..0 then 0100..0 and so on
putchar(n&m ? '1' : '0');
putchar('\n');
}

Related

How to store a binary string into uint8_t array bits? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I have binary string( only 0s or 1s) "0101011111011111000001001001110110", for Huffman encoding I want to store each char in the string as bit representation in a uint8_t array.
If I write the binary string as-is into a file it occupies 35 bytes. If we can store each binary char in the string as bit representation in uint8_t array, it can be stored in ~5 bytes.
static uint8_t out_buffer[1024];
static uint32_t bit_pos = 0;
void printbuffer()
{
printf("Just printing bits\n");
int i;
for (i = 0; i < bit_pos; i++) {
printf("%c", (out_buffer[i / 8] & 1 << (i % 8)) ? '1' : '0');
}
}
void append_to_bit_array(char* in, int len, uint8_t* buf)
{
int i;
printbuffer();
for (i = 0; i < len; i++) {
if (in[i])
{
buf[bit_pos / 8] |= 1 << (bit_pos % 8);
}
bit_pos++;
}
}
You need to first decide on what order you want to put the bits in the bytes — i.e. put the first bit in the most significant bit of the first byte, or the least? You also need to have a strategy to deal with the extra 0 to 7 bits in the last byte. Those could look like another Huffman code, and give you extraneous symbols when decoding. Either you will need a count of symbols to decode, or you will need an end symbol that you add to your set before Huffman coding, and send that symbol at the end.
Learn the bitwise operators in C noted in your tag, and use those to place each bit, one by one, into the sequence of bytes. Those are at least the shifts << and >>, and &, and or |.
For example, 1 << n gives you a one bit in position n. a |= 1 << n would set that bit in a, given that a is initialized to zero. On the decoding end, you can use & to see if a bit is set. E.g. a & (1 << n) would be non-zero if bit n in a is set.

can't understand showbit() function in bitwise operatrers in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
Improve this question
/* Print binary equivalent of characters using showbits( ) function */
#include <stdio.h>
void showbits(unsigned char);
int main() {
unsigned char num;
for (num = 0; num <= 5; num++) {
printf("\nDecimal %d is same as binary ", num);
showbits(num);
}
return 0;
}
void showbits(unsigned char n) {
int i;
unsigned char j, k, andmask;
for (i = 7; i >= 0; i--) {
j = i;
andmask = 1 << j;
k = n & andmask;
k == 0 ? printf("0") : printf("1");
}
}
Sample numbers assigned for num : 0,1,2,3,4 ...
Can someone explain in detail what is going on in
k = n & andmask? How can n, which is a number such as 2, be an operand of the same & operator with andmask, eg 10000000, since 2 is a 1-digit value and 10000000 is a multiple-digit value?
Also why is char is used for n and not int?
Let's walk through it.
Assume n is 2. The binary representation of 2 is 00000010.
The first time through the loop j is equal to 7. The statement
andmask = 1 << j;
takes the binary representation of 1, which is 00000001, and shifts it left seven places, giving us 10000000, assigning to andmask.
The statement
k = n & andmask;
performs a bitwise AND operation on n and andmask:
00000010
& 10000000
--------
00000000
and assigns the result to k. Then if k is 0 it prints a "0", otherwise it prints a "1".
So, each time through the loop, it's basically doing
j andmask n result output
- -------- -------- -------- ------
7 10000000 & 00000010 00000000 "0"
6 01000000 & 00000010 00000000 "0"
5 00100000 & 00000010 00000000 "0"
4 00010000 & 00000010 00000000 "0"
3 00001000 & 00000010 00000000 "0"
2 00000100 & 00000010 00000000 "0"
1 00000010 & 00000010 00000010 "1"
0 00000001 & 00000010 00000000 "0"
Thus, the output is "00000010".
So the showbits function is printing out the binary representation of its input value. They're using unsigned char instead of int to keep the output easy to read (8 bits instead of 16 or 32).
Some issues with this code:
It assumes unsigned char is always 8 bits wide; while this is usually the case, it can be (and historically has been) wider than this. To be safe, it should be using the CHAR_BIT macro defined in limits.h:#include <limits.h>
...
for ( i = CHAR_BIT - 1; i >= 0; i++ )
{
...
}
?: is not a control structure and should not be used to replace an if-else - that would be more properly written asprintf( "%c", k ? '1' : '0' );
That tells printf to output a '1' if k is non-zero, '0' otherwise.
Can someone explain in detail what is going on in k = n & andmask? How can n, which is a number such as 2, be an operand of the same & operator with andmask, eg 10000000, since 2 is 1 digit value and 10000000 is multiple digit value?
The number of digits in a number is a characteristic of a particular representation of that number. In context of the code presented, you actually appear to be using two different forms of representation yourself:
"2" seems to be expressed (i) in base 10, and (ii) without leading zeroes.
On the other hand, I take
"10000000" as expressed (i) in base 2, and (ii) without leading zeroes.
In this combination of representations, your claim about the numbers of digits is true, but not particularly interesting. Suppose we consider comparable representations. For example, what if we express both numbers in base 256? Both numbers have single-digit representations in that base.
Both numbers also have arbitrary-length multi-digit representations in base 256, formed by prepending any number of leading zeroes to the single-digit representations. And of course, the same is true in any base. Representations with leading zeroes are uncommon in human communication, but they are routine in computers because computers work most naturally with fixed-width numeric representations.
What matters for bitwise and (&) are base-2 representations of the operands, the width of one of C's built-in arithmetic types. According to the rules of C, the operands of any arithmetic operators are converted, if necessary, to a common numeric type. These have the same number of binary digits (i.e. bits) as each other, some of which often being leading zeroes. As I infer you understand, the & operator computes a result by combining corresponding bits from those base-2 representations to determine the bits of the result.
That is, the bits combined are
(leading zeroes)10000000 & (leading zeroes)00000010
Also why is char is used for n and not int?
It is unsigned char, not char, and it is used for both n and andmask. That is a developer choice. n could be made an int instead, and the showbits() function would produce the same output for all inputs representable in the original data type (unsigned char).
At first glance this function seems to print an 8-bit value in binary representation (0s and 1s). It creates a mask that isolate each bit of the char value (setting all other bits to 0) and prints "0" if the masked value is 0 or "1" otherwise. char is used here because the function is designed to print the binary representation of an 8-bit value. If int was used here, only values in the range [0-255] would correctly be printed.
I don't understand your point with the 1-digit value and multiple-digit value.

How to store 10 bit float value in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a radar device. Various data coming out from device like detected object speed, acceleration distance etc. But the data is in 10 bit and 13 bit float values. How to print that 10 bit and 13 bit float value and how to store that values ? As floats having 32 bit value. I tried to store it in float variable directly but it gives wrong values.
For the 10-bit case, input consists of:
Bit 15: sign
Bits 10-14: exponent (exponent = (bits 10-14) + 15)
Bits 0-9: signficant (1.(bits 0-9))
Something like this should work, although note I haven't tested it:
int halfFloatToInt16(unsigned int input, int shift)
{
int exp, output;
// Load precision: (1.(precision bits 0-9))
output = (int)(0x03FF & input);
output += 0x0400;
// Apply sign (bit 15)
output = (0x8000 & input)?(-output):output;
// Calculate exponent (bits 10 - 14)
// Adjustment -25 = -15 for exponent and -10 for significand
exp = (int)((0x001F) & (input >> 10));
exp -= 25;
// Apply shift to acheive desired fixed point precision
exp += shift;
// Shift output
if(exp > 0)
{
return(output << exp);
}
else
{
return(output >> exp);
}
}
Here the input will be the 16-bit floating point value, as specified above, casted to unsigned int. The shift identifies the shift that's been applied to the output. So the output of the function will be the value times two to the power specified by shift. For example if the expected maximum output value is 1 you would use a shift of 14. So 16384 represents one. If the maximum expected value of the output is 20000, you make the shift zero. This will optimize the overall precision of the output.

What does "return 0x8000 0000;" mean? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I saw the following code(part of a function):
if (end == start)
{
*max = *min = *start;
return 0x80000000;
}
I dont understand why it returns 0x80000000,which is 2^31,and it is out of int's range and has type unsigned int
And what is it equal to ?
Complete code:
int MaxDiffCore(int* start, int* end, int* max, int* min)
{
if (end == start)
{
*max = *min = *start;
return 0x80000000;
}
int* middle = start + (end - start) / 2;
int maxLeft, minLeft;
int leftDiff = MaxDiffCore(start, middle, &maxLeft, &minLeft);
int maxRight, minRight;
int rightDiff = MaxDiffCore(middle + 1, end, &maxRight, &minRight);
int crossDiff = maxLeft - minRight;
*max = (maxLeft > maxRight) ? maxLeft : maxRight;
*min = (minLeft < minRight) ? minLeft : minRight;
int maxDiff = (leftDiff > rightDiff) ? leftDiff : rightDiff;
maxDiff = (maxDiff > crossDiff) ? maxDiff : crossDiff;
return maxDiff;
}
0x80000000 is not out of int's range. An int is platform dependent, and there are platforms where int is 32 bits wide. This number is 32 bits wide, so it will do a "straight bit assignment" to the int.
Yes, the decimal representation of this number is 2^31 but that's only if you interpret the bits as unsigned, which in the case of bits, makes little sense. You really need to look at the L-value to know what it is going to be handled as, and that's a signed int/
Now, assuming this is a 32 bit platform, this is a fancy way to write MIN_INT, and by fancy, I mean non-portable and requiring a lot of assumptions that aren't constant, and finally confusing to those who don't want to do the binary math. It assumes 2's complement math and opts to set the bits directly.
Basically, with 2's complement numbers, zero is still
0x00000000
but to get -1 + 1 = 0 you have to get something to add to 1 yeilding 0
0x????????
+ 0x00000001
= 0x00000000
So you choose
0x11111111
+ 0x00000001
= 0x00000000
relying on the carrying 1's to eventually walk off the end. You can then deduce that 1 lower is -2 and so on; up to a point -2 = 0x11111110 and so on. Basically since the first bit determines the "sign" of the number, the "biggest" negative number you could have would be 0x1000000 and if you tried to subtract 1 from that, you would carry from the "negative" sign bit yielding the largest positive number. 0x01111111.
If the constant has type unsigned int on your platform and the function is declared as returning int, then the unsigned int value will get implicitly converted to type int. If the original value does not fit into int range, the result of this conversion is implementation-defined (or it might raise a signal).
6.3.1.3 Signed and unsigned integers
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is
implementation-defined or an implementation-defined signal is raised.
Consult your compiler documentation to see what will happen in this case. Apparently the authors of the code came to conclusion that the implementation does exactly what they wanted it to do. For example, a natural thing to expect is for some implementation to "reinterpret" this bit pattern as a signed integer value with the highest-order bit becoming the sign bit. It will convert 0x80000000 into INT_MIN value on a 2's-complement platform with 32-bit ints.
This is a wrong practice and the return value should be corrected.
The code is returning binary 10000000 00000000 00000000 00000000 and
On machines where sizeof(int) = 4byte :
In your case, function return type int is treating it as binary 10000000 00000000 00000000 00000000 = integer -2147483648 (negative value).
If function return type would have been unsigned int, it would have treated 0x80000000 as binary 10000000 00000000 00000000 00000000 = integer 2147483648
On machines where sizeof(int) = 2byte :
The result would be implementation-defined or an implementation-defined signal would be raised [see other answer].

What does XORing for 2 decimal numbers mean? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I know that XORing 2 decimal numbers mean that, they binary representations are XORed.
But what does it mean non-mathematical sense ?
What significance does it have?
If you XOR the result with one of the original numbers, you get the other original number.
a ^ b = X
X ^ a = b
X ^ b = a
This is used commonly in cryptography and hashing algorithms.
In simple words, the XOR of two decimal means, first converting the two decimals to binary and then performing the bit-wise XOR and then again converting the result to decimal.
Let's take an example,
Suppose we wanna find out what does 3^7 results? (where ^ is symbolising XOR operation)
Step 1 : Converting the numbers from decimal to binary
3 => 0011 and 7 => 0111
Step 2 : Taking the bit-wise XOR of the two binary numbers
3 : 0011
7 : 0111
3^7 : 0100
(hint : 1^0 = 1 and 1^1 = 0^0 = 0)
Step 3 : Convert the answer to decimal
0100 => 4
Hence, the 3^7 = 4
Click here for more details.
if i correctly understand, you are searching for the physical meaning of XOR.
xor is an odd parity counter, i mean if you xor(A,B), you are counting the number of ones in each bit, if the number is odd, the xor output will be one
Ex:
3 = 0011
5 = 0101
3 ^ 5 = 0110
in the LSB there are (1 and 1) which represent two ones, and since two is even, therefore you put 0, in the next bit, there are (1 and 0) and the count of ones is one which is odd, therefore you put 1 and so on.
if you want to experiment this, try this online calculator
this is used alot in telecommunication for parity check and in error correcting algorithms, and generation of orthogonal code sequencye; see this website about CDMA for more details.
a Simple example for parity checking, assume we send 8 Bits, 7 Bits data and 8th bit is parity check.
we send :
0110011X: X in this case is the parity checker, is 0 because we have 4 ones and 4 is even.
if there is a mistake in the data tranmitted and we receive for example this
11100110: Number of ones in the Byte Stream is 5 with a mistake in MSB. 5 should produce a parity bit of 1 because 5 is odd, but since the parity is 0, this means there is a mistake in the data transmitted. This is the simplest parity check used in serial data transfer. Error Correcting codes build on it.

Resources