浮动到二进制

Ant*_*Ant 6 python floating-point binary

我正在尝试将浮点数转换为二进制表示; 我该怎么做到这一点?然而,我的目标是不受2米的限制,因此我希望能够轻松扩展到任何基础(3,4,8)ecc.

到目前为止,我对整数有一个简单的实现:

import string

LETTER = '0123456789' + string.ascii_lowercase
def convert_int(num, base):
    if base == 1:
        print "WARNING! ASKING FOR BASE = 1"
        return '1' * num if num != 0 else '0'

    if base > 36: raise ValueError('base must be >= 1 and <= 36')

    num, rest = divmod(num, base)
    rest = [LETTER[rest]]
    while num >= base:
        num, r = divmod(num, base)
        rest.append(LETTER[r])
    rest.reverse()
    return (LETTER[num] if num else '') + ''.join(str(x) for x in rest)
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏:)

编辑:

def convert_float(num, base, digits=None):
    num = float(num)
    if digits is None: digits = 6

    num = int(round(num * pow(base, digits)))
    num = convert_int(num, base)
    num = num[:-digits] + '.' + num[:digits]
    if num.startswith('.'): num = '0' + num
    return num
Run Code Online (Sandbox Code Playgroud)

是对的吗?为什么我会这样做?

>>> convert_float(1289.2893, 16)
'509.5094a0'
>>> float.hex(1289.2983)
'0x1.42531758e2196p+10'
Run Code Online (Sandbox Code Playgroud)

ps 如何将浮点数转换为二进制?

我已经阅读了那个讨论,但我没有得到答案..我的意思是,它只适用于0.25,0.125?我不明白"必须按相反顺序"这句话......

stm*_*tmi 16

对于浮点数,有内置方法hex().

http://docs.python.org/library/stdtypes.html#float.hex

它为您提供给定数字的十六进制表示.从十六进制到二进制的翻译形式是微不足道的.

例如:

In [15]: float.hex(1.25)
Out[15]: '0x1.4000000000000p+0'

In [16]: float.hex(8.25)
Out[16]: '0x1.0800000000000p+3'
Run Code Online (Sandbox Code Playgroud)

  • 应该有一条规则反对“陈述某事是微不足道的”。尤其是在不解释的情况下。-1 (6认同)
  • +1,但你可以解释如何实现这一目标吗?;) (3认同)
  • @stmi:你怎么在这里为''0x1.0800000000000p + 3'"从十六进制转换为二进制"?谢谢!` (3认同)
  • @stmi:我的意思当然是一种编程方式,即如何使用python将''0x1.0800000000000p + 3'`翻译为''1000.01' (3认同)

stm*_*tmi 12

下一步回答一点理论.

以下说明并未解释IEEE浮点标准仅涉及浮点数表示的一般概念

每个浮点数表示为小数部分乘以指数乘以符号.另外,所谓的指数偏差,将在下面解释.

所以我们有

  1. 签名位
  2. 分数部分数字
  3. 指数部分数字

具有8位分数和8位指数的基数2的示例

小数部分中的位告诉我们从下面的序列中将哪些加数(要添加的数字)包括在所表示的数值中

2 ^ -1 + 2 ^ -2 + 2 ^ -3 + 2 ^ -4 + 2 ^ -5 + 2 ^ -6 + 2 ^ -7 + 2 ^ -8

因此,如果您在分数部分中说01101101,则会给出

0*2 ^ -1 + 1*2 ^ -2 + 1*2 ^ -3 + 0*2 ^ -4 + 1*2 ^ -5 + 1*2 ^ -6 + 0*2 ^ -7 + 1*2 ^ -8 = 0.42578125

现在可以表示的非零数字落在2**-8 = 0.00390625和1 - 2** - 8 = 0.99609375之间

这里指数部分进来.指数允许我们通过将分数部分乘以指数来表示非常大的数字.因此,如果我们有一个8位指数,我们可以将得到的分数乘以0到2 ^ 255之间的数字.

所以回到上面的例子,让我们的指数为11000011 = 195.

我们有01101101 = 0.42578125的分数部分和指数部分11000011 = 195.它给出了我们的数字0.42578125*2 ^ 195,这是非常大的数字.

到目前为止,我们可以表示2 ^ -8*2 ^ 0和(1-2 ^ -8)*2 ^ 255之间的非零数字.这允许非常大的数字但不是非常小的数字.为了能够代表小数,我们必须在指数中包含所谓的偏差.它是一个总是从指数中减去的数字,以便允许表示小数字.

让我们偏向127.现在所有指数都减去127.所以可以表示的数字在2 ^ -8*2 ^(0 - 127)和(1-2 ^ -8)*2 ^(255 - 127)之间= 128)

示例号现在是0.42578125*2 ^(195-127 = 68),这仍然很大.

示例结束

为了更好地理解这一点,尝试尝试不同的基数和大小的分数和指数部分.一开始不要尝试使用奇数基数,因为它只会使必要的事情复杂化.

一旦掌握了这种表示的工作原理,你就应该能够编写代码来获得任何基数,分数/指数部分组合中任何数字的表示.


dan*_*n04 8

如果要将a转换为十进制小数点后的数字float字符串:d

  1. 将数字乘以base**d.
  2. 舍入到最接近的整数.
  3. 将整数转换为字符串.
  4. 在结束前插入.字符d数字.

例如,在基数12中表示0.1,带有4个十进制位数,

  1. 0.1×12 4 = 2073.6
  2. 舍入到最接近的整数→2074
  3. 转换为字符串→ 124A
  4. 添加小数点→ 0.124A