使用Python 2.7

时间:2016-01-22 06:05:58

标签: python python-2.7 rounding

大家好我对python很新,这是我的第一个项目。我正在创建一个计算器,当我进入圆的周长时,它将为我计算直径。比如摩托车上的把手没有取下把手。

我得到了它的工作,但我真的需要它不那么准确,就像可以四舍五入到最接近的1/8。如果我输入2.75它的效果很好,但如果我输入2.76则会给出疯狂的分数。我仍然希望它读到7/8,直到它超过1.0的一半

这是我到目前为止所提供的任何帮助都会很棒。

from fractions import Fraction

print "Do you wish to calculate the Diameter or Radius from a perimeter measurement? Type 'd' or 'r'"
var = raw_input("Please type 'd' or 'r'")


if var == 'd':
    print "Now type the perimeter measurement for the diameter you would like calculate."
    cir = float(raw_input())
    answer = cir/3.1415926535
    rnd = round(answer, 3 )
    frac = Fraction(rnd).limit_denominator()
    print rnd
    print "The diameter of a %s perimeter is" % cir, frac
elif var == 'r':
    print "Now type the perimeter measurement for the Radius you would like to calculate."
    cir = float(raw_input())
    answer = cir/3.1415926535/2
    print "The Radius of a %s perimeter is" % cir, answer 
else:
    print "Error: You did not type 'd' or 'r' Please run again"

3 个答案:

答案 0 :(得分:1)

如果你需要相同的分母,这很简单。

denominator = 8
rnd = round(answer * denominator)
frac = Fraction(int(rnd), denonimator)

答案 1 :(得分:0)

您可以将其四舍五入到最接近的1/8。

In [1]: from fractions import Fraction

In [14]: Fraction(round(2.6*8)/8).limit_denominator()
Out[14]: Fraction(21, 8)

In [4]: Fraction(round(2.75*8)/8).limit_denominator()
Out[4]: Fraction(11, 4)

In [5]: Fraction(round(2.9*8)/8).limit_denominator()
Out[5]: Fraction(23, 8)

答案 2 :(得分:0)

之前的所有方法都使用错误的round(x*8)/8方法;当然,当我赶时间的时候,我会(通常不会)使用它,但这是一种错误的方法。

方法1(最正统的)

根据连续分数理论,有四个最佳近似值到2.76,即:

2, 3, 11/4, 69/25

你可以说11/4与22/8相同(如所要求的那样),但是你不能期望它能以任何数字的方式工作。以Pi为例; round(3.1415926*8)/8是25/8,与22/7相比是一个非常差的近似值: 22/7实际上接近Pi到1/8,但甚至更好(虽然比25/8更简单)!< / strong>原始海报想要近似1/8。看看以下三个部分:22 / 7,25 / 8,314 / 100;所有近似Pi到1/8,但你会选择哪一个(可能是第一个;现在:第一个不仅是三个分数中最简单的一个;它也是最准确的)?比22/7好的最简单的部分跳跃到精度不到1e-4(即333/106)!

此外,如果你想要接近0.5,你就不能满意4/8!当然fractions模块可能会在初始化时将其取消,但这无论如何都是一个非常糟糕的迹象:你的方法不希望产生类似4/8的东西,即使是作为中间步骤!

一个笑话:取0.33333333 ...并尝试round(x*8)/8方法;你会发现3/8接近0.33333333 ......到1/8,这当然是真的,但......如何礼貌地说出来?

看看以下功能;你可以放心地依靠它来逼近一个数字:

from fractions import Fraction                                              

def rationalize(x, maxden=1000):
    p0, p1 = 0, 1
    q0, q1 = 1, 0
    a = int(x) if x >= 0 else int(x-1)
    while q1 <= maxden:
        p = a*p1 + p0
        q = a*q1 + q0
        p0, p1 = p1, p
        q0, q1 = q1, q
        if x==a:
            if q1 <= maxden: return Fraction(p1, q1)
            else: return Fraction(p0, q0)
        x = 1/(x-a)
        a = int(x)
    return Fraction(p0, q0)

如果您使用maxden=8的Pi进行尝试,则会得到预期的22/7(并且不再是疯狂的25/8)。

该函数将收敛返回到由数字的连续分数扩展中的连续部分商构建的数字。请参阅https://en.wikipedia.org/wiki/Diophantine_approximation

上的说明

方法2

某些计算机代数系统也使用线性整数关系算法(例如PSLQ)来解决这个问题;例如,Sympy使用mpmath.pslq方法来执行此操作。它非常方便,并且它给出了良好的结果,因为PSLQ返回向量,给出1和x之间的整数关系和最小的范数。但它仍然比其他方法更复杂。