I'm having a little trouble writing my code to rotate my hexadecimal digits right. Below is a function I wrote, where, if you call on it, passing it like so: rotr(0x12345678, 4), it should return 0x81234567. Instead, it's only returning 7 digits (as opposed to eight, like in the original value = 0x12345678).
Can someone please help me understand what is going on in the bit level? I'm having trouble understanding why my current code is returning 0x123456f, instead of 0x81234567. Thanks in advance!
Edit: is it because I'm shifting 0x12345678 too early? I'm mainly trying to figure out why only seven digits return back, as opposed to eight.
unsigned int rotr(unsigned int x, int n) {
int i; //iterate for loop
unsigned int y; //masked last bit
unsigned int z; //final result
for (i=1; i<=n; i++) {
y = x & 0x1; //isolates last bit
x = x >> 1; //shift right 1
z = x | (y << (sizeof(x)-1)); //shifts mask back to first slot; OR
//it with x
}
return z;
}
sizeof(x) will give the size of the variable in bytes, while the shift operators work with numbers of bits. You need to convert these operands to use the same unit.
instead of sizeof(x) you should write 8*sizeof(x), it's looks generic because your input may be short int, long int or anything.
For Right Rotation instead of rotating loops you can try below logic.
#include<stdio.h>
unsigned int rotr(unsigned int x, int n) {
unsigned int z;
z = (x >> n) | (x << (8*sizeof(int) - n)) ;
return z;
}
int main()
{
unsigned int num= 0x12345678, n = 4, ret;
printf("before : %x\n",num);
ret= rotr(num,n);
printf("before : %x\n",ret);
}
Related
I have a program that will take two 4-byte integers as input and I need to store these into integer arrays like so...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[]) {
int vals1[32], vals2[32];
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
// so argv[1] might be 47 and I would want to set the values of the vals1 array to reflect that in binary form
}
Any suggestions?
First task would be to convert a char * to an int, which you said you can. So here comes the next part i.e. getting the binary representation. For getting the binary representation of any data type, usage of Shift Operator is one of the best ways. And you can get it by performing shift on the data type and then performing Bitwise AND i.e. & with 1. For example, if n is an integer
int n = 47;
for (int i = 0; i < 32; i++)
{
/* It's going to print the values of bits starting from least significant. */
printf("Bit%d = %d\r\n", i, (unsigned int)((n >> i) & 1));
}
So, using shift operator, solution to your problem would be something like
void fun(int n1, int n2)
{
int i, argv1[32], argv2[32];
for (i = 0; i < 32; i++)
{
argv1[i] = ((unsigned int)n1 >> i) & 1;
argv2[i] = ((unsigned int)n2 >> i) & 1;
}
}
You have to be careful about the bit order i.e. which bit are being stored at which of the array index.
After reading the question how to get bit by bit data from a integer value in c?, I see that if I want to look at each bit in an integer, I should right shift the integer and mask it. But I wonder is it possible to access each bit in the memory without such a complicated code? By using pointer or something like that.
In C, bit wise operations, like shifting is one of the only ways to manipulate variables on the bit level. Its expressions can be somewhat "ugly" at first glance but like everything through practice, will soon be easy to understand.
Just keep at it.
Here's a great article for your interest:
A bit of fun: fun with bits
It is possible to do it without shifting and masking, but it's hardly less "complicated" to do so:
#include <stdio.h>
#include <stdbool.h>
unsigned int ui_pow(unsigned int base, unsigned int exponent)
{
unsigned int result = 1;
for ( unsigned int i = 1; i <= exponent; ++i ) {
result *= base;
}
return result;
}
bool bit_is_set_one(unsigned int n, unsigned int bit)
{
return (n >> bit) & 1;
}
bool bit_is_set_two(unsigned int n, unsigned int bit)
{
return (n / ui_pow(2, bit)) % 2;
}
int main(void)
{
bool all_equal = true;
for ( unsigned int i = 0; i < 65535; ++i ) {
for ( unsigned int j = 0; j < 16; ++j ) {
if ( bit_is_set_one(i, j) != bit_is_set_two(i, j) ) {
all_equal = false;
}
}
}
printf("Methods%s give equal results.\n", all_equal ? "" : " do not");
return 0;
}
which outputs:
paul#thoth:~/src/sandbox$ ./altshift
Methods give equal results.
paul#thoth:~/src/sandbox$
If you know the bit location, you can do a bit mask without doing the shift.
For example: (i & 0x02)
You'll get 0x02 if the 2nd bit from right is a 1, or 0x00 if the 2nd bit is a 0.
Usually a macro is used: #define BitMask(i) (1 << (i))
For a constant i, the shift will be handle in compilation stage, and it wont show up in final binaries.
I think if some integer is in register by scanf, then the number would be in 2s complement representation. Can I get that number by printf? I searched many websites but couldnt find the code for C beginners...
Float numbers are not stored in 2's complement, but rather in IEEE 754. To print the binary representation of some binary data, first see https://stackoverflow.com/a/112956/1689451. You can put your float into a union to extract the single bytes:
#include <stdio.h> /* printf */
#include <string.h> /* strcat */
// taken from https://stackoverflow.com/a/112956/1689451
const char *byte_to_binary(int x)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
union {
float f;
unsigned char b[4];
} x;
x.f = 0.34;
for (int i = 0; i < 4; i++) {
printf("%s", byte_to_binary(x.b[i]));
}
I did not try the example; does probably not compile, but should give hints in the right direction.
There's no standard in c that prints "two's complement" number or binary numbers in general, if that's your question. That task must be solved separately. Eg.
for (i=0;i<32;i++) putc( '0'+((number >> (31-i)) & 1)); // or copy to local strings
Otherwise scanf("%f", &my_float); prints with printf("%f", my_float);
I wrote this code to do the IEEE 754 floating point arithmetic on a 4byte string.
It takes in the bytes, converts them to binary and with the binary I get the sign, exponent, and mantissa and then do the calculation.
It all works just about perfectl, 0xDEADBEEF gives me 6259853398707798016 and the true answer is 6.259853398707798016E18, now these are same values and I wont have anything this large in the project I'm working with, all other smaller values put the decimal in the correct place.
Here is my code:
float calcByteValue(uint8_t data[]) {
int i;
int j = 0;
int index;
int sign, exp;
float mant;
char bits[8] = {0};
int *binary = malloc(32*sizeof *binary);
for (index = 0;index < 4;index++) {
for (i = 0;i < 8;i++,j++) {
bits[i] = (data[index] >> 7-i) & 0x01;
if (bits[i] == 1) {
binary[j] = 1;
} else {
binary[j] = 0;
}
}
printf("\nindex(%d)\n", index);
}
sign = getSign(&(binary[0]));
mant = getMant(&(binary[0]));
exp = getExp(&(binary[0]));
printf("\nBinary: ");
for (i = 0;i < 32;i++)
printf("%d", binary[i]);
printf("\nsign:%d, exp:%d, mant:%f\n",sign, exp, mant);
float f = pow(-1.0, sign) * mant * pow(2,exp);
printf("\n%f\n", f);
return f;
}
//-------------------------------------------------------------------
int getSign(int *bin) {
return bin[0];
}
int getExp (int *bin) {
int expInt, i, b, sum;
int exp = 0;
for (i = 0;i < 8;i++) {
b = 1;
b = b<<(7-i);
if (bin[i+1] == 1)
exp += bin[i+1] * b;
}
return exp-127;
}
float getMant(int *bin) {
int i,j;
float b;
float m;
int manBin[24] = {0};
manBin[0] = 1;
for (i = 1,j=9;j < 32;i++,j++) {
manBin[i] = bin[j];
printf("%d",manBin[i]);
}
for (i = 0;i < 24;i++) {
m += manBin[i] * pow(2,-i);;
}
return m;
}
Now, my teacher told me that there is a much easier way where I can just take in the stream of bytes, and turn it into a float and it should work. I tried doing it that way but could not figure it out if my life depended on it.
I'm not asking you to do my homework for me, I have it done and working, but I just need to know if I could of done it differently/easier/more efficiently.
EDIT: there are a couple special cases I need to handle, but it's just things like if the exponent is all zeros blah blah blah. Easy to implement.
The teacher probably had this in mind:
char * str; // your deadbeef
float x;
memcpy(&x, str, sizeof(float));
I would advise against it, for the issues with endianness. But if your teacher wants it, he shall have it.
I think you want a union - just create a union where one member is a 4 character array, and the other a float. Write the first, then read the second.
Looking at what your code does then the "4 byte string" looks like it already contains the binary representation of a 32 bit float, so it already exists in memory at the address specified by data in big endian byte order.
You could probably cast the array data to a float pointer and dereference that (if you can assume the system you are running on is big endian and that data will be correctly aligned for the float type on your platform).
Alternatively if you need more control (for example to change the byte order or ensure alignment) you could look into type punning using a union of a uint8_t array and a float. Copy the bytes into your union's uint8_t array and then read the float member.
Here is my working code:
unsigned char val[4] = {0, 0, 0xc8, 0x41};
cout << val << endl;
cout << "--------------------------------------------" << endl;
float f = *(float*)&val;
cout << f << endl;
return 0;
How do you count the number of bits set in a floating point number using C functions?
#include <stdio.h> /* for printf() */
#include <limits.h> /* for CHAR_BIT */
int main(void) {
/* union method */
{
/* a union can only be initialized for the first option in the union */
union { float f; char cs[sizeof(float)]; } const focs = { 1.0 };
int j,k;
int count = 0;
for (j = 0; j < sizeof(float); j++)
{
char const byte = focs.cs[j];
for (k = 0; k < CHAR_BIT; k++)
{
if ((1 << k) & byte)
{
count++;
}
}
}
printf("count(%2.1f) = %d\n", focs.f, count);
}
/* cast method */
{
float const f = 2.5;
int j,k;
int count = 0;
for (j = 0; j < sizeof(float); j++)
{
char const byte = ((char *)&f)[j];
for (k = 0; k < CHAR_BIT; k++)
{
if ((1 << k) & byte)
{
count++;
}
}
}
printf("count(%2.1f) = %d\n", f, count);
}
return 0;
}
If you want to work on the actual bitwise representation of a floating point number, you should do something like this:
float f; /* whatever your float is */
int i = *(int *)&f;
What this does is take the address of f with the address-of operator, &. This address is of type float *, a pointer to a float. Then it recasts it with (int *), which says "pretend this pointer doesn't point to a float anymore, but now it points to an int". Note that it doesn't change the value at f at all. Then the last * (or first, since we read right-to-left) dereferences this pointer, which is a pointer to an int, and therefore returns an int, a.k.a. the integer with the same bitwise representation as the float.
To do the opposite (convert and int i back to a float f), do the opposite:
f = *(float *)&i;
Unless I am mistaken, this operation is undefined by the C standard, but will probably work on most computers and compilers. It is undefined because I believe the actual floating-point representation of numbers is implementation-dependent, and can be left to the CPU or the compiler, and therefore the value of i is almost impossible to predict after this operation (same goes for the value of f in the reverse operation). It is famously used in John Carmack's inverse square root function for the same nefarious purpose.
Anyway, if you're doing this in real code, you should probably stop and think twice about what you're trying to do and why you're using floats to do it. However, if you're just doing this out of curiosity, or you have thought about these and are sure of your design and methods, go for it.
I'm led to believe that you already know how to count the number of bits set in a regular integer, as this is a much easier task. If you don't know, your compiler (or the C language, I don't even know) may have a function to count bits, or you could use something from the wonderful Bit-Twiddling Hacks website, which has ways to do things like this with bitwise operations (which should be pretty fast).
A nice function for counting set bits in an integer mentioned by the first answer:
int NumberOfSetBits(int i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
To use it on your float you would do something like this:
//...
float f;
//...
int numBitsOfF = NumberOfSetBits(*(int*) &f);
You mean the bits set in the IEEE-754 single precision representation of a number? If so, cast it to int (both float and int are 32bit wide) and do a regular bit count: SO question #109023.
The following function will find the number of bits in a 32-bit number. Just type case your float with integer and call this function by a cast
float f=3.14f;
count_bits(*(int *)&f);
int count_bits(int v)
{
// count the number of bits set in v
int c; // c accumulates the total bits set in v
int b=v;
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
//printf("No of bits in %d is %d\n",b,c);
return c;
}