字节转换之大小端

今天有个任务是将字节文件转换成整型,我是采用C#的BinaryReader.ReadInt32来直接读取的,运行结果也很顺利,整型结果是1577,但是好奇心驱使我用Ultraedit打开了源文件,但是我发现16进制存储的数组是这样的

这是什么鬼…,读取结果:

0x29060000=0*16^0+0*16^1+0*16^2+0*16^3+6*16^4+0*16^5+9*16^6+2*16^7=688259072

这和1577完全不搭嘎啊,都溢出了…

于是乎问大牛,查资料,得知这是大小端问题,我的是小端,低位存低位地址,高位存高位地址。

读取的正确结果应该是:

0x00000629=9*16^0+2*16^1+6*16^2=1577

大端:高位存在低地址,低位存在高地址;

小端:高位存在高地址,低位存在低地址;(intel的x86,ARM普遍都是属于小端)

查询自己机器到底是大端还是小端的方法也不复杂

C#自带BitConverter封装的IsLittleEndian判断

//判断大小端(BigEndian - LittleEndian, C#/Win小端,Java大端,网络传输大端)
        //数字或Unicode区分大小端(2的倍数的字节数)
        bool isLittle = BitConverter.IsLittleEndian;

        //数字
        //方法一
        int c = 97;
        byte[] cb = BitConverter.GetBytes(c);//小端
        Array.Reverse(cb);//反转成大端

        //方法二
        int c2 = IPAddress.HostToNetworkOrder(c);//大端字节数
        byte[] bb = System.BitConverter.GetBytes(c2);//字节数组

        //文本(Unicode)
        string s = "code";
        byte[] sbb = Encoding.BigEndianUnicode.GetBytes(s);//大端
        byte[] sbs = Encoding.Unicode.GetBytes(s);//小端

C++判断也简单,采用Union的方式判断,因为在Union中所有的元素都放在一块内存空间中,mu.c的内存地址是和int型的变量i的起始地址对齐的,所以改变int型的值mu.i=1,如果为小端存储,则mu.c==1,反之,则为大端存储。详细可以参考:http://blog.csdn.net/anialy/article/details/8015183

void checkSystemBigOrLittle(void)
{
    typedef union MyUnion
    {
        int i;
        char c;
    }; 

    MyUnion mu; 

    mu.i = 1; 

    if(mu.c == 1)
    {
        printf("小端存储模式");
    }
    else if (mu.c == 0)
    {
        printf("大端存储模式");
    }
    else
    {
        printf("很抱歉,出错了");
    }
} 

上文是各种被大牛喷的结果,后来的童鞋们请打牢基础,被喷请自查…

时间: 2024-10-23 22:17:27

字节转换之大小端的相关文章

字节序与大小端

为什么会有字节序问题 1. 内存以8bit为一个地址单位:早期的处理器地址以8bit为一个单位(8位处理器),也就是说一次可以访问8bit的数据,后来出现了16位,32位甚至64位的处理器,但为了兼容最早的8位处理器,因此沿用8bit为一个地址单位. 2. 大于8位的处理器,如32位处理器,虽然每个8bit(一个字节)存储数据的方式是一样的,但是针对整形这样的有多个字节的数据结构的数据,每个字节内存储数据方式相同,但字节间(即几个字节的顺序)存储方式不同. 3.其他历史原因. 不同的处理器结构对

字节顺序与大小端

1.概念: 1)小端:操作数的存放方式是高地址存放高字节. 0x1234,存放地址为0x2000 内存地址 存放内容 0x2000 0x34 0x2001  0x12 2)大端:操作数的存放方式是高地址存放低字节.    0x1234,存放地址为0x2000 内存地址 存放内容 0x2000 0x12 0x2001  0x34 x86平台采用的是小端模式,网络字节顺序是大端模式. 2.检测系统大小端 1)调用库检测 1 #include<endian.h> 2 #include<stdi

【转】[c/c++ ]字节序与大小端转换--不错

原文网址:http://blog.csdn.net/kuai0705/article/details/20841133 注明: 以下内容均为学习内容整理,记录,便于自己学习,并非完全意义上的自产,如有感到不适,请联系我 一.多字节值及字节序 1.brief 现在有一个数字 65430,这个数字在二进制的内存中一个字节无法完全存下,存储这个数字需要1个字节以上的空间.这样的值被称为多字节量(multi-byte quantity). 65430在内存中由两个字节表示:0xFF 和 0x96 ,其中

Linux程序设计学习笔记----网络编程之网络数据包拆封包与字节顺序大小端

网络数据包的封包与拆包 过程如下: 将数据从一台计算机通过一定的路径发送到另一台计算机.应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示: 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据包(packet),在链路层叫做帧(frame).数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理. 上图对应两台计算机在同一网段中的情况,

(转)大小端模式详解

int i=1; char *p=(char *)&i; if(*p==1) printf("1"); else printf("2"); 大小端存储问题,如果小端方式中(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端. 请写一个C函数,若处理器是Big_end

memcpy与大小端

搬运自我的CSDNhttps://blog.csdn.net/u013213111/article/details/100149145 参考: 大端 小端 与memcpy 网络字节序和大小端字节序 来看这样一段代码: 本意是想把uint8_t a[2]中的内容合成一个uint16_t b #include <stdlib.h> #include <stdio.h> #include <stdint.h> int main() { uint8_t a[2] = { 0x1

关于大小端问题和字节序问题的一些总结

1.大小端是不同的对于数据在内存地址中的存放方式,不同的处理器(平台)的数据存储方式是不同.的如果 实现跨平台通信则大小端是不能忽视的问题. 大端模式:数据的高位存储在内存的低字节.ARM/PowerPC等处理器采用大端模式 小端模式:数据的地位存储在内存的低字节.Intel架构处理器采用小端模式. 如一个数据:0x12345678;对应内纯地址是0x00~0x03. 大端模式: 小端模式: 地址:0x00 0x01 0x02 0x03 地址:0x00 0x01 0x02 0x03 数据:0x1

【转】htonl(),htons(),ntohl(),ntons()--大小端模式转换函数

转自 http://www.cnblogs.com/kungfupanda/archive/2013/04/24/3040785.html 不同机器内部对变量的字节存储顺序不同,有的采用大端模式(big-endian),有的采用小端模式(little-endian).大端模式是指高字节数据存放在低地址处,低字节数据放在高地址处.小端模式是指低字节数据存放在低地址处,高字节数据放在高地址处. 在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此 TCP

一场关于异构平台通信的风波(粘包&#183;大小端方式&#183;网络字节序)

一.引子 前段时间用StriveEngine做一个信息采集系统,服务器是Windows的,客户端是各种单片机,以及Unix等等平台.这些异构的平台,被我召集起来“加强对话, 扩大共识, 深化合作”.都说有人的地方就有江湖,讲真,机器世界也一样!这些异构的平台,平日里各自为政,井水不犯河水,倒也相安无事.如今群雄会盟,共商大计,如我所料,势必会上演一波真正的血雨腥风! 就像新闻联播里常说的,“加强对话, 扩大共识, 深化合作”,首先得“加强对话”吧. 看着各位爷陆续到场,我稍稍清了清嗓子,不揣冒昧