molinchz 发表于 2021-11-15 10:02:24

python 字节碰到 的的问题



我用hex(4565),得到 16进制11d5    ,但存放的是d511,也就是高低位交换了,而且python 里面比如hex(2016 ) 得到是0x7e0,高位的07转成7了,这样的,存放到 .cis 文件 中0x7 还能 是07吗?要补码操作吗,高低位交换是分离在合成 ,    根本大神给的方法和我网上查到后,测试结果 发现 代码如下
ybnum = 99
print(hex(ybnum))   # 转换为十六进制
# 数量二个字节高低位交换
data_byte1 = ybnum.to_bytes(length=2, byteorder='little', signed=True)
print(data_byte1)

得到的结果很奇怪:
0x63
b'c\x00'


如果 是4565 这个数就是对,其它的好些个有变。
查到这个to_bytes是参数范围是0到255,我有点不知怎么搞了,请大神帮忙 看下

jackz007 发表于 2021-11-15 10:24:27

本帖最后由 jackz007 于 2021-11-15 10:31 编辑

      看了半天,不知道你究竟想干啥?
      一般的应用不涉及字节顺序问题,除非你有二进制文件需要跨大、小端系统使用。否则,完全没有必要关心字节顺序问题!

molinchz 发表于 2021-11-15 10:34:41

本帖最后由 molinchz 于 2021-11-15 11:07 编辑

jackz007 发表于 2021-11-15 10:24
看了半天,不知道你究竟想干啥?

意思 是这样,要存放的数总共是二个字节 , 10进制转成16进制 到存放 ,转成16进制 后,高低交换存放,比如 hex(4565),得到 16进制11d5 ,这个是二字节,最后交换存放 是01 00,如果是一个字节,就不用交换。

jackz007 发表于 2021-11-15 10:43:45

本帖最后由 jackz007 于 2021-11-15 10:44 编辑

molinchz 发表于 2021-11-15 10:34
意思 是这样,要存放的数总共是二个字节 , 10进制转成16进制 到存放 ,转成16进制 后,高低交换存放, ...

      你这个说法脱离使用场景,大端、小端是针对需要多字节编码的数值型变量而存在的,例如,32位整型数、32位浮点数每个数需要用 4 个字节来表示;64 位整型数、64 位浮点数每个数需要用 8 个字节来表示,这些字节的排列顺序才是大小端体系架构带来的真正区别。单纯讨论字节顺序变换没有任何实际意义。

hrpzcf 发表于 2021-11-15 15:39:24

你不用管hex的返回值是什么,它的返回值是一个字符串,只是给人看的,如果前缀是0他会将0省去(毕竟只是给人看的),其返回值只能用来参考数据以大端模式时候的大致样子。
关键是to_bytes的返回值,毕竟它返回的字节码是要被你写入文件中的,跟hex没半点关系。
ybnum = 99
# print(hex(ybnum))   # 转换为十六进制
# 数量二个字节高低位交换 x
# 不能理解成高低位交换,只能说是生成小端模式顺序的字节码(byteorder="big"就生成大端模式顺序的)
# 比较一般x86_64的个人PC,数据都是以小端模式储存的,你改变不了它
data_byte1 = ybnum.to_bytes(length=2, byteorder="little", signed=True)
print(data_byte1)

# b"c\x00" 和 b"\x63\x00"是相等的,\x63显示成c只是因为\x63刚好对应c的
# ascii码python将其显示成c给你看(个人认为这点不好,我并不想看\x63是什么字母)
print(data_byte1 == b"\x63\x00")

print((2016).to_bytes(2, "big"))    # 生成大端模式顺序的字节码b'\x07\xe0'



molinchz 发表于 2021-11-15 16:23:39

hrpzcf 发表于 2021-11-15 15:39
你不用管hex的返回值是什么,它的返回值是一个字符串,只是给人看的,如果前缀是0他会将0省去(毕竟只是给人 ...

谢谢,我自己测试 了写入,确实 是这样,返回值什么 不重要,写入的是16进制 的转码,但写入编码 是高低位交换 的。

hrpzcf 发表于 2021-11-15 16:34:36

molinchz 发表于 2021-11-15 16:23
谢谢,我自己测试 了写入,确实 是这样,返回值什么 不重要,写入的是16进制 的转码,但写入编码 是高低 ...

写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big参数才能生成高低位不相反的字节码。读取你的二进制文件的其他程序也要按大端模式读取才能正确还原数值,否则会出错,你得先了解读取你的文件的程序到底是按大端还是小端读取的,再决定你要不要用大端模式生成字节码并写入文件。

molinchz 发表于 2021-11-15 17:05:29

hrpzcf 发表于 2021-11-15 16:34
写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big ...

明白了,谢谢,转得好麻烦 {:5_109:}

molinchz 发表于 2021-11-15 22:36:43

hrpzcf 发表于 2021-11-15 16:34
写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big ...

大神,在问下1000   这个出来的16进制是0000 7A44    ,这是什么编码 ?

hrpzcf 发表于 2021-11-15 23:40:15

molinchz 发表于 2021-11-15 22:36
大神,在问下1000   这个出来的16进制是0000 7A44    ,这是什么编码 ?

你看错了吧

molinchz 发表于 2021-11-16 11:06:31

hrpzcf 发表于 2021-11-15 23:40
你看错了吧

1000 的转出来是   00 00 12268   

molinchz 发表于 2021-11-16 15:10:19

molinchz 发表于 2021-11-16 11:06
1000 的转出来是   00 00 12268

我忘了附上VBA的代码
H2里面是1000
Public Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) 'EXCEL申明
CopyMemory(EndFile(41), CSng(Range("H2")), 4)      
得到的结果 不是000003e8   而是00007a44

把CSng换成CLng。CSng是转换为单精度数,在内存中其存储格式与长整型是不一样的。而CopyMemory是按地址传递参数的,会将保存单精度数的地址(这里其实就是保存CSng函数返回值的内存地址)传递过去,然后取出这个地址内的4个字节直接复制到你EndFile字节数组的指定位置代表的内存地址,
还有就是,4字节代表的整数存储的顺序是高位在后,复制过去应该是E8 03 00 00,表示的就是3E8这个十六进制数,但现在复制过去的数据表示为整数      就是447A0000,,这怎么来算出这个数呢,最后一步了!!

hrpzcf 发表于 2021-11-16 15:52:10

molinchz 发表于 2021-11-16 15:10
我忘了附上VBA的代码
H2里面是1000
Public Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias ...

import struct

f = struct.pack("<f", 1000.0)    # 以浮点型生成字节码(小端)
print("字节码内容:", f)    # 打印字节码的值

for b in f:
    print(b, end="\t")    # 打印字节码的值(以十进制)
print()
for b in f:
    print(r"\x%02x" % b, end="\t") # 打印字节码的值(以十六进制)

hrpzcf 发表于 2021-11-16 15:59:26

@不二如是 大佬帮忙审核一下回复

molinchz 发表于 2021-11-16 16:43:41

hrpzcf 发表于 2021-11-16 15:59
@不二如是 大佬帮忙审核一下回复

大佬,是不是这样可以解了,
s = float('1000')
print(struct.pack('<f', s).hex())#小端
#输出:00007a44
print(struct.pack('>f', s).hex())#大端
#输出:447a0000

hrpzcf 发表于 2021-11-16 17:14:48

molinchz 发表于 2021-11-16 16:43
大佬,是不是这样可以解了,
s = float('1000')
print(struct.pack('f', s).hex())#大端


是的,我上一条回复跟这差不多但被审核了,让大佬审核回复但是大佬会错意选了最佳{:10_247:}

molinchz 发表于 2021-11-16 20:49:34

hrpzcf 发表于 2021-11-16 17:14
是的,我上一条回复跟这差不多但被审核了,让大佬审核回复但是大佬会错意选了最佳

float_to_hex = struct.pack('<f', s)#小端
data_byte1 = ybnum.to_bytes(length=2, byteorder='little', signed=True)   
大佬,这个s和ybnum   怎样写成变量的模式

hrpzcf 发表于 2021-11-17 09:26:46

molinchz 发表于 2021-11-16 20:49
float_to_hex = struct.pack('

你现在写的不就是变量吗

molinchz 发表于 2021-11-17 16:35:52

hrpzcf 发表于 2021-11-17 09:26
你现在写的不就是变量吗

for com_num in range(393000, 394000, 1):
    with open(os.path.join(lc_path, f"{com_num}.cis"), "wb") as cisf:   

老师,我增加一个变量假如是 bklist=321,我只要计数这321次,怎样修改代码 ?

hrpzcf 发表于 2021-11-17 16:45:31

molinchz 发表于 2021-11-17 16:35
for com_num in range(393000, 394000, 1):
    with open(os.path.join(lc_path, f"{com_num}.cis"), " ...

循环外面把它初始化为0,循环里一直 +1 就行了。
页: [1] 2
查看完整版本: python 字节碰到 的的问题