大端机小端机
Table of Contents
一个进制转换的小脚本
#!/usr/bin/bash if [ "$1" == "--help" -o "$1" == "-h" ]; then echo "usage: OBASE; IBASE; NUMBER" else echo "obase=$1; ibase=$2; $3" | bc fi
上面这个脚本,保存为 tran 文件,然后 chmod u+x ./tran 然后就可以使用各种基來表示了,不足之处是大于 10 的输出要用大写,最多支持 16 进制
tran 10 2 111 # 10 是输出格式, 2 是输入格式 7
tran 10 16 FF # 10 是输出格式, 16 是输入格式 255
tran 10 17 34 Runtime warning (func=(main), adr=13):ibase too large, set to 16 52
判断大端机还是小端机
union check { int i; char ch; } c; c.i = 1; printf("%d\n", (c.ch ==1));
在小端机的存储是
0x 01 00 00 00
在大端机的存储是
0x 00 00 00 01
所以在 小端机的输出是 1, 在大端机的输出是 0
大端机和小端机的转化
int a[5]; a[3] = 128; ((short *)a)[7] = 3; printf("%d\n", a[3]); // 196736
假设 int 占 4 位,short 占 2 位
首先是 a[ 3],由于 128 = 27, 10000000,他刚好占了 1Byte
a[ 3] = 128 在小端机画数组的时候要让右边为 0 开始往左边画
a[4] a[3] a[2] a[1] a[0] 0000 0000 0000 8000 0000 0000 0000 0000 0000 0000
((short *)a)[ 7] = 3
a[4] a[3] a[2] a[1] a[0] 0000 0000 0003 8000 0000 0000 0000 0000 0000 0000
216 + 217 + 27 = 196736
char a[4] = "abc"; int i = *(int *)a; printf("%d\n", i);
a 数组的存储布局(小端机)是,
0x ‘0‘ ‘c‘ ‘b‘ a‘ 00000000 01100011 01100010 01100001
赋值
char c1 = 65; short s1 = c1; // 65 // c1: 0x 0100 0001 // s1: 0x 0000 0000 0100 0001 short s2 = 195; char c2 = s2; // 195 // s2: 0x 0000 0000 1100 0011 // c2: 0x 1100 0011 char c3 = 128; short s3 = c3; // c3: 0x 1000 0000 // s2: 0x 1111 1111 1000 0000 short s4 = -1; int i = s4; // s3: 1111 1111 // i: 1111 1111 1111 1111
当位数少的时候, 赋值给位数多的, 赋值是看最高位的, c1 的最高位是 0, 那么赋值给 s1, 是用 0 去填充. c3 的最高位是 1, 那么赋值给 s3, 是用 1 去填充. s4 的最高位是 1, 那么赋值给 i, 是用 1 去填充.
当位数多的时候, 赋值给位数少的, 赋值直接截取, 看 c2, s2,
浮点数 和 整点数赋值的情况
float f = 7.0; short s = *(float *)&f; int i = *(int *)&f; printf("%d\n", s); // 0 printf("%d\n", i); // 1088421888
f 用 IEE754 表示是, 0x40 E0 00 00, 在小端机的内存中就是, 0x00 00 E0 40,
所以就会用 0x 00 00 赋值给 s, 也就是 0. e 而 i 就是 0x 00 00 E0 40, 也就是, 当然这是他在内存中的方式, 计算的时候就是 40E00000
在大端机测试的时候会是什么结果? (自己个人推测)
s = 0x40E0 i = 0x40E00000