繁体   English   中英

在big-endian机器中对little-endian整数进行简单的按位操作?

[英]Simple bitwise manipulation for little-endian integer, in big-endian machine?

为了满足特定的需要,我在四个一个字节的字符中构建一个四字节整数,没有什么特别的(在我的小端平台上):

    return (( v1 << 24) | (v2 << 16) | (v3 << 8) | v4);

我知道存储在大端机器中的整数看起来像AB BC CD DE而不是具有小端字节的DE CD BC AB ,尽管它会完全影响我的操作,因为我将错误地移动,或者它只会导致反向存储的正确结果需要反转吗?

我想知道是否要创建这个函数的第二个版本来为大端机器做(但未知)位操作,或者可能使用与ntonl相关的函数,我不清楚如何知道我的数字是否正确或不。

你有什么建议来确保兼容性,请记住我需要以这种方式形成整数?

只要您在价值水平上工作,无论您的机器是小端还是大端,您获得的结果都绝对没有区别。 即只要您使用语言级别的运算符(如示例中的|<< ),您将在任何平台上从上面的表达式获得完全相同的算术结果。 机器的字节顺序无法检测到,并且在此级别不可见。

当您需要关心字节顺序时,唯一的情况是在对象表示级别检查您正在使用的数据,即在其原始内存表示很重要的情况下。 您上面所说的“ AB BC CD DE而不是DE CD BC AB ”具体是关于数据的原始内存布局。 这就像ntonl这样的功能:它们将一个内存布局转换为另一个内存布局。 到目前为止,您没有表明实际的原始内存布局对您来说非常重要。 是吗?

同样,如果您只关心上述表达式的 ,则它完全且完全独立于字节序。 基本上,当您编写不尝试访问和检查原始内存内容的C程序时,您根本不应该关心字节序。

虽然它会完全影响我的操作,因为我会错误地转移(?)

没有。

无论endian架构如何,结果都是相同的。 比特移位和twiddling就像常规算术运算一样。 小端和大端架构上的2 + 2是否相同? 当然。 2 << 2也是一样的。

当你直接处理内存时会出现小的和大的endian问题。 执行以下操作时,您将遇到问题:

char bytes[] = {1, 0, 0, 0};
int n = *(int*)bytes;

在小端机器上,n将等于0x00000001。 在大端机器上,n将等于0x01000000。 这是你必须交换周围的字节。

[为清楚起见重写]

ntohl (和ntohs等)主要用于将数据从一台机器移动到另一台机器。 如果你只是简单地在一台机器上操作数据,那么在没有任何进一步仪式的情况下进行位移是完全没有问题的 - 位移(至少在C和C ++中)是用乘法/除以2的幂来定义的,无论机器是big-endian还是little-endian,它的工作原理都是一样的。

当/如果您需要(至少可能)将数据从一台机器移动到另一台机器时,在发送之前使用htonl通常是明智的,而在收到它时则使用ntohl 这可能完全是nops(在BE到BE的情况下),两个相同的转换相互抵消(LE到LE),或实际上导致交换字节(LE到BE或反之亦然)。

FWIW,我认为这里所说的很多都是正确的。 但是,如果程序员在编写时考虑了字节顺序,比如使用掩码进行按位检查和操作,则跨平台结果可能会出乎意料。

您可以在运行时确定'endianness',如下所示:

#define LITTLE_ENDIAN 0
#define BIG_ENDIAN    1

int endian() {
    int i = 1;
    char *p = (char *)&i;

    if (p[0] == 1)
        return LITTLE_ENDIAN;
    else
        return BIG_ENDIAN;
}

......并据此进行。

我从这里借用了代码片段: http//www.ibm.com/developerworks/aix/library/au-endianc/index.html? ca=drs-这里也对这些问题进行了很好的讨论。

hth -

佩里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM