Dar*_*ell 6 c++ endianness visual-studio-2008
我正在尝试为在Win XP上运行的C++程序编写一个byteswap例程.我正在使用Visual Studio 2008编译.这就是我想出的:
int byteswap(int v) // This is good
{
return _byteswap_ulong(v);
}
double byteswap(double v) // This doesn't work for some values
{
union { // This trick is first used in Quake2 source I believe :D
__int64 i;
double d;
} conv;
conv.d = v;
conv.i = _byteswap_uint64(conv.i);
return conv.d;
}
Run Code Online (Sandbox Code Playgroud)
还有一个测试功能:
void testit() {
double a, b, c;
CString str;
for (a = -100; a < 100; a += 0.01) {
b = byteswap(a);
c = byteswap(b);
if (a != c) {
str.Format("%15.15f %15.15f %15.15f", a, c, a - c);
}
}
}
Run Code Online (Sandbox Code Playgroud)
获取这些数字不匹配:
-76.789999999988126 -76.790000000017230 0.000000000029104 -30.499999999987718 -30.499999999994994 0.000000000007276 41.790000000014508 41.790000000029060 -0.000000000014552 90.330000000023560 90.330000000052664 -0.000000000029104
这是在阅读之后:
如何在C++中的big-endian和little-endian值之间进行转换?
Little Endian - Big Endian问题
顺便说一下你不能在双重上使用<<和>>(除非我弄错了?)
虽然double在主存储器中是64位,但在x86 CPU上,双精度寄存器是80位宽.因此,如果您的一个值全部存储在寄存器中,但另一个值通过主存储器往返并被截断为64位,这可以解释您所看到的小差异.
也许你可以通过获取地址(并打印它,以防止编译器优化它)来强制变量存在于主存储器中,但我不确定这是否可以保证工作.
b = byteswap(a);
Run Code Online (Sandbox Code Playgroud)
这是个问题。交换字节后,该值不再是正确的双精度值。当 FPU 对值进行规范化时,将其存储回双精度值会导致微妙的问题。您必须将其存储回 __int64 (long long)。修改方法的返回类型。
尝试 3
好的,发现有更好的方法。另一种方式是您必须担心打包/拆包的顺序。这样你就不会:
// int and float
static void swap4(void *v)
{
char in[4], out[4];
memcpy(in, v, 4);
out[0] = in[3];
out[1] = in[2];
out[2] = in[1];
out[3] = in[0];
memcpy(v, out, 4);
}
// double
static void swap8(void *v)
{
char in[8], out[8];
memcpy(in, v, 8);
out[0] = in[7];
out[1] = in[6];
out[2] = in[5];
out[3] = in[4];
out[4] = in[3];
out[5] = in[2];
out[6] = in[1];
out[7] = in[0];
memcpy(v, out, 8);
}
typedef struct
{
int theint;
float thefloat;
double thedouble;
} mystruct;
static void swap_mystruct(void *buf)
{
mystruct *ps = (mystruct *) buf;
swap4(&ps->theint);
swap4(&ps->thefloat);
swap8(&ps->thedouble);
}
Run Code Online (Sandbox Code Playgroud)
发送:
char buf[sizeof (mystruct)];
memcpy(buf, &s, sizeof (mystruct));
swap_mystruct(buf);
Run Code Online (Sandbox Code Playgroud)
接收:
mystruct s;
swap_mystruct(buf);
memcpy(&s, buf, sizeof (mystruct));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9873 次 |
| 最近记录: |