大多数十岁的孩子都知道如何做到这一点:使用长除法!1
代码
def finite_long_division(n,d)
return nil if d.zero?
sign = n*d >= 0 ? '' : '-'
n, d = n.abs, d.abs
pwr =
case n <=> d
when 1 then power(n,d)
when 0 then 0
else -power(d,n)-1
end
n *= 10**(-pwr) if pwr < 0
d *= 10**(pwr) if pwr >= 0
s = ld(n,d)
t = s.size == 1 ? '0' : s[1..-1]
"%s%s.%s x 10^%d" % [sign, s[0], t, pwr]
end
def power(n, d)
ns = n.to_s
ds = d.to_s
pwr = ns.size - ds.size - 1
pwr += 1 if ns[0, ds.size].to_i >= ds.to_i
pwr
end
def ld(n,d)
s = ''
loop do
m,n = n.divmod(d)
s << m.to_s
return s if n.zero?
n *= 10
end
end
例子2
finite_long_division(1, 2**15)
请注意,每个有理数都具有十进制表示或包含无限重复的数字序列(例如,
1/3#=> 0.33333 ...
,
3227/555#=> 5.8144144144 ...
和
1/9967#=> 0.00010033109260559848 ...
3)。如果有理数是重复序列类型,则此方法永远不会终止。由于通常无法事先知道有理数属于哪种类型,因此修改该方法以首先确定有理数是否具有有限的十进制表示可能很有用。已知不能通过消除公共因素来减少(即最简形式)的有理数
n/d
仅当
d
可被
2
或
5
整除且不能被任何其他质数整除时才具有此属性。
4我们可以轻松构建一个方法来确定已约简的有理数是否具有该属性。
require 'prime'
def decimal_representation?(n, d)
primes = Prime.prime_division(d).map(&:first)
(primes & [2,5]).any? && (primes - [2, 5]).empty?
end
1 至少在我小时候是这样的。
2 请参见此处,其中列出了具有有限小数表示的有理数的部分列表。
3 这个有理数的重复序列包含9,966位数字。
4 参考文献.
2**15 #=> 32768
- Sagar Pandya