c; converting 2 bytes to short and vice versa - c

I want to convert array of bytes bytes1 (little endian), 2 by 2, into an array of short integers, and vice versa . I expect to get final array bytes2, equal to initial array bytes1. I have code like this:
int i = 0;
int j = 0;
char *bytes1;
char *bytes2;
short *short_ints;
bytes1 = (char *) malloc( 2048 );
bytes2 = (char *) malloc( 2048 );
short_ints = (short *) malloc( 2048 );
for ( i=0; i<2048; i+=2)
{
short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ;
j++;
}
j = 0;
for ( i=0; i<2048; i+=2)
{
bytes2[i+1] = (short_ints[j] >> 8) & 0xff;
bytes2[i] = (short_ints[j]) ;
j++;
}
j = 0;
Now, can someone tell me why I haven't got bytes2 array, completely the same as bytes1 ? And how to do this properly?

Suggest 2 functions. Do all combining and extraction as unsigned to remove issues with the sign bit in short and maybe char.
The sign bit is OP's code biggest problem. short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ; likely does a sign extend with bytes1[i] conversion to int.
Also (short_ints[j] >> 8) does a sign extend.
// Combine every 2 char (little endian) into 1 short
void charpair_short(short *dest, const char *src, size_t n) {
const unsigned char *usrc = (const unsigned char *) src;
unsigned short *udest = (unsigned short *) dest;
if (n % 2) Handle_OddError();
n /= 2;
while (n-- > 0) {
*udest = *usrc++;
*udest += *usrc++ * 256u;
udest++;
}
}
// Break every short into 2 char (little endian)
void short_charpair(char *dest, const short *src, size_t n) {
const unsigned short *usrc = (const unsigned short *) src;
unsigned char *udest = (unsigned char *) dest;
if (n % 2) Handle_OddError();
n /= 2;
while (n-- > 0) {
*udest++ = (unsigned char) (*usrc);
*udest++ = (unsigned char) (*usrc / 256u);
usrc++;
}
}
int main(void) {
size_t n = 2048; // size_t rather than int has advantages for array index
// Suggest code style: type *var = malloc(sizeof(*var) * N);
// No casting of return
// Use sizeof() with target pointer name rather than target type.
char *bytes1 = malloc(sizeof * bytes1 * n);
Initialize(bytes, n); //TBD code for OP-best to not work w/uninitialized data
// short_ints = (short *) malloc( 2048 );
// This is weak as `sizeof(short)!=2` is possible
short *short_ints = malloc(sizeof * short_ints * n/2);
charpair_short(short_ints, bytes1, n);
char *bytes2 = malloc(sizeof * bytes2 * n);
short_charpair(bytes2, short_ints, n);
compare(bytes1, bytes2, n); // TBD code for OP
// epilogue
free(bytes1);
free(short_ints);
free(bytes2);
return 0;
}
Avoided the union approach as that is platform endian dependent.

Here's a program that demonstrates that you are experiencing the problem associated with bit-shifting signed integral values.
#include <stdio.h>
#include <stdlib.h>
void testCore(char bytes1[],
char bytes2[],
short short_ints[],
int size)
{
int i = 0;
int j = 0;
for ( i=0; i<size; i+=2)
{
short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ;
j++;
}
j = 0;
for ( i=0; i<size; i+=2)
{
bytes2[i+1] = (short_ints[j] >> 8) & 0xff;
bytes2[i] = (short_ints[j]) ;
j++;
}
for ( i=0; i<size; ++i)
{
if ( bytes1[i] != bytes2[i] )
{
printf("%d-th element is not equal\n", i);
}
}
}
void test1()
{
char bytes1[4] = {-10, 0, 0, 0};
char bytes2[4];
short short_ints[2];
testCore(bytes1, bytes2, short_ints, 4);
}
void test2()
{
char bytes1[4] = {10, 0, 0, 0};
char bytes2[4];
short short_ints[2];
testCore(bytes1, bytes2, short_ints, 4);
}
int main()
{
printf("Calling test1 ...\n");
test1();
printf("Done\n");
printf("Calling test2 ...\n");
test2();
printf("Done\n");
return 0;
}
Output of the program:
Calling test1 ...
1-th element is not equal
Done
Calling test2 ...
Done
Udate
Here's a version of testCore that works for me:
void testCore(char bytes1[],
char bytes2[],
short short_ints[],
int size)
{
int i = 0;
int j = 0;
unsigned char c1;
unsigned char c2;
unsigned short s;
for ( i=0; i<size; i+=2)
{
c1 = bytes1[i];
c2 = bytes1[i+1];
short_ints[j] = (c2 << 8) | c1;
j++;
}
j = 0;
for ( i=0; i<size; i+=2)
{
s = short_ints[j];
s = s >> 8;
bytes2[i+1] = s;
bytes2[i] = short_ints[j] & 0xff;
j++;
}
for ( i=0; i<size; ++i)
{
if ( bytes1[i] != bytes2[i] )
{
printf("%d-th element is not equal\n", i);
}
}
}
It is tested with:
char bytes1[4] = {-10, 0, 25, -4};
and
char bytes1[4] = {10, -2, 25, 4};

Well, what you need is a UNION:
#include <stdio.h>
#include <string.h>
union MyShort {
short short_value;
struct {
char byte1;
char byte2;
};
};
int main(int argc, const char * argv[])
{
char a[4]="abcd";
char b[4]="1234";
short c[5]; c[4]=0;
union MyShort d;
for (int i = 0; i<4; i++) {
d.byte1 = a[i];
d.byte2 = b[i];
c[i] = d.short_value;
}//next i
printf("%s\n", (char*)c);
return 0;
}
the result should be a1b2c3d4.

Related

Bytes of png become corrupted in C

I want to write my own png reader using little help from other libraries. So far, I can read back images with only one IDAT chunk perfectly well. However, when I need to concatenate multiple chunks, the file ends up corrupted. Here is an example of one:
I have a lot of code, so I'm going to try and get it to as 'minimum reproducable example' as I can get, but this along with the fact I do not know specifically what part is causing it, is going to make it a bit longer than I'm sure some of you might like, and I'm sorry.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
unsigned char IEND_CHUNK[4] = {'I', 'E', 'N', 'D'}; //Indicates End Of File
unsigned char IDAT_CHUNK[4] = {'I', 'D', 'A', 'T'}; //Holds Pixel Information
typedef struct Chunk Chunk;
typedef struct IHDR IHDR;
struct Chunk {
int length;
unsigned char type[4];
unsigned char *data;
unsigned char crc[4];
};
struct IHDR {
int width;
int height;
int bitd;
int colort;
int compm;
int filterm;
int interlacem;
int channels;
int bytesPerPixel;
};
int bytesToInt(unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
return (int) a << 24 | b << 16 | c << 8 | d;
}
int compType(unsigned char *a, unsigned char b[], int len)
{
int equal = 1;
for(int i = 0; i < len; i++) equal = a[i] == b[i] ? equal : 0;
return equal;
}
Chunk* getChunksFromBytes(unsigned char* bytes)
{
int next_seg = 7;
int chunks = 0;
long int size = 1;
Chunk* temp = (Chunk*) malloc(sizeof(Chunk));
while(1){
size += sizeof(Chunk);
temp = realloc(temp, size);
temp[chunks].length = bytesToInt(bytes[next_seg+1], bytes[next_seg+2],
bytes[next_seg+3], bytes[next_seg+4]);
temp[chunks].type[0] = bytes[next_seg+5];
temp[chunks].type[1] = bytes[next_seg+6];
temp[chunks].type[2] = bytes[next_seg+7];
temp[chunks].type[3] = bytes[next_seg+8];
temp[chunks].data = malloc(temp[chunks].length);
if(temp[chunks].length > 0){
memcpy(temp[chunks].data, bytes+next_seg+9, temp[chunks].length);
}
else temp[chunks].data = NULL;
temp[chunks].crc[0] = bytes[next_seg+temp[chunks].length+9];
temp[chunks].crc[1] = bytes[next_seg+temp[chunks].length+10];
temp[chunks].crc[2] = bytes[next_seg+temp[chunks].length+11];
temp[chunks].crc[3] = bytes[next_seg+temp[chunks].length+12];
if(compType(temp[chunks].type, IEND_CHUNK, 4)) break;
next_seg+=temp[chunks].length+12;
chunks++;
}
return temp;
}
IHDR getIHDRFromChunks(Chunk* chunks)
{
IHDR img_info;
int channels[7] = {1, 0, 3, 1, 2, 0, 4};
img_info.width = bytesToInt(chunks[0].data[0], chunks[0].data[1],
chunks[0].data[2], chunks[0].data[3]);
img_info.height = bytesToInt(chunks[0].data[4], chunks[0].data[5],
chunks[0].data[6], chunks[0].data[7]);
img_info.bitd = (int) chunks[0].data[8];
img_info.colort = (int) chunks[0].data[9];
img_info.compm = (int) chunks[0].data[10];
img_info.filterm = (int) chunks[0].data[11];
img_info.interlacem = (int) chunks[0].data[12];
img_info.channels = channels[img_info.colort];
img_info.bytesPerPixel = (int) img_info.channels * (img_info.bitd / 8);
return img_info;
}
unsigned char* getImgFromChunks(Chunk* chunks)
{
int count = 0;
IHDR ihdr_data = getIHDRFromChunks(chunks);
uLongf compressed_size = 0;
uLongf uncompressed_size = (ihdr_data.width*ihdr_data.height*ihdr_data.bytesPerPixel) + ihdr_data.height + 1;
unsigned char* compressed_idat = (unsigned char*) malloc(sizeof(unsigned char)*4);
unsigned char* uncompressed_idat = (unsigned char*) malloc(sizeof(unsigned char)*uncompressed_size);
while(1){
if(compType(chunks[count].type, IEND_CHUNK, 4)) break;
else if (compType(chunks[count].type, IDAT_CHUNK, 4)){
compressed_size += sizeof(unsigned char)*chunks[count].length;
compressed_idat = realloc(compressed_idat, compressed_size);
memcpy(compressed_idat + compressed_size - chunks[count].length, chunks[count].data, chunks[count].length);
}
count++;
}
int ret = uncompress(uncompressed_idat, &uncompressed_size, compressed_idat, compressed_size);
free(compressed_idat);
return ret == 0 ? uncompressed_idat : '\0';
}
int PaethPredictor(int a, int b, int c)
{
int pa = abs(b - c);
int pb = abs(a - c);
int pc = abs(a + b - (2*c));
if(pa <= pb && pa <= pc) return a;
else if(pb <= pc) return b;
return c;
}
int* getPixelsFromImg(unsigned char* img, IHDR ihdr_info)
{
int* pixels = (int*) malloc(sizeof(int)*ihdr_info.width*ihdr_info.height*ihdr_info.bytesPerPixel);
int filter_type;
int i = 0;
int current_pixel = 0;
int stride = ihdr_info.width * ihdr_info.bytesPerPixel;
int filt_a;
int filt_b;
int filt_c;
for(int r = 0; r < ihdr_info.height; r++){
filter_type = img[i];
i++;
for(int c = 0; c < stride; c++){
filt_a = c >= ihdr_info.bytesPerPixel ? pixels[r * stride + c - ihdr_info.bytesPerPixel] : 0;
filt_b = r > 0 ? pixels[(r - 1) * stride + c] : 0;
filt_c = r > 0 && c >= ihdr_info.bytesPerPixel ? pixels[(r - 1) * stride + c - ihdr_info.bytesPerPixel] : 0;
switch(filter_type){
case 0:
pixels[current_pixel] = img[i] & 0xff;
break;
case 1:
pixels[current_pixel] = (img[i] + filt_a) & 0xff;
break;
case 2:
pixels[current_pixel] = (img[i] + filt_b) & 0xff;
break;
case 3:
pixels[current_pixel] = (img[i] + filt_a + filt_c) & 0xff;
break;
case 4:
pixels[current_pixel] = (img[i] + PaethPredictor(filt_a, filt_b, filt_c)) & 0xff;
break;
}
current_pixel++;
i++;
}
}
return pixels;
}
These are the combinations of funtcions i use to achieve this. I first use a separate function which I know is not the problem and have therefore left out to get the bytes of the png file. I then call getChunksFromBytes() to gather the chunks of the png file, and I separate the IHDR from these chunks into a separate struct. Finally, I call getImgFromChunks() to uncompress the IDAT data, and getPixelsFromImg() to unfilter the uncompressed values.
First off, bytes per pixel is not a thing since pixels can be bits packed into bytes. So your calculation of uncompressed_size in getImgFromChunks() is wrong. It should be:
uLongf uncompressed_size = ihdr_data.height *
(1 + ((ihdr_data.bitd * ihdr_data.channels * (uLongf)ihdr_data.width + 7) >> 3));
Given that bits per pixel is not a thing, you need to rethink how you are doing getPixelsFromImg(). So there's no point in digging further here until you do that.
There is nothing wrong with your processing of multiple IDAT chunks. You may have misidentified the salient difference of the png file that is giving you issues.

Why does the array contain values which I did not specify?

I'm trying to make a program which crosses binary numbers. The problem is with the cross function. It accepts two binary sequences and returns 5 sequences which are the result of crossing the arguments. Somewhy, the first of these sequences has a mess of values, and I cannot really solve this problem. Does anyone have any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define BINARY_LEN 5
#define POPULATION 5
// #define CROSS_BINARY_LIMIT 3
unsigned randrange(unsigned lower, unsigned upper)
{
return lower + rand() / (RAND_MAX / (upper - lower + 1) + 1);
}
unsigned char *int_to_bin(unsigned number)
{
unsigned char *binary = malloc(BINARY_LEN);
unsigned count = 0;
while (number > 0)
{
binary[count] = number % 2;
number /= 2;
count++;
}
return binary;
}
unsigned char **cross(unsigned char *parent_1, unsigned char *parent_2)
{
unsigned char **offspring = malloc(POPULATION);
unsigned cross_binary_point;
for (unsigned char i = 0; i < POPULATION; i++)
{
cross_binary_point = randrange(0, BINARY_LEN);
offspring[i] = malloc(BINARY_LEN);
for (unsigned char j = 0; j < BINARY_LEN; j++)
{
if (j < cross_binary_point)
{
offspring[i][j] = parent_1[j];
}
else
{
offspring[i][j] = parent_2[j];
}
}
}
return offspring;
}
int main(void)
{
unsigned char *x = int_to_bin(14);
unsigned char *y = int_to_bin(18);
for (unsigned char i = BINARY_LEN; i > 0; i--)
{
printf("%hhu", x[i - 1]);
}
printf("\n");
for (unsigned char i = BINARY_LEN; i > 0; i--)
{
printf("%hhu", y[i - 1]);
}
printf("\n\n");
unsigned char **ofspr = cross(x, y);
printf("%s\n", ofspr[0]); // Try to check out what's wrong with the first array
for (unsigned char i = 0; i < POPULATION; i++)
{
for (unsigned char j = BINARY_LEN; j > 0; j--)
{
printf("%hhu", ofspr[i][j]);
}
printf("\n");
}
free(ofspr);
free(x);
free(y);
}
The output is like this:
01110
10010
`w;
00059119
01011
01001
01111
01011
Maybe there is some memory conflict stuff, but I do not have any ideas
unsigned char **offspring = malloc(POPULATION);
only allocates 5 bytes, you want 5 pointers
should be
unsigned char **offspring = malloc(POPULATION * sizeof(char*));

How to vectorize and optimize this functions in C?

I have this functions, the result is correct but the compiler don't vectorize this.
How can I achive that the compiler vectorize this and how can I optimize this codes?
void LongNumSet( char *L, unsigned N, char digit )
{
for (int i = 0; i < N; ++i){
L[i] = digit;
}
}
void LongNumCopy( char *Vin, char *Vout, unsigned N )
{
for ( int i=0; i< N; ++i )
{
Vout[i] = Vin[i];
}
}
char LongNumAddition( char *__restrict Vin1, char * __restrict Vin2, char * __restrict Vout, unsigned N )
{
char CARRY = 0,R,aux;
Vin1 = (char*)__builtin_assume_aligned (Vin1, 1);
Vin2 = (char*)__builtin_assume_aligned (Vin2, 1);
for ( int i=0; i< N; ++i )
{
char R = Vin1[i] + Vin2[i] + CARRY;
aux = R <= 9;
Vout[i] = (aux) ? R:R-ten;
CARRY = (aux) ? 0:1;
}
return CARRY;
}
char LongNumAddDigit( char *V, char digit, unsigned N )
{
int i=0;
char R = V[0] + digit;
if ( R < ten){
V[0] = R;
return 0;
}
V[0] = R-ten;
// add carry, maybe iteratively for all digits
char CARRY = 1;
i = 1;
while ( CARRY && i < N )
{
if ( V[i] < 9 )
{
V[i]++;
CARRY = 0;
}
else
{
V[i] = 0;
i++; // CARRY remains set to 1
}
}
return CARRY;
}
I use the comand gcc -O3 -ffast-math -msse -funroll-all-loops -ftree-vectorizer-verbose=25 -lm -g $1 -o ${2}.O3 and I executate the program in 55 s.
This is all of code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// Variable used to generate pseudo-random numbers
unsigned int seed;
unsigned int temp;
unsigned int var1 = 214013;
unsigned int var2 = 2531011;
#define val13 13
#define ten 10
// Function to generate pseudo-random numbers
inline int myRandom() {
temp = var1*seed;
seed = temp + var2;
return (seed>>val13);
}
void LongNumInit( char *L, unsigned N )
{
for ( int i=0; i<N;++i )
{
L[i] = myRandom() % ten; // digito decimal
}
}
void LongNumPrint( char *L, unsigned N, char *Name )
{
printf("%s:", Name);
for ( int i=N; i>0; i-- )
{
printf("%d", L[i-1]);
}
printf("\n");
}
void LongNumSet( char *L, unsigned N, char digit )
{
for (int i = 0; i < N; ++i){
L[i] = digit;
}
}
void LongNumCopy( char *Vin, char *Vout, unsigned N )
{
for ( int i=0; i< N; ++i )
{
Vout[i] = Vin[i];
}
}
char LongNumAddition( char *__restrict Vin1, char * __restrict Vin2, char * __restrict Vout, unsigned N )
{
char CARRY = 0,R,aux;
Vin1 = (char*)__builtin_assume_aligned (Vin1, 1);
Vin2 = (char*)__builtin_assume_aligned (Vin2, 1);
for ( int i=0; i< N; ++i )
{
char R = Vin1[i] + Vin2[i] + CARRY;
aux = R <= 9;
Vout[i] = (aux) ? R:R-ten;
CARRY = (aux) ? 0:1;
}
return CARRY;
}
char LongNumAddDigit( char *V, char digit, unsigned N )
{
int i=0;
char R = V[0] + digit;
if ( R < ten){
V[0] = R;
return 0;
}
V[0] = R-ten;
// add carry, maybe iteratively for all digits
char CARRY = 1;
i = 1;
while ( CARRY && i < N )
{
if ( V[i] < 9 )
{
V[i]++;
CARRY = 0;
}
else
{
V[i] = 0;
i++; // CARRY remains set to 1
}
}
return CARRY;
}
char LongNumHorizAdd( char *Vin, char *Vout, unsigned N )
{
char CARRY = 0;
LongNumSet ( Vout, N, 0 );
for ( int i=0; i< N; ++i )
{
LongNumAddDigit ( Vout, Vin[i], N );
}
return 0; // CARRY can never be set
}
char LongNumConstMult( char *V, unsigned N, char digit )
{
char CARRY = 0;
char ja = 0;
for ( int i=0; i< N; ++i )
{
char aux = V[i] * digit;
char R = aux + CARRY;
CARRY = ((u_int32_t)R * (u_int32_t)0xCCCD) >> 19;
ja = (CARRY << 3) + 2*CARRY;
R -= ja;
V[i] = R;
}
return CARRY; // may be from 0 to 9
}
void LongNumMultiply( char *Vin1, char *Vin2, char *VoutH, char *VoutL, unsigned N )
{
// Create Temporal Long Integer with double size
unsigned char *TEMP = (unsigned char*) calloc(2*N,sizeof(unsigned char));
unsigned char *RES = (unsigned char*) calloc( 2*N,sizeof(unsigned char) );
LongNumSet ( RES, 2*N, 0 ); // Set RES to 0
for ( int i=0; i<N; ++i )
{
LongNumSet ( TEMP, 2*N, 0 ); // Set TEMP to 0
LongNumCopy ( Vin1, TEMP+i, N ); // Copy Vin1 -> TEMP, with offset i
LongNumConstMult( TEMP, 2*N, Vin2[i] ); // TEMP * Vin2[i] -> TEMP
LongNumAddition ( TEMP, RES, RES, 2*N ); // TEMP + RES -> RES
}
// Result goes to VoutH-VoutL
LongNumCopy ( RES, VoutL, N ); // Copy RES -> VoutL
LongNumCopy ( RES+N, VoutH, N ); // Copy RES+N -> VoutH
}
int main (int argc, char **argv)
{
int i, sum1, sum2, sum3, N=10000, Rep=50;
seed = 12345;
// obtain parameters at run time
if (argc>1) { N = atoi(argv[1]); }
if (argc>2) { Rep = atoi(argv[2]); }
printf("Challenge #3: Vector size is %d. Repeat %d times\n", N, Rep);
// Create Long Nums
unsigned char *V1= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V2= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V3= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V4= (unsigned char*) malloc( N*sizeof(unsigned char) );
LongNumInit ( V1, N ); LongNumInit ( V2, N ); LongNumInit ( V3, N );
// Repeat
for (i=0; i<Rep; i++)
{
LongNumAddition ( V1, V2, V4, N );
LongNumMultiply ( V3, V4, V2, V1, N );
LongNumHorizAdd ( V1, V2, N );
LongNumAddDigit ( V3, V2[0], N );
}
// Print last 32 digits of Long Numbers
LongNumPrint( V1, 32, "V1" );
LongNumPrint( V2, 32, "V2" );
LongNumPrint( V3, 32, "V3" );
LongNumPrint( V4, 32, "V4" );
free(V1); free(V2); free(V3); free(V4);
return 0;
}
Acording to your usage, instead of LongNumSet you could create and use LongNumClear(not much improvement).
Below are some other potential rewrites of some of your functions. I think you should notice some improvements. For me it's around 44%. I also changed the type from char to unsigned.
#include <string.h>
void LongNumClear(uint8_t *L, size_t N) {
memset (L, 0, N);
}
void LongNumCopy(const uint8_t *Vin, uint8_t *Vout, size_t N) {
memcpy(Vout, Vin, N);
}
uint8_t LongNumAddition(uint8_t * Vin1, uint8_t * Vin2, uint8_t * Vout, size_t N) {
uint8_t carry = 0;
for (size_t i=0; i < N; ++i) {
Vout[i] = Vin1[i] + Vin2[i] + carry;
carry = (Vout[i] > 9);
if (carry) {
Vout[i] -= ten;
}
}
return carry;
}
uint8_t LongNumAddDigit(uint8_t *V, uint8_t digit, size_t N) {
size_t i=0;
V[0] += digit;
if (V[0] < ten) {
return 0;
}
V[0] -= ten;
while ((++i < N) && (V[i] >= 9)) {
V[i] = 0;
}
if ((i != N) && (V[i] < 9)) {
V[i]++;
return 0;
}
return 1;
}
uint8_t LongNumConstMult(uint8_t *V, size_t N, uint8_t digit) {
uint8_t carry = 0;
for (size_t i = 0; i < N; ++i ) {
V[i] = V[i] * digit + carry;
carry = ((u_int32_t)V[i] * (u_int32_t)0xCCCD) >> 19; // divide by 10
V[i] -= ((carry << 3) + (carry << 1));
}
return carry;
}

C: Best way to index the digits in an integer

If I have an
int i = 11110001
How would I be able to convert this int into an int array where
int array[8] = {1, 1, 1, 1, 0, 0, 0, 1}
Using a little different approach and snprintf:
#include <stdio.h>
int main (void) {
int i = 11110001;
char arr[9]; //8 digits + \0
int array[8];
if ((snprintf(arr,9,"%d", i) == 8) { //return the 8 characters that were printed
int c;
for(c = 0; c < 8; c++)
array[c] = arr[c] - '0';
}
return 0;
}
P.S: I'm assuming positive values only
You may try like this:
#include <math.h>
char * convertNumber(unsigned int i) {
/* unsigned int length = (int)(log10((float)i)) + 1; */
/* char * arr = (char *) malloc(length * sizeof(char)), * x = arr; */
char * arr = malloc(8);
char * x = arr;
do
{
*x++ = i% 10;
i/= 10;
} while (i != 0);
return arr;
}
Try this :
#include<stdio.h>
void convert_int_to_array(unsigned int);
int main()
{
unsigned int a = 12345678;
convert_int_to_array(a);
return 0;
}
void convert_int_to_array(unsigned int a)
{
int array[25]; // array large enough for an integer
int i = 0, count = 0;
unsigned int num = a;
memset(array, '\0', 20); // I've not included the header file for this.
// gives a warning on compilation.
while(num > 0)
{
array[i] = num % 10;
num = num / 10;
++i;
++count;
}
for(i = count; i>=0;--i)
{
printf("array[%d] = %d\n",i, array[i]);
// or
printf("%d", array[i]);
// dont use both the printf statements, else you will see a
// messed up output.
}
}
BINARY REPRESENTATION :
#include<stdio.h>
struct bit
{
int a : 1;
};
int main()
{
struct bit b;
int d ,f,i;
d=f=256; // take any number of your choice
printf("binary representation of 256:\n");
for(i = 15; i>=0 ; i--) //assuming that the number wont have more than
// 15 DIGITS
{
f=f>>i;
b.a = f;
//d= d>>1;
f=d;
printf("%d",b.a);
}
return 0;
}

Converting 4 bytes to unsigned int

If one has a character array such as
char bytes[256] = "10000011011110110010001101000011";
I want to unsigned value of this which would be : 2205885251
I'm trying to do something along these lines
unsigned int arr[256];
for(int i = 0, k=0; i<256; i++, k++)
{
arr[k] = bytes[i]|bytes[i+1]<<8|bytes[i+2]<<16|bytes[i+3]<<24;
}
I am obtaining the wrong value: 3220856520, can anyone point out what I am doing wrong?
#include <stdio.h>
char bytes[256] = "10000011011110110010001101000011";
int main(void)
{
unsigned int out;
int i;
for (out = 0, i = 0; i < 32; ++i)
if (bytes[31 - i] == '1')
out |= (1u << i);
printf("%u\n", out);
return 0;
}
Output is:
2205885251
#include <stdio.h>
int main()
{
char bytes[256] = "10000011011110110010001101000011";
unsigned int value = 0;
for(int i = 0; i< 32; i++)
{
value = value *2 + (bytes[i]-'0');
}
printf("%u\n",value);
}
it outputs: 2205885251
char bytes[] = "10000011011110110010001101000011";
unsigned int k;
k = strtoul(bytes, NULL, 2);
printf("%u \n", k);
valter

Resources