Skip to content

Commit 36f5853

Browse files
committed
When converting doubles to bignums fill up 3 digits. Pass test 60 on 32bit machines
1 parent e6a721b commit 36f5853

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/ops/nqp_bigint.ops

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,38 @@ static void from_num(FLOATVAL d, mp_int *a) {
5454
FLOATVAL da = fabs(d);
5555
FLOATVAL upper;
5656
FLOATVAL lower;
57+
FLOATVAL lowest;
58+
FLOATVAL rest;
5759
int digits = 0;
5860

5961
mp_zero(a);
6062

61-
while (da > d_digit * d_digit) {;
63+
while (da > d_digit * d_digit * d_digit) {;
6264
da /= d_digit;
6365
digits++;
6466
}
65-
mp_grow(a, digits + 2);
67+
mp_grow(a, digits + 3);
6668

67-
/* populate the top 2 digits */
68-
upper = da / d_digit;
69-
lower = fmod(da, d_digit);
69+
/* populate the top 3 digits */
70+
upper = da / (d_digit*d_digit);
71+
rest = fmod(da, d_digit*d_digit);
72+
lower = rest / d_digit;
73+
lowest = fmod(rest,d_digit );
7074
if (upper >= 1) {
7175
mp_set_long(a, (unsigned long) upper);
7276
mp_mul_2d(a, DIGIT_BIT , a);
77+
DIGIT(a, 0) = (mp_digit) lower;
78+
mp_mul_2d(a, DIGIT_BIT , a);
7379
} else {
74-
a->used = 1;
80+
if (lower >= 1) {
81+
mp_set_long(a, (unsigned long) lower);
82+
mp_mul_2d(a, DIGIT_BIT , a);
83+
a->used = 2;
84+
} else {
85+
a->used = 1;
86+
}
7587
}
76-
DIGIT(a, 0) = (mp_digit) lower;
88+
DIGIT(a, 0) = (mp_digit) lowest;
7789

7890
/* shift the rest */
7991
mp_mul_2d(a, DIGIT_BIT * digits, a);

t/nqp/60-bigint.t

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#! nqp
22
use nqpmo;
33

4-
plan(34);
4+
plan(36);
55

66
my $knowhow := pir::get_knowhow__P();
77
my $bi_type := $knowhow.new_type(:name('TestBigInt'), :repr('P6bigint'));
@@ -80,6 +80,12 @@ ok(nqp::abs_n($big - $converted) / $big < 1e-4, 'bigint -> float, 1e16');
8080
my $float := 123456789e240;
8181
ok(nqp::iseq_n($float, nqp::tonum_I(nqp::fromnum_I($float, $bi_type))),
8282
'to_num and from_num round-trip');
83+
my $small_float := 1e3;
84+
ok(nqp::iseq_n($small_float, nqp::tonum_I(nqp::fromnum_I($small_float, $bi_type))),
85+
'to_num and from_num round-trip on small floats');
86+
my $medium_float := 1e14;
87+
ok(nqp::iseq_n($medium_float, nqp::tonum_I(nqp::fromnum_I($medium_float, $bi_type))),
88+
'to_num and from_num round-trip on medium sized floats');
8389
$float := -$float;
8490
ok(nqp::iseq_n($float, nqp::tonum_I(nqp::fromnum_I($float, $bi_type))),
8591
'to_num and from_num round-trip (negative number)');

0 commit comments

Comments
 (0)