简体   繁体   English

如何在python中将浮点数转换为基数3

[英]How to convert floating point number to base 3 in python

How does one convert a base-10 floating point number in Python to a base-N floating point number?如何将 Python 中的基数为 10 的浮点数转换为基数为 N 的浮点数?

Specifically in my case, I would like to convert numbers to base 3 (obtain the representation of floating point numbers in base 3), for calculations with the Cantor set .特别是在我的情况下,我想将数字转换为基数 3(获得基数为 3 的浮点数的表示),以使用Cantor set进行计算。

After a bit of fiddling, here's what I came up with.经过一番摆弄,这就是我想出的。 I present it to you humbly, keeping in mind Ignacio's warning.我谨记伊格纳西奥的警告,谦虚地呈现给你。 Please let me know if you find any flaws.如果您发现任何缺陷,请告诉我。 Among other things, I have no reason to believe that the precision argument provides anything more than a vague assurance that the first precision digits are pretty close to correct.除其他事项外,我没有理由相信precision参数提供的只是一个模糊的保证,即第一个precision数字非常接近正确。

def base3int(x):
    x = int(x)
    exponents = range(int(math.log(x, 3)), -1, -1)
    for e in exponents:
        d = int(x // (3 ** e))
        x -= d * (3 ** e)
        yield d

def base3fraction(x, precision=1000):
    x = x - int(x)
    exponents = range(-1, (-precision - 1) * 2, -1)
    for e in exponents:
        d = int(x // (3 ** e))
        x -= d * (3 ** e)
        yield d
        if x == 0: break

These are iterators returning ints.这些是返回整数的迭代器。 Let me know if you need string conversion;如果您需要字符串转换,请告诉我; but I imagine you can handle that.但我想你能应付得了。

EDIT: Actually looking at this some more, it seems like a if x == 0: break line after the yield in base3fraction gives you pretty much arbitrary precision.编辑:实际上再看看这个,似乎if x == 0: breakbase3fractionyield之后base3fraction给了你几乎任意的精度。 I went ahead and added that.我继续补充说。 Still, I'm leaving in the precision argument;尽管如此,我还是要离开precision论点; it makes sense to be able to limit that quantity.能够限制该数量是有意义的。

Also, if you want to convert back to decimal fractions, this is what I used to test the above.另外,如果你想转换回十进制分数,这就是我用来测试上面的。

sum(d * (3 ** (-i - 1)) for i, d in enumerate(base3fraction(x)))

Update更新

For some reason I've felt inspired by this problem.出于某种原因,我受到了这个问题的启发。 Here's a much more generalized solution.这是一个更通用的解决方案。 This returns two generators that generate sequences of integers representing the integral and fractional part of a given number in an arbitrary base.这将返回两个生成器,它们生成表示任意基数中给定数字的整数部分和小数部分的整数序列。 Note that this only returns two generators to distinguish between the parts of the number;请注意,这仅返回两个生成器来区分数字的部分; the algorithm for generating digits is the same in both cases.在这两种情况下,生成数字的算法是相同的。

def convert_base(x, base=3, precision=None):
    length_of_int = int(math.log(x, base))
    iexps = range(length_of_int, -1, -1)
    if precision == None: fexps = itertools.count(-1, -1)
    else: fexps = range(-1, -int(precision + 1), -1)

    def cbgen(x, base, exponents):
        for e in exponents:
            d = int(x // (base ** e))
            x -= d * (base ** e)
            yield d
            if x == 0 and e < 0: break

    return cbgen(int(x), base, iexps), cbgen(x - int(x), base, fexps)

Although 8 years have passed, I think it is worthwhile to mention a more compact solution.虽然已经过去了 8 年,但我认为还是值得提一个更紧凑的解决方案。

def baseConversion( x=1, base=3, decimals=2 ):
    import math
    n_digits = math.floor(-math.log(x, base))#-no. of digits in front of decimal point
    x_newBase = 0#initialize
    for i in range( n_digits, decimals+1 ):
        x_newBase = x_newBase + int(x*base**i) % base * 10**(-i)
    return x_newBase

For example calling the function to convert the number 5+1/9+1/27例如调用函数来转换数字 5+1/9+1/27

def baseConversion( x=5+1/9+1/27, base=3, decimals=2 ) 
12.01
def baseConversion( x=5+1/9+1/27, base=3, decimals=3 ) 
12.011

You may try this solution to convert a float string to a given base.您可以尝试使用此解决方案将浮点字符串转换为给定的基数。

def eval_strint(s, base=2):
    assert type(s) is str
    assert 2 <= base <= 36
    ###
    ### YOUR CODE HERE
    ###
    return int(s,base)

def is_valid_strfrac(s, base=2):
    return all([is_valid_strdigit(c, base) for c in s if c != '.']) \
        and (len([c for c in s if c == '.']) <= 1)
    
def eval_strfrac(s, base=2):
assert is_valid_strfrac(s, base), "'{}' contains invalid digits for a base-{} number.".format(s, base)

stg = s.split(".")
float_point=0.0
if len(stg) > 1:
    float_point = (eval_strint(stg[1],base) * (base**(-len(stg[1]))))
stg_float = eval_strint(stg[0],base) + float_point
return stg_float

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM