我正在尝试将浮点数转换为二进制表示;我该怎么做到这一点? 然而,我的目标不是限制在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)
任何帮助表示赞赏:)
编辑:
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
是吗?为什么我会这样做?
>>> convert_float(1289.2893, 16)
'509.5094a0'
>>> float.hex(1289.2983)
'0x1.42531758e2196p+10'
P.S。 How to convert float number to Binary?
我已经阅读了那个讨论,但我没有得到答案..我的意思是,它只适用于0.25,0.125?我不明白“必须按相反顺序”这句话......
答案 0 :(得分: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'
答案 1 :(得分:12)
接下来回答一下理论。
以下说明并未解释IEEE浮点数标准仅涉及浮点数表示的一般概念
每个浮点数表示为小数部分乘以指数乘以符号。此外,所谓的指数偏差,将在下面解释。
所以我们有
具有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),这仍然很大。
示例结束
为了更好地理解这一点,尝试尝试不同的基数和大小的分数和指数部分。一开始不要尝试使用奇数基数,因为它只会使必要的事情复杂化。
一旦掌握了这种表示的工作原理,你就应该能够编写代码来获得任何基数,分数/指数部分组合中任何数字的表示。
答案 2 :(得分:8)
如果要将float
转换为十进制小数点后d
位的字符串:
base**d
。.
个字符d
数字。例如,在基数12中用0.1 十进制十几个位置表示0.1,
124A
0.124A
答案 3 :(得分:1)
这与您想要的二进制表示形式不同,但这会将IEEE 754转换为它的符号,尾数和基数,可用于以相当简单的方式创建十六进制表示。请注意,尾数的“值”是1 + BINARY,其中BINARY是二进制表示 - 因此返回中为-1。
我写了这段代码并宣布它是公共领域。
def disect_float(f):
f = float(f); #fixes passing integers
sign = 0x00; #positive
exp = 0;
mant = 0;
if(f < 0): #make f positive, store the sign
sign = '-'; #negative
f = -f;
#get the mantissa by itself
while(f % 1 > 0): #exp is positive
f*=2
exp+=1
#while(f % 1 > 0):
tf = f/2;
while(tf % 1 <= 0): #exp is negative
exp-=1;
f=tf;
tf=f/2;
if(exp < -1024): break;
mant=int(f);
return sign, mant-1, exp;
答案 4 :(得分:1)
我发现有一个技巧可以使用简单的字符串操作来完成。我觉得这种方法比遇到的其他方法更简单。
echo '<div class="name_form">
<input type="text" name="field1" id="diploma_name" value=" " placeholder=" name "required="required">
<button name="submit" id="diploma_submit" value="submit"> Scrie-ți numele pentru a personaliza diploma!</button>
</div>
<div style="margin-top: 50px;" id="diploma_name_display">
</div>
<script>
jQuery(document).ready(function(){
jQuery("#diploma_submit").click(function() {
var firstfield_value = jQuery("#diploma_name").val();
jQuery("#diploma_name_display").html( "<strong>" + firstfield_value +"</strong>" );
c = navigator.userAgent.search("Firefox");
if (c > -1) {
jQuery("#diploma_name_display").css("margin-top: 50px;");
}
// $.window.stop(); //don't mind this, I have added this to stop the page from refreshing so my boss thinks this actually work.
} );
});
</script>';
输出:
s = "1101.0101"
s1, s2 = s.split(".")
s1 = int(s1, 2)
s2 = int(s2, 2)/(2**len(s2))
x = s1+s2
print(x)
希望对某人有帮助。
答案 5 :(得分:0)
直接回答标题并使用使用64位IEE754的float.hex,可以编写这个方法:
def float_to_bin(x):
if x == 0:
return "0" * 64
w, sign = (float.hex(x), 0) if x > 0 else (float.hex(x)[1:], 1)
mantissa, exp = int(w[4:17], 16), int(w[18:])
return "{}{:011b}{:052b}".format(sign, exp + 1023, mantissa)
float_to_bin(-0.001) # '1011111101010000000010110011111101011000011011100110110100101010'
但请注意,这不适用于NaN和Inf。