e$B86$G$9!#e(B
e$B$U$J$P$G$9!#e(B
Common Lisp e$B$G$O!"e(Binteger-decode-floate$B!"e(BHaskell e$B$G$Oe(B decodeFloat e$B$,$“e(B
e$B$k$N$G!“0lHL$N%W%m%0%i%^$,e(B rational/rationalize e$B$N$h$&$J$b$N$r=q$1$k$He(B
e$B;W$$$^$9!#e(Bruby e$B$G$be(B Float#decode e$B$N$h$&$J$b$N$,$”$C$F$b$$$$$N$+$b$7$le(B
e$B$J$$!”$H;W$$$^$7$?!#e(B
Float#decode e$B$H$$$&$N$O!"8=:_$G$be(B
class Float
def decode
f, e = Math.frexp(self)
[Math.ldexp(f, Float::MANT_DIG).floor, e - Float::MANT_DIG]
end
end
e$B$H=q$1$k$N$G$O$J$$$+$J!#e(B
e$B$3$l$r$b$&$9$3$70BA4$K$7$F#C$G<BAu$7$?$H$7$F$b7k9=C1=ce(B
e$B$J$N$G!"$=$l$re(B Float#to_r e$B$K$7$F$b$^$:$/$O$J$$$+$J$H$$$&e(B
e$B5$$b$7$F$-$^$7$?!#$&!<$`!#e(B
e$B$?$H$($P!“e(Be=0 e$B$r%G%U%)%k%H$K$9$k!”$H$$$&$3$H$G$b$$$$$+$b$7$l$J$$$G$9$M!#e(B
Common Lisp e$B$Ne(B rationalize e$B$O!“e(Be e$B$,M?$($i$l$J$$$N$G!”$I$&$7$F$$$k$N$+e(B
e$B$H;W$C$?$s$G$9$,!"e(Bclisp e$B$N%=!<%9$r$A$g$C$H8+$?$H$3$m$G$O!“85$N2>?t$d;Xe(B
e$B?t$K4p$$$?7W;;$,$”$j$^$9$M!#e(B
clisp e$B$G$9$+!"!"!"$A$g$C$H8+$F$_$^$7$?$,e(B r e$B$KBP$9$ke(B e
e$B$NCM$,$@$$$?$$!“e(B
f0, e0 = r.decode e$B$H$7$?$H$-$Ne(B 2**e0/2
e$B$K$J$C$F$^$9$M!#$?$V$s$3$l$Ge(B
e$B$$$$$s$@$m$&$J$”!#e(B
e$B$3$l$r<h$jF~$l$F!"99$Ke(B[ruby-dev:28544]
e$B$r%k!<%W$G=q$-D>$9$H!"e(B
def rationalize(r, e = nil)
return(-rationalize(-r, e)) if r < 0
if e
raise ArgumentError, “negative precision” if e < 0
x = Rational(r - e)
y = Rational(r + e)
return x if x == y
xn, xd = x.numerator, x.denominator
yn, yd = y.numerator, y.denominator
else
f0, e0 = r.decode
return f0 << e0 if e0 >= 0
xn, xd = 2*f0 - 1, 1 << (1 - e0)
yn, yd = 2*f0 + 1, 1 << (1 - e0)
end
a, b, c, d = 1, 0, 0, 1
while true
xq, xr = xn.divmod(xd)
yq, yr = yn.divmod(yd)
if xr.zero?
return Rational(a*xq + b, c*xq + d)
elsif xq < yq
return Rational(a*(xq + 1) + b, c*(xq + 1) + d)
elsif xq > yq
raise "implementation error"
end
a, b, c, d = a*xq + b, a, c*xq + d, c
xn, xd, yn, yd = yd, yr, xd, xr
end
end
e$B$H$J$j$^$7$?!#e(B
e$B$$$:$l$K$7$F$b!“e(Brationalize e$BAjEv$O!”$"$l$P$$$$$J!"$/$i$$$@$H;W$&$N$G!"e(B
e$B:#$9$0<BAu$G$-$J$/$F$b$$$$$H;W$$$^$9$,!#e(B
e$B$d$O$j$3$l$OLLGr$$$N$G!"e(Brational.c
e$B$K4^$a$F$_$k$3$H$K$7$^$7$?!#e(B
class Float
def -(y)
(rationalize - y.rationalize).to_f
end
end
p 61.1 - 60.0 == 1.1 #=> true
e$B$H$+$G$-$F!"$+$J$j%J%$%9$G$9!#e(B