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
Related
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*));
I'm having trouble with one final task that my program should do.
Having my output character in a lexicographic order.
For example, if I input bbbaaa it should have an output of
Frequencies:
a 3
b 3
Not
Frequencies:
b 3
a 3
Can anyone help me solve this problem?
Here is my code:
#include <iostream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;
void sort(char letters[], int integers[], int size);
void swap_letters(char& first, char& second, int& int1, int& int2);
int index_of_largest(const int integers[], int start_index, int number_used);
int main(){
const int MAX_CHARS = 200;
char letters[MAX_CHARS] = {'\0'};
int integers[MAX_CHARS] = {'\0'};
int index, size = 0;
char character;
cout << "Enter text:" << endl;
cin.get(character);
character = tolower(character);
while (character!= '.' && size < MAX_CHARS){
if(isalpha(character)){
index = 0;
while (index < size){
if(letters[index] == character)
break;
else
index++;
}
if (index < size){
integers[index] = integers[index] + 1;
}
else{
letters[index] = character;
integers[index] = 1;
size++;
}
}
cin.get(character);
character = tolower(character);
}
letters[index] = tolower(letters[index]);
sort(letters, integers, size);
cout << "Frequencies:"<< endl;
for(int i = 0; i < size; i++){
cout << letters[i] << " " << integers[i] << endl;
}
return 0;
}
void sort(char letters[], int integers[], int size){
for (int i = 0; i < size -1; i++){
int j = index_of_largest(integers, i, size);
swap_letters(letters[i], letters[j], integers[i], integers[j]);
}
}
void swap_letters(char& first, char& second, int& int1, int& int2){
char temp_char = first;
first = second;
second = temp_char;
int temp_int = int1;
int1 = int2;
int2 = temp_int;
}
int index_of_largest(const int integers[], int start_index, int number_used){
int max_int = integers[start_index];
int max_int_index = start_index;
for (int index = start_index + 1; index < number_used; index++){
if (integers[index] > max_int){
max_int = integers[index];
max_int_index = index;
}
}
return max_int_index;
}
The problem is in function index_of_largest() where you detect the index of largest checking only integers and ignoring letters.
All goes well when all letters are with different frequencies but doesn't work when a couple two or letter are with the same frequency. In this case you should take in count letters too.
I suppose you can correct the function in this way
int index_of_largest(const int integers[], const char letters[], int start_index, int number_used){
int max_int = integers[start_index];
int max_int_index = start_index;
for (int index = start_index + 1; index < number_used; index++){
if ( (integers[index] > max_int)
|| ( (integers[index] == max_int)
&& (letters[index] < letters[max_int_index]) )){
max_int = integers[index];
max_int_index = index;
}
}
return max_int_index;
}
But I suggest you to follow the Jack's suggestion: use STL container/algorithm when you can / when is possible
p.s.: sorry for my bad English.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int testNums[] = {3, 0x12, 0xFF, -3};
int testBits[] = {9, 7, 12, 15};
int i;
for (i = 0; i < sizeof(testNums) / sizeof(testNums[0]); i++)
printBin(testNums[i], testBits[i]);
}
void printBin(int num, int bits)
{
int pow;
int mask = 1 << bits - 1;
for(pow=0; pow<bits; pow++)
{
if(mask & num)
printf("1");
else
printf("0");
num<<1;
}
printf("\n");
}
It doesn't print out the correct binary number, but has the right amount of bits, and advice on how I can fix this?
Your problem is here, in printBin:
num<<1;
This statement does nothing. What you want is:
num<<=1;
For clarity, you should also use parenthesis here:
int mask = 1 << (bits - 1);
And you should move printBin above main so the definition is visible at the time the function is called.
Finally, main should always return int.
There are several issues in your code:
You need a prototype for printBin().
Use int main(void) or int main(int argc, char** argv) instead of void main().
num<<1; is an expression that has no side effects. Perhaps you are able infer this from compiler's warning. Write num<<=1; to make a difference.
Only a suggestion: Why not replace the if statement with printf("%d", !!(mask & num));?
Here is the fixed code that compiles without warnings using clang:
#include <stdio.h>
#include <stdlib.h>
void printBin(int num, int bits);
int main(void)
{
int testNums[] = {3, 0x12, 0xFF, -3};
int testBits[] = {9, 7, 12, 15};
int i;
for (i = 0; i < sizeof testNums / sizeof testNums[0]; i++)
printBin(testNums[i], testBits[i]);
return 0;
}
void printBin(int num, int bits)
{
int pow;
int mask = 1 << (bits - 1);
for(pow=0; pow<bits; pow++)
{
printf("%d", mask & num);
num <<= 1;
}
putchar('\n');
}
Output:
000000011
0010010
000011111111
111111111111101
Although your approach is conventional and #dbush's answer is appropriate, I would like like to mention another approach. You may know this and it doesn't handle the negative values very well but in this approach, you can convert number of any base into other very easily
#include <stdio.h>
#include <string.h>
#define RESOLUTION 128
void compute(int number, int base, char* placeHolder){
int k = 0;
int i, j;
char temp;
while(number){
placeHolder[k++] = "0123456789ABCDEF"[number % base];
number /= base;
}
if (k != 0) {
placeHolder[k] = '\0';
for(i = 0, j = strlen(placeHolder) - 1; i < j; i++, j--){
temp = placeHolder[i];
placeHolder[i] = placeHolder[j];
placeHolder[j] = temp;
}
}else{
placeHolder[0] = '0';
placeHolder[1] = '\0';
}
}
int main(void) {
char bin[RESOLUTION];
compute(0xFF, 10, bin);
printf("%s\n", bin);
return 0;
}
Change the RESOLUTION value at you will.
More specific to binary, you can print binary of any datatype like this
void printBits(size_t const size, void const * const ptr)
{
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;
for (i=size-1;i>=0;i--)
{
for (j=7;j>=0;j--)
{
byte = b[i] & (1<<j);
byte >>= j;
printf("%u", byte);
}
}
puts("");
}
int main()
{
int i = 23;
uint ui = UINT_MAX;
float f = 23.45f;
printBits(sizeof(i), &i);
printBits(sizeof(ui), &ui);
printBits(sizeof(f), &f);
return 0;
}
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;
}
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.