```ごとけんです

In message "[ruby-math:00140] Re: %  &  divmod() & remainder()"
on 00/01/27, GOTO Kentaro <gotoken / math.sci.hokudai.ac.jp> writes:

>以上より、d,m = x.divmod(y) に関する条件として次を提案します。
>
>  (y<=>0)*x == m + (y<=>0)*y*d

やっぱり、分かりにくいので、Pythonのに一票です。

-- gotoken

class Numeric
def dm(y) # altanative divmod
return (d,m= (-self).dm(-y); [d, -m])   if y<0
return (d = self/y; [d,d*y-self])       if y.zero?

d = self-self+y-y

if self < 0
d -= 1 while self < d*y
elsif self.zero?
# d = zero
elsif self > 0
d += 1 while d*y+y <= self
else # seif is NaN
return [self, self]
end

d = self/y if 1 != y/y and y >0 # for infinity
m = self - y*d

return [d, m]
end
end

class Float
alias fucomp <=> #

def <=>(x) # Eguchi-san's <=>
if x == x and self == self
fucomp(x)
elsif x == x
self
else
x
end
end
end

### test for dm ###

if __FILE__ == \$0

COND0 = "y > 0 ? (0 <= m and m < y) : (y < m and m <= 0)"
COND1 = "x == y*d + m"

def cond0(x,y,d,m)
eval COND0
end

def cond1(x,y,d,m)
eval COND1
end

def dmtest(x,y)
# trap("SIGINT"){p "dmtest(#{x.inspect},#{y.inspect})"; return}
fmt = "%x %y | [%div, %mod] | %5s | %5s"
(x.is_a? Float) ? fmt.gsub!("x","4.1f") : fmt.gsub!("x","4d")
(y.is_a? Float) ? fmt.gsub!("y","4.1f") : fmt.gsub!("y","4d")
begin
d,m = x.dm(y)
d ||= 0; m ||= 0
(d.is_a? Float) ? fmt.gsub!("div","4.1f") : fmt.gsub!("div","4d")
(m.is_a? Float) ? fmt.gsub!("mod","4.1f") : fmt.gsub!("mod","4d")
format(fmt, x,y,d,m,cond0(x,y,d,m), cond1(x,y,d,m))
rescue ZeroDivisionError
fmt.gsub!(/\|.*/, "# ZeroDivisionError")
format(fmt, x,y)
end
end

Inf, NaN = 1.0/0.0, 0.0/0.0

X = [-2,0,2,-Inf,Inf,NaN]
Y = [-3,-2,-1,0,1,2,3,-Inf,Inf,NaN]

puts "#"
puts "#  x    y |     x.divmod | cond0 | cond1 "
puts "#"
puts "## cond0: " + COND0
puts "## cond1: " + COND1

Y.each{|d|
puts "### y = #{d}"
X.each{|n|
x,y = n,d
puts dmtest(x,y)

x,y = n.to_f, d
puts dmtest(x,y)

x,y = n, d.to_f
puts dmtest(x,y)

x,y = n.to_f, d.to_f
puts dmtest(x,y)
}
}
end
```