将十进制值转换为二进制、十六进制和八进制的单个函数不会转换为二进制

Posted

技术标签:

【中文标题】将十进制值转换为二进制、十六进制和八进制的单个函数不会转换为二进制【英文标题】:A single function to convert decimal values to binary, hexadecimal and octal does not convert to binary 【发布时间】:2019-09-21 09:12:47 【问题描述】:

我正在尝试构建一个标准函数来将任何十进制值转换为其等效的八进制、十六进制和二进制,但由于某种原因它不适用于二进制。我尝试在条件语句中添加额外的预防措施以检查基数 2,但它仍然不起作用。

这是函数(我知道这不适用于十六进制值。我会在之后处理它):

def convert(num, base):
    remainder = num % base
    conv = []

    if(remainder == 0):
        conv.append('0')
    elif(remainder != 0 and base == 2):
        conv.append('1')
    else:
        conv.append(str(remainder))

    result = ''.join(conv)
    output = result[::-1]

    return int(output)

elif(remainder != 0 and base == 2): 行中,我正在检查余数是否不是 0 并且基数是否为 2 以将 1 添加到临时 conv 列表中。然后我将列表转换为字符串,将其反转并将其作为 int 返回。

例如。如果输入是17,输出需要是这样的:

    1     1     1     1
    2     2     2    10
    3     3     3    11
    4     4     4   100
    5     5     5   101
    6     6     6   110
    7     7     7   111
    8    10     8  1000
    9    11     9  1001
   10    12     A  1010
   11    13     B  1011
   12    14     C  1100
   13    15     D  1101
   14    16     E  1110
   15    17     F  1111
   16    20    10 10000
   17    21    11 10001

这些是负责输入和打印的函数:

def print_formatted(number):
    # your code goes here

    for i in range(number):
        print(
            str(i + 1) + " " + 
            str(convert(i + 1, 8)) + " " + 
            str(convert(i + 1, 16)) + " " + 
            str((convert(i + 1, 2)))
            )


if __name__ == '__main__':
    n = int(input())
    print_formatted(n)

更新

我决定使用内置函数并修剪前两个字符(即0b),而不是遍历整个等式,以便它很好地适应格式。我试图根据二进制输出的宽度将它们彼此分开,但我想不出一种方法。这是我目前所拥有的:

def convert(num, base):
    # get the highest power
    val = ''
    hex_char_list = ['A', 'B', 'C', 'D', 'E', 'F']

    if(base == 2):
        bin_num = bin(num)
        bin_list = list(bin_num)
        bin_list_2 = bin_list[2:]
        val = ''.join(bin_list_2)

    if(base == 8):
        oct_num = oct(num)
        oct_list = list(oct_num)
        oct_list_2 = oct_list[2:]
        val = ''.join(oct_list_2)

    if(base == 16):
        hex_num = hex(num)
        hex_list = list(hex_num)
        hex_list_2 = hex_list[2:]
        val = ''.join(hex_list_2)

        if val in hex_char_list:
            val = val.upper()

    return val

def print_formatted(number):
    # your code goes here
    width = len(convert(number, 2).format(number))

    for i in range(number):
        print(
            str(i + 1) + width + 
            str(convert(i + 1, 8)) + width + 
            str(convert(i + 1, 16)) + width + 
            str((convert(i + 1, 2)))
            )


if __name__ == '__main__':
    n = int(input())
    print_formatted(n)

【问题讨论】:

你得到的当前输出是什么? 什么十进制值?像往常一样,这个问题根本不涉及十进制值。 num 在你的方法被调用时已经是二进制的了。 【参考方案1】:

你的 elif 是多余的 - 如果你这样做 %2 结果只能是 0 或 1 - 不需要做不同的处理。


您的代码不会转换整数 - 您检查数字的模数,而不是您的基数(以及基数的更高幂)适合它的频率。

您需要为适合您的人数的基地获得尽可能高的力量。然后,您需要了解该数字适合您的数字的频率,从数字中减去它并继续该操作的其余部分。你把你的力量缩小一,然后继续直到你的num为0。然后你把所有的数字累加成一个字符串。

您的代码已修复:

def convert(num, base):
    # get the highest power
    power = 0
    while num // (base**(power+1)) > 0:
        power += 1

    # divide, remember, subtract - until down to the lowest power
    result = []
    while num >= 0:
        p = base**power
        if p == 1:
            result.append(num)
            break
        result.append(num // p)
        num -= result[-1]*p
        power -= 1

    return ''.join(map(str,result))

获得以下输出:

1 1 1 1
2 2 2 10
3 3 3 11
4 4 4 100
5 5 5 101
6 6 6 110
7 7 7 111
8 10 8 1000
9 11 9 1001
10 12 10 1010
11 13 11 1011
12 14 12 1100
13 15 13 1101
14 16 14 1110
15 17 15 1111
16 20 10 10000

或者你使用内置函数:

def make(i):
    for k in range(i+1):
        print(f"k:>10 bin(k):>10 hex(k):>10 oct(k):>10")
        # or slice away the prefixes:
        # print(f"k:>10 bin(k)[2:]:>10 hex(k)[2:]:>10 oct(k)[2:]:>10")


make(17)

结果:

         0        0b0        0x0        0o0
         1        0b1        0x1        0o1
         2       0b10        0x2        0o2
         3       0b11        0x3        0o3
         4      0b100        0x4        0o4
         5      0b101        0x5        0o5
         6      0b110        0x6        0o6
         7      0b111        0x7        0o7
         8     0b1000        0x8       0o10
         9     0b1001        0x9       0o11
        10     0b1010        0xa       0o12
        11     0b1011        0xb       0o13
        12     0b1100        0xc       0o14
        13     0b1101        0xd       0o15
        14     0b1110        0xe       0o16
        15     0b1111        0xf       0o17
        16    0b10000       0x10       0o20
        17    0b10001       0x11       0o21

【讨论】:

或者你可以使用'i:>#10 i:>#10b i:>#10x i:>#10o'.format(i=k)#请求前缀)。 @Onur 请发布新问题。你原来的答案已经回答了。这是关于字符串格式的新问题,与如何创建八进制/二进制/十六进制数字无关。除此之外 - 我的示例包括带空格的格式。只需计算最大数字的二进制宽度并相应地格式化。见***.com/questions/4302166/format-string-dynamically 和using-pythons-format-specification-mini-language-to-align-floats【参考方案2】:

问题是你只取你号码的 mod (num % base),也就是说最右边的(“最低有效”)位。我们想要的不是最不重要的位,而是整个分解。

注意:这里的问题也适用于所有其他基数(十进制、十六进制...)。

确实,如果你运行

n = 1000
print_formatted(n)

使用你的函数,你会得到 1000 在不同基础上的分解是:

1000 0 8 0

(都错了)。

在这里,我提出一个递归实现:

def convert(integerToConvert, base = 2):
    '''
    When given a num and a base, will get the 
    conversion of that number in that base
    '''

    # The negative integer case is not taken into account
    if (integerToConvert < 0):
        print("ERROR: INTEGER < 0")
        return;

    # When the integer is 0, we know that we are done. There is no more bit
    if (integerToConvert == 0):
        print("WE ARE DONE")
        return;

    # get the current least significant coeff in the integerToEncode
    currentLeastSignificant = integerToConvert % base;
    print(currentLeastSignificant)

    # remove the least significant coeff and start again
    convert((integerToConvert - currentLeastSignificant) / base, base)

我进行了一些快速测试:

convert(17, 2)
1
0.0
0.0
0.0
1.0
WE ARE DONE

convert(16, 2)
0
0.0
0.0
0.0
1.0
WE ARE DONE

convert(17, 16)
1
1.0
WE ARE DONE

NB1:我打印数字,但您可以将它们存储在您选择的数据结构中。

NB2:最显着的系数排在最后(您可以与您的预期结果进行比较)

NB3:所有这些计算都有点昂贵,所以如果速度对你很重要,最好的办法实际上是将所有分解存储在数组中并访问它们(恒定时间)。

【讨论】:

嘿伙计。我刚看到你的回答。出于欣赏,我给了你一个赞成票。如果您认为这是一个很好的问题,您能否也给我一个赞成票? @OnurOzbek 我已经对这个问题投了赞成票。我希望答案有所帮助,尽管它可能比 Patrick Artner 的效率低(我不知道模式的时间复杂度是多少......)

以上是关于将十进制值转换为二进制、十六进制和八进制的单个函数不会转换为二进制的主要内容,如果未能解决你的问题,请参考以下文章

在 java 中,是不是可以使用 char 函数将 0 到 15 的十进制值转换为十六进制字符?

如何在 Python 中将单个字符转换为其十六进制 ASCII 值?

在 PHP 中将十六进制颜色转换为 RGB 值

PHP如何将从二进制文件中读取的字节转换为数字

节点红色在函数节点中将字节转换为十进制

excel怎样把数字转换成16进制