patterncMinor
Variable to byte decaying function
Viewed 0 times
bytevariablefunctiondecaying
Problem
A function that prints out the values of each of the bytes of a variable, which value is given from
Consists of size detector and a loop.
I don't like the size detection though, it could be more safely coded with one line of bit operations I believe.
stdin.Consists of size detector and a loop.
#include
#include
int main(void)
{
unsigned char uint_8;
unsigned short uint_16;
unsigned long uint_32;
unsigned long long uint_64, n = 0;
int i;
size_t size;
printf("Enter a number: ");
scanf("%lld", &n);
if(n 256) size = 2;
if(n 256*256) size = 3;
if(n pow(256, 3)) size = 4;
for(i = 0; i < size; i++)
{
unsigned char* p = (((unsigned char*)&n) + i);
printf("byte(%i) : %i\n", i, *p);
}
return 0;
}I don't like the size detection though, it could be more safely coded with one line of bit operations I believe.
Solution
A couple of remarks:
-
You should check the return value of
-
Using
-
-
Multiplying an integer by a power of 2 can be done by a left-shift. So
In the end the size detection can be generalized by finding which byte is the most significant byte - which boils down to finding the most significant bit (the highest bits which is 1). There are a bunch of clever operations to make this really fast but the simplest is to shift right until all set bits are shifted out:
-
You should check the return value of
scanf. It returns the number of items successfully converted. You initialize n with 0 so any invalid input will yield in a single 0 output but it might be good to indicate failure anyway.-
Using
EXIT_SUCCESS and EXIT_FAILURE are more portable ways to indicate success/failure upon return to the OS.-
256 is is not representable by an 8-bit type. The binary representation is 1 0000 0000 - so the 9th bit is set. An 8 bit unsigned type can only hold 0 - 255.-
Multiplying an integer by a power of 2 can be done by a left-shift. So
2^5 for example is 1
-
You print out the order of bytes in big endian notation (the highest ordered byte is printed out with the smallest index) while for example x86 is a little endian architecture where the lowest ordered byte has the smallest index. Actually scratch that. The data in memory is laid out little endian so your code will print it in little endian order.
-
Your size detection works on the assumption that a char is 8 bit. This is not guaranteed by the C standard which requires CHAR_BIT to be at least 8. For example there DSPs where CHAR_BIT is 16 and in the past there were architectures with 9 and 12 bit bytes.
-
Your size detection only goes up to 4 bytes however unsigned long long` is 8 bytes on many platforms. So if someone puts a large number in the it will simply omit the upper 4 bytes.In the end the size detection can be generalized by finding which byte is the most significant byte - which boils down to finding the most significant bit (the highest bits which is 1). There are a bunch of clever operations to make this really fast but the simplest is to shift right until all set bits are shifted out:
#include
#include
#include
int main(void)
{
unsigned long long n = 0;
unsigned long long temp;
int most_significant_bit = 0;
int most_significant_byte = 0;
int i;
printf("Enter a number: ");
if (scanf("%lld", &n) != 1)
{
printf("Invalid number entered.");
return EXIT_FAILURE;
}
temp = n;
while (temp >>= 1)
{
++most_significant_bit;
}
most_significant_byte = (most_significant_bit / CHAR_BIT) + 1;
for(i = 0; i < most_significant_byte; i++)
{
unsigned char* p = (((unsigned char*)&n) + i);
printf("byte(%i) : %i\n", i, *p);
}
return EXIT_SUCCESS;
}Code Snippets
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void)
{
unsigned long long n = 0;
unsigned long long temp;
int most_significant_bit = 0;
int most_significant_byte = 0;
int i;
printf("Enter a number: ");
if (scanf("%lld", &n) != 1)
{
printf("Invalid number entered.");
return EXIT_FAILURE;
}
temp = n;
while (temp >>= 1)
{
++most_significant_bit;
}
most_significant_byte = (most_significant_bit / CHAR_BIT) + 1;
for(i = 0; i < most_significant_byte; i++)
{
unsigned char* p = (((unsigned char*)&n) + i);
printf("byte(%i) : %i\n", i, *p);
}
return EXIT_SUCCESS;
}Context
StackExchange Code Review Q#80071, answer score: 3
Revisions (0)
No revisions yet.