大小端判断、转换及测试环境
作者:tyc611.cublog.cn,2008-10-01
先介绍一个网上可用的主机资源:,这个网站提供了众多可远程登录的服务器,有多种CPU(Intel、AMD、Sparc、Power等)和操作系统(Fedora、Ubuntu、FreeBSD、AIX等),是一个非常方便的测试环境,建议注册一个账号。本文将使用它的Sparc/Solaris环境进行测试(为大端环境),主机地址见。
大小端的判断比较简单,主要是利用大小端的性质。举例如下:
#include
using namespace std;
bool IsLittleEndian()
{
int value = 1;
char *p = reinterpret_cast(&value);
return *p == 1;
}
int main()
{
if (IsLittleEndian())
cout << "little-endian" << endl;
else
cout << "big-endian" << endl;
}
我在自己的机器上运行结果如下(AMD+XP):
little-endian
在前面的Sparc/Solaris机器上运行结果如下:
big-endian
大小端的转换也是比较简单的,就是把字节序反转。方法多样。
比如,可以把一个任意长度的整形类型看作字节序列,然后使用字节序列的反转算法处理即可,这个方法可通用于任意长度的整形类型。
#include
using namespace std;
template
Integer Reverse(Integer value)
{
char *p1 = reinterpret_cast(&value);
char *p2 = p1 + sizeof(Integer) - 1;
for (; p1 < p2; ++p1, --p2)
swap(*p1, *p2);
return value;
}
int main()
{
cout << hex << uppercase;
cout << "short: " << Reverse(0x03A1) << endl;
cout << "int: " << Reverse(0x03A1) << endl;
cout << "long long: " << Reverse(0x03A1) << endl;
}
在我的机器输出结果为:
short: A103
int: A1030000
long long: A103000000000000
在前面的Sparc/Solaris机器上运行结果为:
short: A103
int: A1030000
long long: 3A1
不知道这里为什么输出了错误的结果,还没找到原因。
(注:long long在此机器上为8字节。调试发现,Reverse函数中value参数在执行过程中竟然没有改变)
后来发现引入一个临时变量就好了,但问题原因还是不明:
template
Integer Reverse(Integer value)
{
Integer result = value;
volatile char *p1 = reinterpret_cast(&result);
volatile char *p2 = p1 + sizeof(Integer) - 1;
for (; p1 < p2; ++p1, --p2) {
swap(*p1, *p2);
}
return result;
}
此外,还可以使用位运算,但很难写出通用且可移植的代码。
阅读(2073) | 评论(2) | 转发(0) |