So I have this code
char str[80] = "192.168.12.142";
char string[80];
char s[2] = ".";
char *token;
int val[4];
int counter=0;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ){
val[counter] = atoi(token);
token = strtok(NULL, s);
counter++;
}
sprintf(string,"%d.%d.%d.%d",val[0],val[1],val[2],val[3]);
puts(string);
Instead of concatenate it into an string, I want to concatenate it to an int concatenation, is there any possibly alternative?
First of all, what you seem to do is exactly what inet_aton is doing. You might consider using this function.
Regarding the concatenation you can write
int result = (val[3] << 24) | (val[2] << 16) | (val[1] << 8) | (val[0]);
or, for the opposite byte order:
int result = (val[0] << 24) | (val[1] << 16) | (val[2] << 8) | (val[3]);
You probably want
(((((val[0] << 8) + val[1]) << 8) + val[2]) << 8 ) + val[3]
Or equivalently
(val[0] << 24) | (val[1] << 16) | (val[2] << 8) | val[0]
Related
I am new to bits, I am trying to get 64 bit value send using UDP.
int plugin(unsigned char *Buffer) {
static const uint8_t max_byte = 0xFF;
uint8_t id[8];
id[0] = (uint8_t)((Buffer[0]) & max_byte);
id[1] = (uint8_t)((Buffer[1] >> 8) & max_byte);
id[2] = (uint8_t)((Buffer[2] >> 16) & max_byte);
id[3] = (uint8_t)((Buffer[3] >> 24) & max_byte);
id[4] = (uint8_t)((Buffer[4] >> 32) & max_byte);
id[5] = (uint8_t)((Buffer[5] >> 40) & max_byte);
id[6] = (uint8_t)((Buffer[6] >> 48) & max_byte);
id[7] = (uint8_t)((Buffer[7] >> 56) & max_byte);
}
I am getting error right shift count >= width of type. I tried other way aswell
int plugin(unsigned char *Buffer) {
uint64_t id = (Buffer[0] | Buffer[1] << 8 | Buffer[2] << 16 | Buffer[3] << 24 | Buffer[4] < 32 | Buffer[5] << 40 | Buffer[6] << 48 | Buffer[7] << 56);
printf("ID %" PRIu64 "\n", id);
}
Its getting error left shift count >= width of type
I checked the system it is x86_64. Could someone please tell me the reason why its happening? Please suggest me a way forward.
This happens because of default integer promotion, basically.
When you do this:
uint64_t id = Buffer[7] << 56;
That Buffer[7] is an unsigned char, but it gets promoted to int in the arithmetic expression, and your int is not 64 bits. The type of the left hand side does not automatically "infect" the right hand side, that's just not how C works.
You need to cast:
const uint64_t id = ((uint64_t) Buffer[7]) << 56;
and so on.
I have the following:
payload.data[i].data = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11]);
note: payload.data[i].dataif of type float.
Using this: printf("test:%X%X%X%X", buf[8], buf[9], buf[10], buf[11]);, I have confirmed that the buffer contains #42C78A3D or DEC 99.77 (roughly).
This: printf("Float value:%f", payload.data[i].data prints out 1120373248.00, which is DEC for #42C78A00
It seems to me that for some reason, buf[11] is coming up empty.
Here is a more complete view of my code:
int i = 0;
int j = 0;
struct sensor_payload payload;
payload.key = (buf[0] << 8) | buf[1];
payload.id = (buf[2] << 8) | buf[3];
payload.type = (buf[4] << 8) | buf[5];
payload.fields = buf[6];
for(i = 0, j = 0; i < payload.fields; i++, j = j +33){
payload.data[i].data_type = buf[j+7];
payload.data[i].data = (buf[j+8] << 24) | (buf[j+9] << 16) | (buf[j+10] << 8) | (buf[j+11]);
slog(0, SLOG_DEBUG, "test:%X%X%X%X", buf[8], buf[9], buf[10], buf[11]);
}
payload.valid = true;
return payload;
and the definitions:
struct sensor_data{
uint8_t data_type;
float data;
};
struct sensor_payload{
uint16_t key, id, type;
uint8_t fields;
struct sensor_data data[4];
bool valid;
};
There's a lot in you code which is unclear. However, the only discrepancy I see is that you're putting index-offset entries into your data (notice the j+x pattern):
(buf[j+8] << 24) | (buf[j+9] << 16) | (buf[j+10] << 8) | (buf[j+11])
while printing non-offset entires:
slog(0, SLOG_DEBUG, "test:%X%X%X%X", buf[8], buf[9], buf[10], buf[11])
Technically, data you're printing and putting into the float is only the same for i==0.
i have a byte array (64-bit unsigned integer) :
byte array[8] = { 0x01,0xc9,0x98,0x57,0xd1,0x47,0xf3,0x60 }
i want to translate it into decimal..
when i'am using the calculator windows the result is :
128801567297500000
i don't find a way to do it in winapi or C ..
Any help is appreciated.
for a 4 bytes array i use the working code below
BYTE array[4] = { 0xC3,0x02,0x00,0x00 };
printf("Result : %d\n",(array[0]) | (array[1]) <<8 |(array[2]) <<16 | (array[3]) <<24 );
Result : 707
Cast the bytes to 64bit before the shifting. Currently they are implicitly promoted to int, which is a 32bit data type.
Assuming you use stdint:
uint64_t result = ((uint64_t)b[0]) | ((uint64_t)b[1] << 8) | ((uint64_t)b[2] << 16) | ((uint64_t)b[3] << 24) | ((uint64_t)b[4] << 32) | ((uint64_t)b[5] << 40) | ((uint64_t)b[6] << 48) | ((uint64_t)b[7] << 56);
or in reverse order (array is little endian; this will get the result you're seeing in windows calculator):
uint64_t result = ((uint64_t)b[7]) | ((uint64_t)b[6] << 8) | ((uint64_t)b[5] << 16) | ((uint64_t)b[4] << 24) | ((uint64_t)b[3] << 32) | ((uint64_t)b[2] << 40) | ((uint64_t)b[1] << 48) | ((uint64_t)b[0] << 56);
well, you can use
sprintf() to print the positional hex values to a string.
convert that string to decimal using strtoll() using base 16.
Sample code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 128
int main()
{
char array[8] = { 0x01,0xc9,0x98,0x57,0xd1,0x47,0xf3,0x60 };
char arr[SIZE] = {0};
int i = 0;
unsigned long long res = 0;
for (i = 0; i < 8; i++)
sprintf((arr + (i * 2)), "%2x", (array[i] & 0xff));
printf("arr is %s\n", arr);
res = strtoll(arr, NULL, 16);
printf("res is %llu\n", res);
return 0;
}
int i;
byte array[8] = { 0x01,0xc9,0x98,0x57,0xd1,0x47,0xf3,0x60 };
unsigned long long v;
//Change of endian
for(i=0;i<4;++i){
byte temp = array[i];
array[i] = array[7-i];
array[7-i] = temp;
}
v = memcpy(&v, array, sizeof(v));//*(unsigned long long*)array;
printf("%llu ", v);
So I'm making a hash code function for this algorithm:
For each character rotated the current bit three bits left
add the value of each character,
xor the results with the current
Here's the code I have so far:
unsigned int hash_function(const char *k){
unsigned int current = 0;
unsigned int rot = 0;
int i = 0;
int r = 0;
for(i = 0; i < strlen(k); i++){
for(r = 0; r < 3; r++){
rot = ((rot & 1 (1 << 31)) >> 31 | (rot << 1);
}
rot += k[i];
current ^= rot;
rot = current;
}
return current;
}
Some examples that the algorithm should give
"gimme" = 477003,
"shelter" = 41540041
However, this algorithm isn't giving me the correct results. I'm fairly certain I'm using the correct rotation operations and then I follow the algorithm as it is. I'm wondering if anybody can point me in the correct direction.
Thanks, and hopefully I formatted this question correctly
I think you meant to put rot = ((rot & (1 << 31)) >> 31) | (rot << 1);. But the loop is unnecessary — use rot = ((rot & (7 << 29)) >> 29) | (rot << 3); instead.
This should work:
unsigned int hash_function(const char *k){
unsigned int current = 0;
unsigned int rot = 0;
int i = 0;
for (i = 0; i < strlen(k); i++){
rot = ((rot & (7 << 29)) >> 29) | (rot << 3);
rot += k[i];
current ^= rot;
rot = current;
}
return current;
}
This was initially just a comment, but it turns out that it's the answer to your question.
On this line:
rot = ((rot & 1 (1 << 31)) >> 31 | (rot << 1);
You have an extra 1 and an extra (, which prevent it from compiling on gcc:
main.c: In function ‘hash_function’:
main.c:11:29: error: called object is not a function or function pointer
rot = ((rot & 1 (1 << 31)) >> 31 | (rot << 1);
^
main.c:11:58: error: expected ‘)’ before ‘;’ token
rot = ((rot & 1 (1 << 31)) >> 31 | (rot << 1);
^
main.c:12:9: error: expected ‘;’ before ‘}’ token
}
^
Remove those two things:
rot = (rot & (1 << 31)) >> 31 | (rot << 1);
And it works.
In the future, you may want to find a compiler which can detect errors like this. I'm actually surprised that yours didn't.
How do I go about avoiding the compiler warning (warning: cast increases required alignment of target type) in the following code?
static int fill_color24 (VisVideo *video, VisColor *color)
{
int x, y;
uint32_t *buf;
uint8_t *rbuf = visual_video_get_pixels (video);
uint8_t *buf8;
int32_t cola =
(color->b << 24) |
(color->g << 16) |
(color->r << 8) |
(color->b);
int32_t colb =
(color->g << 24) |
(color->r << 16) |
(color->b << 8) |
(color->g);
int32_t colc =
(color->r << 24) |
(color->b << 16) |
(color->g << 8) |
(color->r);
for (y = 0; y < video->height; y++) {
buf = (uint32_t *) rbuf; // warning is for this line
for (x = video->width; x >= video->bpp; x -= video->bpp) {
*(buf++) = cola;
*(buf++) = colb;
*(buf++) = colc;
}
buf8 = (uint8_t *) buf;
*(buf8++) = color->b;
*(buf8++) = color->g;
*(buf8++) = color->r;
rbuf += video->pitch;
}
return VISUAL_OK;
}
I'm not sure you can. That function might return color array unaligned. You can't do anything to be able to read word from there.
You will have to read color by components (uint8_t) and then construct uint32_t from these by adding and shifting.