mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* numeric.c (num_div): use floor rather than rb_Integer().
[ruby-dev:28589] * numeric.c (flo_divmod): the first element of Float#divmod should be an integer. [ruby-dev:28589] * test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder. * util.c (ruby_strtod): fixed wrong conversion. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@10123 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a6fdf0bbcd
commit
9466848db3
4 changed files with 81 additions and 71 deletions
12
ChangeLog
12
ChangeLog
|
|
@ -1,3 +1,13 @@
|
|||
Mon May 1 12:23:19 2006 <sinara@blade.nagaokaut.ac.jp>
|
||||
|
||||
* numeric.c (num_div): use floor rather than rb_Integer().
|
||||
[ruby-dev:28589]
|
||||
|
||||
* numeric.c (flo_divmod): the first element of Float#divmod should
|
||||
be an integer. [ruby-dev:28589]
|
||||
|
||||
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
|
||||
|
||||
Sat Apr 29 22:42:08 2006 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
* ext/openssl/ossl_asn1.c (ossl_asn1_decode0): should initialize
|
||||
|
|
@ -8,6 +18,8 @@ Fri Apr 28 10:53:16 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
* util.c (ruby_strtod): should not cut off 18 digits for no
|
||||
reason. [ruby-core:07796]
|
||||
|
||||
* util.c (ruby_strtod): fixed wrong conversion.
|
||||
|
||||
Thu Apr 27 01:38:10 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_fill): internalize local variable "beg" to
|
||||
|
|
|
|||
28
numeric.c
28
numeric.c
|
|
@ -256,6 +256,8 @@ num_quo(x, y)
|
|||
}
|
||||
|
||||
|
||||
static VALUE num_floor(VALUE num);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* num.div(numeric) => integer
|
||||
|
|
@ -269,7 +271,7 @@ static VALUE
|
|||
num_div(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
return rb_Integer(rb_funcall(x, '/', 1, y));
|
||||
return num_floor(rb_funcall(x, '/', 1, y));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -297,21 +299,21 @@ num_div(x, y)
|
|||
* ------+-----+---------------+---------+-------------+---------------
|
||||
* -13 | -4 | 3, -1 | 3 | -1 | -1
|
||||
* ------+-----+---------------+---------+-------------+---------------
|
||||
* 11.5 | 4 | 2.0, 3.5 | 2.875 | 3.5 | 3.5
|
||||
* 11.5 | 4 | 2, 3.5 | 2.875 | 3.5 | 3.5
|
||||
* ------+-----+---------------+---------+-------------+---------------
|
||||
* 11.5 | -4 | -3.0, -0.5 | -2.875 | -0.5 | 3.5
|
||||
* 11.5 | -4 | -3, -0.5 | -2.875 | -0.5 | 3.5
|
||||
* ------+-----+---------------+---------+-------------+---------------
|
||||
* -11.5 | 4 | -3.0 0.5 | -2.875 | 0.5 | -3.5
|
||||
* -11.5 | 4 | -3, 0.5 | -2.875 | 0.5 | -3.5
|
||||
* ------+-----+---------------+---------+-------------+---------------
|
||||
* -11.5 | -4 | 2.0 -3.5 | 2.875 | -3.5 | -3.5
|
||||
* -11.5 | -4 | 2 -3.5 | 2.875 | -3.5 | -3.5
|
||||
*
|
||||
*
|
||||
* Examples
|
||||
* 11.divmod(3) #=> [3, 2]
|
||||
* 11.divmod(-3) #=> [-4, -1]
|
||||
* 11.divmod(3.5) #=> [3.0, 0.5]
|
||||
* (-11).divmod(3.5) #=> [-4.0, 3.0]
|
||||
* (11.5).divmod(3.5) #=> [3.0, 1.0]
|
||||
* 11.divmod(3.5) #=> [3, 0.5]
|
||||
* (-11).divmod(3.5) #=> [-4, 3.0]
|
||||
* (11.5).divmod(3.5) #=> [3, 1.0]
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
|
|
@ -715,7 +717,7 @@ static VALUE
|
|||
flo_divmod(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
double fy, div, mod;
|
||||
double fy, div, mod, val;
|
||||
volatile VALUE a, b;
|
||||
|
||||
switch (TYPE(y)) {
|
||||
|
|
@ -732,7 +734,13 @@ flo_divmod(x, y)
|
|||
return rb_num_coerce_bin(x, y);
|
||||
}
|
||||
flodivmod(RFLOAT(x)->value, fy, &div, &mod);
|
||||
a = rb_float_new(div);
|
||||
if (FIXABLE(div)) {
|
||||
val = div;
|
||||
a = LONG2FIX(val);
|
||||
}
|
||||
else {
|
||||
a = rb_dbl2big(div);
|
||||
}
|
||||
b = rb_float_new(mod);
|
||||
return rb_assoc_new(a, b);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,4 +87,32 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert_raise(ArgumentError){Float("1e")}
|
||||
# add expected behaviour here.
|
||||
end
|
||||
|
||||
def test_divmod
|
||||
assert_equal([2, 3.5], 11.5.divmod(4))
|
||||
assert_equal([-3, -0.5], 11.5.divmod(-4))
|
||||
assert_equal([-3, 0.5], (-11.5).divmod(4))
|
||||
assert_equal([2, -3.5], (-11.5).divmod(-4))
|
||||
end
|
||||
|
||||
def test_div
|
||||
assert_equal(2, 11.5.div(4))
|
||||
assert_equal(-3, 11.5.div(-4))
|
||||
assert_equal(-3, (-11.5).div(4))
|
||||
assert_equal(2, (-11.5).div(-4))
|
||||
end
|
||||
|
||||
def test_modulo
|
||||
assert_equal(3.5, 11.5.modulo(4))
|
||||
assert_equal(-0.5, 11.5.modulo(-4))
|
||||
assert_equal(0.5, (-11.5).modulo(4))
|
||||
assert_equal(-3.5, (-11.5).modulo(-4))
|
||||
end
|
||||
|
||||
def test_remainder
|
||||
assert_equal(3.5, 11.5.remainder(4))
|
||||
assert_equal(3.5, 11.5.remainder(-4))
|
||||
assert_equal(-3.5, (-11.5).remainder(4))
|
||||
assert_equal(-3.5, (-11.5).remainder(-4))
|
||||
end
|
||||
end
|
||||
|
|
|
|||
84
util.c
84
util.c
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "missing/file.h"
|
||||
|
|
@ -750,26 +751,25 @@ ruby_strtod(string, endPtr)
|
|||
|
||||
errno = 0;
|
||||
p = string;
|
||||
while (ISSPACE(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
while (ISSPACE(*p)) p++;
|
||||
if (*p == '-') {
|
||||
sign = Qtrue;
|
||||
p += 1;
|
||||
p++;
|
||||
}
|
||||
else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '+') p++;
|
||||
sign = Qfalse;
|
||||
}
|
||||
|
||||
fraction = 0.;
|
||||
exp = 0;
|
||||
|
||||
/*
|
||||
* Count the number of digits in the mantissa
|
||||
* and also locate the decimal point.
|
||||
*/
|
||||
|
||||
for ( ; c = *p; p += 1) {
|
||||
for ( ; c = *p; p++) {
|
||||
if (!ISDIGIT(c)) {
|
||||
if (c != '.' || hasPoint) {
|
||||
break;
|
||||
|
|
@ -778,13 +778,13 @@ ruby_strtod(string, endPtr)
|
|||
}
|
||||
else {
|
||||
if (hasPoint) { /* already in fractional part */
|
||||
fracExp -= 1;
|
||||
fracExp--;
|
||||
}
|
||||
if (mantSize) { /* already in mantissa */
|
||||
mantSize += 1;
|
||||
mantSize++;
|
||||
}
|
||||
else if (c != '0') { /* have entered mantissa */
|
||||
mantSize += 1;
|
||||
mantSize++;
|
||||
pMant = p;
|
||||
}
|
||||
hasDigit = Qtrue;
|
||||
|
|
@ -807,30 +807,17 @@ ruby_strtod(string, endPtr)
|
|||
mantSize = 18;
|
||||
}
|
||||
if (!hasDigit) {
|
||||
errno = ERANGE;
|
||||
fraction = 0.0;
|
||||
p = string;
|
||||
}
|
||||
else {
|
||||
double frac1, frac2;
|
||||
frac1 = 0;
|
||||
for ( ; mantSize > 9; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
for (; mantSize > 0; mantSize--) {
|
||||
c = *p++;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
c = *p++;
|
||||
}
|
||||
frac1 = 10*frac1 + (c - '0');
|
||||
}
|
||||
frac2 = 0;
|
||||
for (; mantSize > 0; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac2 = 10*frac2 + (c - '0');
|
||||
fraction = 10*fraction + (c - '0');
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -839,21 +826,20 @@ ruby_strtod(string, endPtr)
|
|||
|
||||
p = pExp;
|
||||
if ((*p == 'E') || (*p == 'e')) {
|
||||
p += 1;
|
||||
p++;
|
||||
if (*p == '-') {
|
||||
expSign = Qtrue;
|
||||
p += 1;
|
||||
p++;
|
||||
}
|
||||
else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
p++;
|
||||
}
|
||||
expSign = Qfalse;
|
||||
}
|
||||
if (ISDIGIT(*p)) {
|
||||
do {
|
||||
exp = exp * 10 + (*p - '0');
|
||||
p += 1;
|
||||
exp = exp * 10 + (*p++ - '0');
|
||||
}
|
||||
while (ISDIGIT(*p));
|
||||
}
|
||||
|
|
@ -883,29 +869,6 @@ ruby_strtod(string, endPtr)
|
|||
errno = ERANGE;
|
||||
return 0.0 * (sign ? -1.0 : 1.0);
|
||||
}
|
||||
if (frac1 > 0) {
|
||||
fracExp = exp;
|
||||
exp += 9;
|
||||
if (exp < 0) {
|
||||
expSign = Qtrue;
|
||||
exp = -exp;
|
||||
}
|
||||
else {
|
||||
expSign = Qfalse;
|
||||
}
|
||||
dblExp = 10.0;
|
||||
while (exp) {
|
||||
if (exp & 1) {
|
||||
if (expSign)
|
||||
frac1 /= dblExp;
|
||||
else
|
||||
frac1 *= dblExp;
|
||||
}
|
||||
exp >>= 1;
|
||||
dblExp *= dblExp;
|
||||
}
|
||||
fraction = frac1;
|
||||
}
|
||||
if (exp < 0) {
|
||||
expSign = Qtrue;
|
||||
exp = -exp;
|
||||
|
|
@ -918,18 +881,17 @@ ruby_strtod(string, endPtr)
|
|||
{
|
||||
if (exp & 1) {
|
||||
if (expSign)
|
||||
frac2 /= dblExp;
|
||||
fraction /= dblExp;
|
||||
else
|
||||
frac2 *= dblExp;
|
||||
fraction *= dblExp;
|
||||
}
|
||||
exp >>= 1;
|
||||
dblExp *= dblExp;
|
||||
}
|
||||
fraction += frac2;
|
||||
}
|
||||
|
||||
if (endPtr != NULL) {
|
||||
*endPtr = (char *) p;
|
||||
*endPtr = (char *)p;
|
||||
}
|
||||
|
||||
if (sign) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue