Backport #6044 ยป fixmodulo.patch
insns.def | ||
---|---|---|
BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
|
||
double x = RFLOAT_VALUE(recv);
|
||
double y = RFLOAT_VALUE(obj);
|
||
double div, mod;
|
||
{
|
||
double mod;
|
||
#ifdef HAVE_FMOD
|
||
mod = fmod(x, y);
|
||
#else
|
||
if((x == -0.0) || (isinf(y) && !isinf(x)))
|
||
mod = x;
|
||
else {
|
||
double z;
|
||
modf(x / y, &z);
|
||
modf(x/y, &z);
|
||
mod = x - z * y;
|
||
}
|
||
div = (x - mod) / y;
|
||
#endif
|
||
if (y * mod < 0) {
|
||
mod += y;
|
||
div -= 1.0;
|
||
}
|
||
val = DBL2NUM(mod);
|
||
}
|
numeric.c | ||
---|---|---|
static void
|
||
flodivmod(double x, double y, double *divp, double *modp)
|
||
{
|
||
/******
|
||
Modifications to this implementation should be mirrored in insns.def
|
||
*******/
|
||
double div, mod;
|
||
if (y == 0.0) rb_num_zerodiv();
|
||
#ifdef HAVE_FMOD
|
||
mod = fmod(x, y);
|
||
#else
|
||
{
|
||
if((x == -0.0) || (isinf(y) && !isinf(x)))
|
||
mod = x;
|
||
else {
|
||
double z;
|
||
modf(x/y, &z);
|
||
mod = x - z * y;
|
||
}
|
||
#endif
|
||
if (isinf(x) && !isinf(y) && !isnan(y))
|
||
div = x;
|
||
else
|
test/ruby/envutil.rb | ||
---|---|---|
assert_equal([true, ""], [status.success?, err], message)
|
||
assert_operator(after.fdiv(before), :<, limit, message)
|
||
end
|
||
def assert_is_minus_zero(f)
|
||
assert(1.0/f == -Float::INFINITY, "#{f} is not -0.0")
|
||
end
|
||
end
|
||
end
|
||
end
|
test/ruby/test_float.rb | ||
---|---|---|
assert_raise(TypeError) { 2.0.send(:%, nil) }
|
||
end
|
||
def test_modulo3
|
||
assert_equal(4.2, 4.2.send(:%, Float::INFINITY))
|
||
assert_equal(4.2, 4.2 % Float::INFINITY)
|
||
assert_is_minus_zero(-0.0 % 4.2)
|
||
assert_is_minus_zero(-0.0.send :%, 4.2)
|
||
end
|
||
def test_divmod2
|
||
assert_equal([1.0, 0.0], 2.0.divmod(2))
|
||
assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
|