64,681
社区成员
发帖
与我相关
我的任务
分享
#include <cstdio> //printf
#include <cstring> //memset
typedef unsigned char byte_t;
const int BIT_NUM = 8; // bit number of one byte.
/*
从下标为@start的开始位置输出字节@byte的@num数量的标记(1/0)
(01234567)
例如: @byte: 00101001
@start: 1
@num: 4
输出: 0101
*/
int print_byte_bits(byte_t byte, int start, int num)
{
int i,n;
if(start < 0) start = 0;
if(num - start > BIT_NUM) num = BIT_NUM - start;
n = 0;
for(i=start; i < BIT_NUM && n < num; i++)
{
printf("%d",((byte & (0x80>>i)) ? 1 : 0)); //0x80: 1000 0000b
n++;
}
return n;
}
/*
从下标为@start的开始位置输出任意位置@addr的@num数量的标记(1/0)
(0123456789012345)
例如: @addr: 0010100100011010
^^^^^^^
@start: 5
@num: 7
输出: 0010001
*/
int print_bits(const void* addr, int start, int num)
{
int ibyte,ibit,n,temp;
byte_t byte;
if(start < 0) start = 0;
n = 0;
for(ibyte = start / BIT_NUM, ibit = start % BIT_NUM; n < num; ibyte++)
{
byte = ((byte_t*)addr)[ibyte];
temp = print_byte_bits(byte, ibit, num - n);
if(temp == 0) break;
n += temp;
ibit = 0;
}
return n;
}
//检测当前系统是否为“大端”字节序
/*bool*/int bigendian()
{
const unsigned short s = 0x0201;
struct S{ byte_t b1,b2; }* p = (struct S*)&s;
// struct: b1 b2
// big: [0x02 0x01]
// little: [0x01 0x02]
return p->b1 > p->b2;
}
/*
按字节反转从@p指定位置开始@len指定长度的内容
例如: @p: 0x [01 02 03 04] 05 06
@len: 4
反转后: 0x [04 03 02 01] 05 06
*/
void reverse(void* p, int len)
{
int i;
byte_t t;
byte_t* byte = (byte_t*)p;
for(i = 0; i < len/2; i++)
{
t = byte[i];
byte[i] = byte[(len-1)-i];
byte[(len-1)-i] = t;
}
}
//测试1:输出int类型的位(bits)
void t1()
{
int i = 0x01020304;
size_t j;
printf("int 0x%08x: ",i);
if(!bigendian())
reverse(&i,sizeof(i));
for(j=0; j<sizeof(i); j++)
{
print_bits(&i,j*BIT_NUM,BIT_NUM);
printf(" ");
}
printf("\n");
//output: 00000001 00000010 00000011 00000100
}
//测试2:输出float类型的位
// float: [1:sign][8:exponent][23:mantissa]
typedef struct _Float
{
int mantissa:23;
int exponent:8;
int sign:1;
} Float;
void t2()
{
float f = 8.25; //: 8.25(10) = 1000.01(2) = 1.00001 * 2^3
printf("float %f: ",f);
if(!bigendian())
reverse(&f,sizeof(f));
print_bits(&f,0,1);
printf(" ");
print_bits(&f,1,8);
printf(" ");
print_bits(&f,9,23);
printf("\n");
//output: 0 10000010 00001000000000000000000
// / ^^^^^
// 127+3 0.00001
// //
// 127(10) = 11111111(2)
}
//测试3:输出double类型的位
// double: [1:sign][11:exponent][52:mantissa]
#pragma pack(push)
#pragma pack(1)
typedef struct _Double
{
long long mantissa:52; //long long -> 64 bits
int exponent:11;
int sign:1;
} Double;
#pragma pack(pop)
void t3()
{
double f = 8.25;
printf("double %f: ",f);
if(!bigendian())
reverse(&f,sizeof(f));
print_bits(&f,0,1);
printf(" ");
print_bits(&f,1,11);
printf(" ");
print_bits(&f,12,52);
printf("\n");
//output: 0 10000000010 0000100000000000000000000000000000000000000000000000
}
//模版:输出任意类型的位
template<typename T>
void print(T d)
{
if(!bigendian()) reverse(&d,sizeof(d));
for(size_t i=0; i<sizeof(d); i++)
{
print_bits(&d,i*BIT_NUM,BIT_NUM);
printf(" ");
}
printf("\n");
}
//测试4:输出自定义类型的大小
void t4()
{
printf("Float:%d, Double:%d\n",sizeof(Float),sizeof(Double));
}
//测试5:查看float类型各个"区段"的位置
void t5()
{
Float f;
memset(&f,0,sizeof(f));
f.sign = -1;
printf("s i g n:"); print(f);
memset(&f,0,sizeof(f));
f.exponent = -1;
printf("exponent:"); print(f);
memset(&f,0,sizeof(f));
f.mantissa = -1;
printf("mantissa:"); print(f);
}
//测试6:查看double类型各个"区段"的位置
void t6()
{
Double d;
memset(&d,0,sizeof(d));
d.sign = -1;
printf("s i g n:"); print(d);
memset(&d,0,sizeof(d));
d.exponent = -1;
printf("exponent:"); print(d);
memset(&d,0,sizeof(d));
d.mantissa = -1;
printf("mantissa:"); print(d);
}
//测试7:通过自定义类型"构造"一个float类型的小数
void t7()
{
Float f;
memset(&f,0,sizeof(f));
// 1.00001(2) * 2^3 = 8.25(10)
f.sign = 0;
f.exponent = 127+3; //:3
f.mantissa = 0x040000;//:.00001 -> 0000100 00000000 00000000
float* p = (float*)&f;
printf("Float(0,130,0x040000):\n");
printf("(2): ");print(f);
printf("(10): %f\n",*p);
}
int main()
{
printf("测试1:输出int类型的位(bits)\n"); t1();
printf("测试2:输出float类型的位\n"); t2();
printf("测试3:输出double类型的位\n"); t3();
printf("测试4:输出自定义类型的大小\n"); t4();
printf("测试5:查看float类型各个'区段'的位置\n"); t5();
printf("测试6:查看double类型各个'区段'的位置\n"); t6();
printf("测试7:通过自定义类型'构造'一个float类型的小数\n"); t7();
printf("问题:为什么Double类型和Float类型表现不太一样?预期:sizeof(Float)=4,sizeof(Double)=8.\n");
printf("补充:Float类型正如预期的,大小为4字节;但Double类型却有12字节大小(如果不加pack(1)设置则为16)。\n");
return 0;
}
/*
测试1:输出int类型的位(bits)
int 0x01020304: 00000001 00000010 00000011 00000100
测试2:输出float类型的位
float 8.250000: 0 10000010 00001000000000000000000
测试3:输出double类型的位
double 8.250000: 0 10000000010 0000100000000000000000000000000000000000000000000000
测试4:输出自定义类型的大小
Float:4, Double:12
测试5:查看float类型各个'区段'的位置
s i g n:10000000 00000000 00000000 00000000
exponent:01111111 10000000 00000000 00000000
mantissa:00000000 01111111 11111111 11111111
测试6:查看double类型各个'区段'的位置
s i g n:00000000 00000000 00001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
exponent:00000000 00000000 00000111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
mantissa:00000000 00000000 00000000 00000000 00000000 00001111 11111111 11111111 11111111 11111111 11111111 11111111
测试7:通过自定义类型'构造'一个float类型的小数
Float(0,130,0x040000):
(2): 01000001 00000100 00000000 00000000
(10): 8.250000
问题:为什么Double类型和Float类型表现不太一样?预期:sizeof(Float)=4,sizeof(Double)=8.
补充:Float类型正如预期的,大小为4字节;但Double类型却有12字节大小(如果不加pack(1)设置则为16)。
*/
// 参考文章:
// http://blog.csdn.net/wuna66320/article/details/1691734
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
int main() {
int i,v;
char bs[33];
char b[33];
char hs[9];
char h[9];
char s[4];
char *e;
// 十进制整数转二进制串;
i=1024;
ltoa(i,b,2);
sprintf(bs,"%032s",b);
printf("i=%d,bs=%s\n",i,bs);
// 十进制整数转十六进制串;
i=1024;
ltoa(i,h,16);
sprintf(hs,"%08s",h);
printf("i=%d,hs=%s\n",i,hs);
// 十六进制字符串转成十进制数
strcpy(hs,"00000400");
sscanf(hs,"%x",&i);
printf("hs=%s,i=%d\n",hs,i);
// 二进制字符串转化为十六进制字符串;
strcpy(bs,"00000000000000000000010000000000");
i=strtol(bs,&e,2);
ltoa(i,h,16);
sprintf(hs,"%08s",h);
printf("bs=%s,hs=%s\n",bs,hs);
// 二进制字符串转化为十进制数;
strcpy(bs,"00000000000000000000010000000000");
i=strtol(bs,&e,2);
printf("bs=%s,i=%d\n",bs,i);
// 十六进制字符串转成二进制串
strcpy(hs,"00000400");
sscanf(hs,"%x",&i);
ltoa(i,b,2);
sprintf(bs,"%032s",b);
printf("hs=%s,bs=%s\n",hs,bs);
// ASC\GBK字符串转十六进制串
strcpy(s,"a汉");
i=0;
while (1) {
if (0==s[i]) break;
sprintf(hs+i*2,"%02X",(unsigned char)s[i]);
i++;
}
setlocale(LC_ALL,"chs");
printf("s=%s,hs=%s\n",s,hs);
// 十六进制字符串转成汉字(GBK)及字符(ASC)
strcpy(hs,"61BABA");
i=0;
while (1) {
if (1!=sscanf(hs+i*2,"%2x",&v)) break;
s[i]=(char)v;
i++;
}
s[i]=0;
printf("hs=%s,s=%s\n",hs,s);
return 0;
}
//i=1024,bs=00000000000000000000010000000000
//i=1024,hs=00000400
//hs=00000400,i=1024
//bs=00000000000000000000010000000000,hs=00000400
//bs=00000000000000000000010000000000,i=1024
//hs=00000400,bs=00000000000000000000010000000000
//s=a汉,hs=61BABA
//hs=61BABA,s=a汉
#include <stdio.h>
#include <stdlib.h>
char buf[17];
union U {
unsigned short int aa;
struct {
unsigned int bb:7;//(bit 0-6)
unsigned int cc:6;//(bit 7-12)
unsigned int dd:3;//(bit 13-15)
};
} u;
void main() {
//bbbbbbbbbbbbbbbb
//iiiiiiiiiiiiiiii
//tttttttttttttttt
//111111
//5432109876543210
//::::::::::::::::
u.aa=0xE07F;//1110000001111111
printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);
u.bb=0x41;
u.cc=0x21;//dddccccccbbbbbbb
u.dd=5; //1011000011000001
printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2));
}
//bb==127,cc==0,dd==7
//aa==0xB0C1==1011000011000001(2)
#include <stdio.h>
#pragma pack(push,1)
union U {
unsigned char byte;
struct BF {
unsigned int b0:1;//a
unsigned int b1:1;//b
unsigned int b2:1;//c
} bf;
} u;
#pragma pack(pop)
unsigned char bt;
int a,b,c;
int main() {
for (bt=0;bt<8;bt++) {
u.byte=(unsigned char)bt;
a=u.bf.b0;
b=u.bf.b1;
c=u.bf.b2;
printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);
}
for (c=0;c<2;c++)
for (b=0;b<2;b++)
for (a=0;a<2;a++) {
u.bf.b0=a;
u.bf.b1=b;
u.bf.b2=c;
bt=u.byte;
printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);
}
return 0;
}
//byte 0x00 -- c:0 b:0 a:0
//byte 0x01 -- c:0 b:0 a:1
//byte 0x02 -- c:0 b:1 a:0
//byte 0x03 -- c:0 b:1 a:1
//byte 0x04 -- c:1 b:0 a:0
//byte 0x05 -- c:1 b:0 a:1
//byte 0x06 -- c:1 b:1 a:0
//byte 0x07 -- c:1 b:1 a:1
//c:0 b:0 a:0 -- byte 0x00
//c:0 b:0 a:1 -- byte 0x01
//c:0 b:1 a:0 -- byte 0x02
//c:0 b:1 a:1 -- byte 0x03
//c:1 b:0 a:0 -- byte 0x04
//c:1 b:0 a:1 -- byte 0x05
//c:1 b:1 a:0 -- byte 0x06
//c:1 b:1 a:1 -- byte 0x07
typedef struct _Float
{
int mantissa:23;
int exponent:8;
int sign:1;
} Float;
typedef struct _Double
{
long long mantissa:9; //long long -> 64 bits
int exponent:8;
int sign:1;
} Double;
输出结果 4, 16
typedef struct _Float
{
int mantissa:24;
int exponent:8;
int sign:1;
} Float;
typedef struct _Double
{
long long mantissa:52; //long long -> 64 bits
int exponent:8;
int sign:1;
} Double;
输出结果 8 16
为啥前者的M有影响后者没有列typedef struct _Float
{
int mantissa:23;
int exponent:8;
int sign:1;
} Float;
typedef struct _Double
{
long long mantissa:52; //long long -> 64 bits
int exponent:11;
int sign:1;
} Double;
大哥你是在搞事情啊,你上面有这个,长度当然16啊。
long long 8字节
int 4字节
8+4+4=16