首页 > 其他分享 >Little Endian & Big Endian

Little Endian & Big Endian

时间:2024-04-26 17:34:28浏览次数:27  
标签:__ Little short 字节 Big char 内存 Endian

什么是字节序

字节序是指在多字节数据类型(如整数、浮点数等)的字节在内存中的存储顺序。

主要有两种字节序:大端字节序(Big-endian)和小端字节序(Little-endian)。

  • Little-Endian 低字节在内存低地址端,高字节在内存高地址端

  • Big-Endian 高字节在内存低地址端,低字节在内存高地址端

address Little Endian Big Endian
0x7000 0x34 0x12
0x7001 0x12 0x34

为什么会有大小端的分别

大小端问题主要涉及的是非单字节非字符串外的其余数据的表示和传递,如short型、int型等。大端和小端有其各自的优势。

我们知道计算机正常的内存增长方式是从低到高(当然栈不是),取数据方式是从基址根据偏移找到他们的位置,从他们的存储方式可以看出,大端存储因为第一个字节就是高位,从而很容易知道它是正数还是负数,对于一些数值判断会很迅速。

而小端存储 第一个字节是它的低位,符号位在最后一个字节,这样在做数值四则运算时从低位每次取出相应字节运算,最后直到高位,并且最终把符号位刷新,这样的运算方式会更高效。

链接:https://www.zhihu.com/question/25311159/answer/33589698

如何判断主机大小端

//
// Created by zhipeng shu on 2024/4/26.
//

//Little-Endian:低字节在内存低地址端,高字节在内存高地址端,如
//0x7000 is 0x34
//0x7001 is 0x12

//Big-Endian:高字节在内存低地址端,低字节在内存高地址端,如
//0x7000 is 0x12
//0x7001 is 0x34

bool isLittleEndian_1(){
    union Word{
        short value;
        char ch[sizeof(short)];
    };
    Word word = {4660};//0x1234=4660=pow(16,3)+2*pow(16,2)+3*pow(16,1)+4*pow(16,0)
    return word.ch[0]==0x34;
}

bool isLittleEndian_2(){
    short value = 0x1234;//4660
    char ch =  * (char *)&value;//short转char*,取首元素判断
    return ch==0x34;
}

网络字节序

UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待。也就是说,发送端发送的第一个字节是需要是高位字节。

而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节。

所以网络字节序就是大端字节序。

有些系统的本机字节序是小端字节序, 有些则是大端字节序, 为了保证传送顺序的一致性, 所以网际协议使用大端字节序来传送数据。

如何进行大小端转换

使用宏定义转换大小端字节序


/* Macros for swapping constant values in the preprocessing stage. */
//16位数据转换大小端
#define __DARWIN_OSSwapConstInt16(x) \
    ((__uint16_t)((((__uint16_t)(x) & 0xff00U) >> 8) | \
	        (((__uint16_t)(x) & 0x00ffU) << 8)))
//32位数据转换大小端
#define __DARWIN_OSSwapConstInt32(x) \
    ((__uint32_t)((((__uint32_t)(x) & 0xff000000U) >> 24) | \
	        (((__uint32_t)(x) & 0x00ff0000U) >>  8) | \
	        (((__uint32_t)(x) & 0x0000ff00U) <<  8) | \
	        (((__uint32_t)(x) & 0x000000ffU) << 24)))
//64位数据转换大小端
#define __DARWIN_OSSwapConstInt64(x) \
    ((__uint64_t)((((__uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
	        (((__uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
	        (((__uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
	        (((__uint64_t)(x) & 0x000000ff00000000ULL) >>  8) | \
	        (((__uint64_t)(x) & 0x00000000ff000000ULL) <<  8) | \
	        (((__uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
	        (((__uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
	        (((__uint64_t)(x) & 0x00000000000000ffULL) << 56)))

使用函数转换大小端


/**
  ******************************************************************************
  * https://blog.csdn.net/weixin_46672094/article/details/122524919
  * @brief   大小端转换 函数
  * @param   *p     数据块指针
  * @param   size   字节数
  * @return  None
  ******************************************************************************
  */
void BigLittleEndianSwap(unsigned char *p, unsigned char size)
{
    unsigned char i;
    unsigned char tmp;
    unsigned char num = size/2;
    size--;
    for(i=0; i<num; i++)
    {
        tmp = p[i];
        p[i] = p[size-i];
        p[size-i] = tmp;
    }
}

本地字节序和网络字节序的转换

htons() //host to network short
htonl() //host to network long
ntohs() //network to host short
ntohl() //network to host long

在unix系统中,可以使用man htons指令查看手册

使用示例

short value = 0x1234;
std::cout<<std::dec<<"value="<<value<<",hex="<<std::hex<<value<<std::endl;
//value=4660,bits=0001001000110100,hex=1234

value = htons(value); //将value从主机端转换为网络字节序

std::cout<<std::dec<<"value="<<value<<",hex="<<std::hex<<value<<std::endl;
//value=4660,bits=0001001000110100,hex=1234

标签:__,Little,short,字节,Big,char,内存,Endian
From: https://www.cnblogs.com/pengpengda/p/18160531

相关文章

  • 精选 | Google Cloud Next'24 拉斯维加斯会议 BigQuery 连续查询报告
    本篇由CloudAce数据解决方案部高级工程师撰写。 我听说了拉斯维加斯GoogleCloudNext'24举办的“使用BigQuery连续查询构建连续数据和AI管道”(“BuildcontinuousdataandAIpipelineswithBigQuerycontinuousqueries”)会议,我想对此进行报道。 本次会议......
  • CodeForces 115D Unambiguous Arithmetic Expression
    洛谷传送门CF传送门直接区间dp可以做到\(O(n^3)\),卡常可过,在此就不赘述了。为了方便先把连续的数字缩成一段。我们考虑直接从前往后扫,扫的过程中dp。设\(f_{i,j}\)为考虑了\([1,i]\),还有\(j\)个没配对的左括号的方案数。但是我们发现我们不知道一个数字前要添加几......
  • SQL+WHERE+别名+过滤的问题 Column 'code' in where clause is ambiguous
    背景有两张表,父表task和子表sub_task,它们使用id关联,并且都有自己的编号code,但是在分页查询子任务列表时,编号需要使用父表编号+子表编号进行拼接(比如,task表编号为zh001,sub_task表编号为01,则页面展示为zh001-01),并且需要根据组成的编号过滤。问题实际项目使用时,sql......
  • SciTech-BigDataAIML-Adam动量自适应的梯度快速收敛
    http://faculty.bicmr.pku.edu.cn/~wenzw/optbook/pages/stograd/Adam.html版权声明此页面为《最优化:建模、算法与理论》、《最优化计算方法》配套代码。代码作者:文再文、刘浩洋、户将,代码整理与页面制作:杨昊桐。Adam算法考虑优化问题:minx∈Rnf(x)=1N∑i=1Nfi(x).Adam算......
  • Java BigDecimal出现科学计数法
    JavaBigDecimal出现科学计数法查看BigDecimal的toString()源码,可以发现出现toString()出现科学计数法的原因 privateStringlayoutChars(booleansci){...intcoeffLen=coeff.length-offset;longadjusted=-(long)scale+(coeffLen-1);......
  • 争论不休的一个话题:金额到底是用Long还是BigDecimal?
    在网上一直流传着一个争论不休的话题:金额到底是用Long还是用BigDecimal?这个话题一出在哪都会引起异常无比激烈的讨论。。。。比如说这个观点:算钱用BigDecimal是常识有支持用Long的,将金额的单位设计为分,然后乘以100,使用Long进行存储以及计算,这样不用担心小数点问题。并且一些......
  • JSNice:Predicting Program Properties from “Big Code”
    发表:ACMSIGPLANNotices,2015,苏黎世联邦理工学院计算机科学系SoftwareReliabilityLab,AndreasKrause团队(https://scholar.google.com/citations?user=eDHv58AAAAAJ)(https://www.sri.inf.ethz.ch/research/plml)工具:http://jsnice.org内容概括  文章通过“大代码”......
  • Mr.LR.HBB (Mr. LavaRoad.Hygiene.BigBrother)
    我们宿舍的一号床名字叫做岩浆路。他是一个体型巨大的,脸胖到离谱并且捏起来很舒服的,抽象的,男孩子。「美好的起源」他在军训时用滑稽的身躯成功引起了我的注意,后来我们又在同一个宿舍,我们就渐渐熟识了。后来又发现我玩florr,虽然我那时已经退游,但是听到有人玩过我曾经玩的游戏,......
  • js处理大数(超过16位的数字):big-init、bignumber.js
    bigints支持JSON.parse/stringify解析方式。基于DouglasCrockford的JSON.js包和bignumber.js库。本地Bigint最近被添加到JS中,所以我们增加了一个选项来代替bignumber.js。但是,使用本机BigInt进行解析是为了向后兼容虽然大多数JSON解析器假设数值具有与IEEE754double相同的精......
  • Redis bigkey解决方案
    什么是大key查询bigkey集群模式查看bigkeyredis-cli排查cluster模式排查大key因为clister集群模式下查询bigkey时,因为键会分散在不同的槽(slot)和不同的节点上,因此需要分别连到各个主节点进行检查,或者在命令添加-c参数首先需要查看cluster各个节点,连接其中任意一个节点执行以......