This project is closed and read-only.
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))
|
||