浮动到二进制 [英] Float to binary
问题描述
但是,我的目标是不被2米限制,所以我希望能够很容易地扩展到任何基地(3,4,8)。 $ b
到目前为止,对于整数我有一个简单的实现:
导入字符串
bt LETTER ='0123456789'+ string.ascii_lowercase
def convert_int(num,base):
if base == 1:
printWARNING!ASKING FOR BASE = 1
返回'1'* num如果num!= 0 else'0'
如果base> 36:raise ValueError('base必须是> = 1且< = 36')
num,rest = divmod(num,base)
rest = [LETTER [rest]]
while num> base:
num,r = divmod(num,base)
rest.append(LETTER [r])
rest.reverse()
返回(LETTER [num] if num else'')+''.join(str(x)for x in rest)
任何帮助表示赞赏:)
编辑:
def convert_float(num,base,digits = None):
num = float(num)
如果digits是None:digits = 6
num = int (数字* 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'
我已经阅读过这个讨论,但是我没有得到答案..我的意思是,它只适用于0.25,0.125吗?我不明白'必须以相反的顺序'...
接下来用一点理论回答。 / p>
下面的解释并不能解释IEEE浮点标准中关于表示浮点数的一般思想
每个浮点数都表示为小数部分乘以指数乘以符号。另外,所谓的指数偏差,将在下面解释。
所以我们有
$ ol
以8位小数和8位指数为基数2的示例 小数部分的位告诉我们哪些加数(要添加的数字)被包括在所表示的数值中 所以,如果你有小数部分说01101101它给 现在可以表示的非零数字在 因此,回到上面的例子,让我们取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),这个数字还是相当大的。 示例结束 为了更好地理解这个问题,尝试使用分数和指数部分的不同基数和大小。一开始不要尝试奇怪的基础,因为它只会使事情复杂化。 一旦你掌握了这种表示的工作原理,你应该能够编写代码来获得任何数字在任何基数,分数/指数部分组合。 I'm trying to convert a floating point number to binary representation; how can I achieve this?
My goal is, however, not to be limited by 2m so I'm hoping for something that could be easily extended to any base (3, 4, 8) ecc. I've got a straightforward implementation so far for integers: any help appreciated :) edit: is that right? why do i get this behaviour? p.s.
How to convert float number to Binary? I've read that discussion, but I don't get the answer.. I mean, does it work only for 0.25, 0.125? and I dont understand the phrase 'must be in reverse order'... Next answer with a bit of theory. Explanation below does not explain IEEE Floating Point standard only general ideas concerning representation of floating point numbers
2 ^ -1 + 2 ^ -2 + 2 ^ -3 + 2 ^ - 4 + 2 ^ -5 + 2 ^ -6 + 2 ^ -7 + 2 ^ -8
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之间的数字。
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'
Every float number is represented as a fractional part multiplied by an exponent multiplied by a sign. Additionally there is so called bias for exponent, which will be explained bellow.
So we have
- Sign bit
- Fractional part digits
- Exponent part digits
Example for base 2 with 8 bit fraction and 8 bit exponent
Bits in fraction part tell us which summands (numbers to be added) from sequence below are to be included in represented number value
2^-1 + 2^-2 + 2^-3 + 2^-4 + 2^-5 + 2^-6 + 2^-7 + 2^-8
So if you have say 01101101 in fractional part it gives
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
Now non-zero numbers that are representable that way fall between 2 ** -8 = 0.00390625 and 1 - 2**-8 = 0.99609375
Here the exponent part comes in. Exponent allows us to represent very big numbers by multiplying the fraction part by exponent. So if we have an 8bit exponent we can multiply the resulting fraction by numbers between 0 and 2^255.
So going back to example above let's take exponent of 11000011 = 195.
We have fractional part of 01101101 = 0.42578125 and exponent part 11000011 = 195. It gives us the number 0.42578125 * 2^195, this is really big number.
So far we can represent non-zero numbers between 2^-8 * 2^0 and (1-2^-8) * 2^255. This allows for very big numbers but not for very small numbers. In order to be able to represent small numbers we have to include so called bias in our exponent. It is a number that will be always subtracted from exponent in order to allow for representation of small numbers.
Let's take a bias of 127. Now all exponents are subtracted 127. So numbers that can be represented are between 2^-8 * 2^(0 - 127) and (1-2^-8) * 2^(255 - 127 = 128)
Example number is now 0.42578125 * 2^(195-127 = 68) which is still pretty big.
Example ends
In order to understand this better try to experiment with different bases and sizes for fractional and exponential part. At beginning don't try with odd bases because it only complicates things necessary.
Once you grasp how this representation works you should be able to write code to obtain representation of any number in any base, fractional/exponential part combination.
这篇关于浮动到二进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!