Last active
December 19, 2015 07:09
-
-
Save BohuTANG/5916727 to your computer and use it in GitHub Desktop.
Fixed: from buffer to uint64_t with big-endian sign extension bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Such as num is:12345678910, 'from_big1' funcation will be wrong | |
* since the sign extension: 'cltq' instruction will full fill upper 32 bits with 0xffffffff | |
*/ | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <inttypes.h> | |
void to_big(unsigned char *buf, uint64_t v) | |
{ | |
buf[0] = (v >> 56) & 0xff; | |
buf[1] = (v >> 48) & 0xff; | |
buf[2] = (v >> 40) & 0xff; | |
buf[3] = (v >> 32) & 0xff; | |
buf[4] = (v >> 24) & 0xff; | |
buf[5] = (v >> 16) & 0xff; | |
buf[6] = (v >> 8) & 0xff; | |
buf[7] = v & 0xff; | |
} | |
uint64_t from_big1(unsigned char *buf) | |
{ | |
uint64_t val = 0; | |
val |= (uint64_t) buf[0] << 56; | |
val |= (uint64_t) buf[1] << 48; | |
val |= (uint64_t) buf[2] << 40; | |
val |= (uint64_t) buf[3] << 32; | |
val |= buf[4] << 24; | |
val |= buf[5] << 16; | |
val |= buf[6] << 8; | |
val |= buf[7]; | |
return val; | |
} | |
/* | |
* this is OK | |
*/ | |
uint64_t from_big2(unsigned char *buf) | |
{ | |
uint64_t val = 0; | |
val = buf[0]; | |
val = (val<<8) | buf[1]; | |
val = (val<<8) | buf[2]; | |
val = (val<<8) | buf[3]; | |
val = (val<<8) | buf[4]; | |
val = (val<<8) | buf[5]; | |
val = (val<<8) | buf[6]; | |
val = (val<<8) | buf[7]; | |
return val; | |
} | |
/* | |
* this is OK | |
*/ | |
uint64_t from_big3(unsigned char *buf) | |
{ | |
uint64_t val = 0; | |
val |= (uint64_t) buf[0] << 56; | |
val |= (uint64_t) buf[1] << 48; | |
val |= (uint64_t) buf[2] << 40; | |
val |= (uint64_t) buf[3] << 32; | |
val |= (uint64_t) buf[4] << 24; | |
val |= (uint64_t) buf[5] << 16; | |
val |= (uint64_t) buf[6] << 8; | |
val |= (uint64_t) buf[7]; | |
return val; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 3) { | |
printf("./xx [num] [method:1 or 2]"); | |
return -1; | |
} | |
uint64_t v1, v2; | |
unsigned char xx[8]; | |
int method = atoi(argv[2]); | |
v1 = strtoull(argv[1], NULL, 0); | |
to_big(xx, v1); | |
switch (method) { | |
case 1: | |
v2 = from_big1(xx); | |
break; | |
case 2: | |
v2 = from_big2(xx); | |
break; | |
case 3: | |
v2 = from_big3(xx); | |
break; | |
default:break; | |
} | |
printf("v2 is %" PRIu64 "\n", v2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment