作为一名年轻的程序员,我总是试图寻找我的技能应用。
无论如何,我现在正在接受三角形,我们正在研究单位圆,从度数转换为坐标的公式是(sinθ,cosθ)(据我所知)。
然而,我遇到的困难是我需要将值保持为分数。
基本上,我计划的算法是:
i = 0
while i < 360:
print(i, "=", calc(i))
i += 15
现在,calc可以给出任何名称,并且将是一个函数,它返回x和y的坐标(可能是一个元组)给定x =sinθ和y =cosθ。
我遇到的问题是Python中的sin会返回介于-1和1之间的浮点,但是,我需要找到一种让它返回分数的方法。例如,在this picture中,坐标是有理数。
我该怎么办?我应该编写自己的正弦函数和余弦函数吗?如果是,我应该怎么做?
答案 0 :(得分:5)
您似乎需要第三方模块,例如sympy:
>>> import sympy
>>> for i in range(0, 360, 15):
... print i, sympy.sin(sympy.Rational(i, 180) * sympy.pi)
...
0 0
15 sin(pi/12)
30 1/2
45 2**(1/2)/2
60 3**(1/2)/2
75 sin(5*pi/12)
90 1
105 sin(5*pi/12)
120 3**(1/2)/2
135 2**(1/2)/2
150 1/2
165 sin(pi/12)
180 0
195 -sin(pi/12)
210 -1/2
225 -2**(1/2)/2
240 -3**(1/2)/2
255 -sin(5*pi/12)
270 -1
285 -sin(5*pi/12)
300 -3**(1/2)/2
315 -2**(1/2)/2
330 -1/2
345 -sin(pi/12)
答案 1 :(得分:4)
您是否尝试过fraction模块?我自己从未使用它,但对于这个问题一目了然。
答案 2 :(得分:0)
我能想到的最好的方法是取十进制数并将其变成一个分数,就像你在六年级时那样。例如.5 - &gt; 1 / .5 = 2 - &gt; 1/2
答案 3 :(得分:0)
正如伊格纳西奥在评论中所说,对于大多数角度,你不能代表正弦和余弦作为分数,因为它们是无理数。因此编写自己的正弦和余弦函数无济于事。 (你可以尝试一下;它是一个有趣的练习,但它们会非常慢。在Python中构建的正弦和余弦的实现是用C语言编写的,基于可能已有40年历史的代码和几代计算机科学家已经对它们进行了优化,因此你可能无法做得更好。)
事实上,即使对于圆度数的角度,您通常也不能将正弦和余弦表示为分数,但在许多情况下,您可以将它们的正方形表示为分数。所以我建议计算正弦平方和余弦平方。 (以45度为例)
当然,即使使用一个漂亮的圆角,你也不会从(平方)正弦和余弦函数中得到一小部分,因为它们会返回浮点数。你最好的办法是将(近似的)十进制数转换成分数。您可以按照建议by mangobug使用fraction
模块执行此操作;如果你这样做,请自由使用limit_denominator
函数,因为你知道你正在寻找的分数有小分母。或者,您可以自己编写算法;这是另一项有益的练习。
最后,一个提示:它实际上是对应于余弦的x坐标和与正弦的y坐标,假设你的角度是以通常的方式定义的。
答案 4 :(得分:0)
以下示例找到30度的cos将帮助您了解如何做到这一点
>>> angle=30*math.pi/180 #30 degree in randian
>>> cosine = math.cos(angle) #Lets find the cosine of 30 degree
>>> #Square it. Helps to represent a range of irrational numbers to rational numbers
>>> cos2 = cosine ** 2
>>> # Lets drop some precision. Don't forget about float approximation
>>> cos2 = round(cos2,4)
>>> num = fractions.Fraction(cos2).numerator #Just the Numerator of the fraction
>>> den = fractions.Fraction(cos2).denominator #The denominator of the fraction
>>> def PerfSquare(n): #Square root in an Integer
return int(n**0.5)**2 == n
# If Perfect Square then Find the Square root or else represent as a root
>>> num = str(num**0.5) if PerfSquare(num) else "root{0}".format(num) # If Perfect Square then Find the Square root or else represent as a root
>>> den = str(den**0.5) if PerfSquare(den) else "root{0}".format(den)
>>> cos = "{0}/{1}".format(num,den) #Combine Numerator and Denominator
>>> print cos
root3/2.0
这是上述原则的功能
>>> HIGHVALUE=1000
>>> def foo(degree,trigfn):
angle=degree*math.pi/180 #in randian
trigval = trigfn(angle) #Lets find the trig function
#Square it. Helps to represent a range of irrational numbers to rational numbers
trigval2 = trigval ** 2
# Lets drop some precission. Don't forget about float aproximation
trigval2 = round(trigval2,5)
if trigval > HIGHVALUE:
return u'\u221e'
num = fractions.Fraction(trigval2).numerator #Just the Numerator of the fraction
den = fractions.Fraction(trigval2).denominator #The denominator of the fraction
if (num > HIGHVALUE or den > HIGHVALUE):
trigval2 = round(1/trigval2,4)
den = fractions.Fraction(trigval2).numerator #Just the Numerator of the fraction
num = fractions.Fraction(trigval2).denominator #The denominator of the fraction
if num > HIGHVALUE or den > HIGHVALUE or num < 1 or den < 1:
#Cannot be represented properly
#Just return the value
return str(round(trigval,4))
# If Perfect Square then Find the Square root or else represent as a root
num = str(int(num**0.5)) if PerfSquare(num) else u"\u221a{0}".format(num)
den = str(int(den**0.5)) if PerfSquare(den) else u"\u221a{0}".format(den)
return u"{0}".format(num) if den == "1" else u"{0}/{1}".format(num,den) #Combine Numerator and Denominator
运行结果
>>> def Bar():
print 'Trig\t'+'\t'.join(str(x) for x in xrange(0,91,15))
for fn in [math.sin,math.cos,math.tan]:
print fn.__doc__.splitlines()[0],'\t',
print '\t'.join(foo(angle,fn) for angle in xrange(0,91,15) )
>>> Bar()
Trig 0 15 30 45 60 75 90
sin(x) 0.0 0.2588 1/2 1/√2 √3/2 0.9659 1
cos(x) 1 0.9659 √3/2 1/√2 1/2 0.2588 0.0
tan(x) 0.0 0.2679 1/√3 1 √3 3.7321 ∞