gpt4 book ai didi

python - 使用二进制补码在 DEC(基数 10)和 HEX(基数 16)之间转换

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:55:07 28 4
gpt4 key购买 nike

正如标题所说,我需要制作一个函数,在二进制补码中的 2 个碱基、DEC 和 HEX 之间进行转换。该值使用的位数从一开始就已知。

在深入研究之后,我发现了以下算法:

  1. 给定一个 DEC 中的数字。
  2. 获取数字的绝对值。
  3. 从步骤 2 中获取 abs 的二进制 (BIN) 值。
  4. 0 在左边填充,直到数字达到所需的长度。
  5. NOT 第 4 步中获得的所有位。
  6. 将结果加 1。 (实践中最简单的方法可能是转换回 DEC,加 1,然后再转换回 BIN)
  7. 转换为十六进制。完成。

根据我的观察,该算法可能仅在原始数字为负数 (<0) 时才有效。通过进行以下修改,我设法获得了看起来正确的结果:

在第 6 步,不要加 1。而是添加与原始数字签名相反的数字。例如,如果原始数字为负数,如 -455,则添加 1,如果为正数,如 10002,则“添加”-1

这似乎确实给出了积极的结果,但我不确定它是否可靠,因为在此之前我从未使用过二进制补码,我认为对第 6 步的修改是逻辑 + 猜测 - 正式知识.

这是我想出的 Python 3.6 函数,DEC 值是一个 int,所有其他值都表示为字符串,我假设的所需长度只是 4 的下一个倍数:

def d2h(i: int) -> str:
sign = (i // abs(i)) if i is not 0 else 1
step1 = i
step2 = abs(step1)
step3 = bin(step2)[2:]
step4 = step3
while len(step4) % 4 != 0:
step4 = '0' + step4
step5 = step4.replace('0', 'O') \
.replace('1', '0') \
.replace('O', '1')
step6 = bin(int(step5, 2) + -sign)[2:]
step7 = hex(int(step6, 2))[2:]
return step7

至于从 HEX 值转换回 DEC 值,我设法进行了某种“逆向工程”(因为我无法找到真正解释这一点的东西):

  1. 给定一个十六进制数字。
  2. 获取它的二进制表示,BIN。
  3. 0 填充直到所需的长度。
  4. 检查最左边的位是否为 1(即数字是否为负数)。
  5. 如果数字是负数,则将步骤 3 中的 BIN 值转换为 DEC,然后减去 2 的任意位数的幂 (2 ^ len(BIN) ),如果number 不是负数(前导位是 0)然后像往常一样简单地将它转换为 DEC。完成。

这是我为此编写的 Python 函数(与上面相同的实现细节):

def h2d(h: str) -> int:
step1 = h
step2 = bin(int(h, 16))[2:]
step3 = step2
while len(step3) % 4 != 0:
step3 = '0' + step3
if step3[0] == '1':
step4 = int(step3, 2) - (2**len(step3))
else:
step4 = int(step3, 2)
return step4

我的基本问题是:这些函数能否正确地将任何数字与十六进制的二进制补码相互转换,或者我只是偶然发现了幸运测试值的巧合?它是否正确?

编辑:经过进一步测试,我发现 h2d(d2h()) 并不总是给出正确的值。对于 0、1、2 等数字,它给出负值 -2、-3、-4 等,但对于边界情况,-32768 和 32767 它有效。

既然现在显然是不正确的,我应该更改什么(对于两种算法)以便它们是正确的?

提前致谢!

最佳答案

My bottom question is: Will these functions convert any number to and from two's complement in HEX correctly or did I just stumble into a coincidence of lucky test values? Is this correct?

您正在将每个数字(包括正数和负数)转换为其二进制补码表示形式。您应该只对负数执行此操作。这就是它们的表示方式,即使用其绝对值的 2s 补码。所以你的 d2h 函数变成了:

def d2h(i: int) -> str:                                                                                       
sign = (i // abs(i)) if i is not 0 else 1
step1 = i
step2 = abs(step1)
step3 = bin(step2)[2:]
step4 = step3
while len(step4) % 4 != 0:
step4 = '0' + step4
if sign == -1:
step5 = step4.replace('0', 'O') \
.replace('1', '0') \
.replace('O', '1')
step6 = bin(int(step5, 2) + 1)[2:]
else:
step5 = step4
step6 = step5
step7 = hex(int(step6, 2))[2:]
return step7

此外,您必须决定应该使用多少位来表示数字,例如。 32 位、64 位等。并将您的所有输入转换为二进制的那么多位。

关于python - 使用二进制补码在 DEC(基数 10)和 HEX(基数 16)之间转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48146012/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com