summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-11 11:50:07 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-11 11:50:07 -0800
commitaf4986ea5e82d32f9699d41781f60d9b77ba9748 (patch)
treef0940cbe7e1bfe5ccfe538dc72a4fb7bca4f1abb
parent819102d2a66dae05f251871d032320167d48b29e (diff)
downloadtxr-af4986ea5e82d32f9699d41781f60d9b77ba9748.tar.gz
txr-af4986ea5e82d32f9699d41781f60d9b77ba9748.tar.bz2
txr-af4986ea5e82d32f9699d41781f60d9b77ba9748.zip
* arith.c (ABS): New macro.
(plus, minus): Bugfix: must not pass signed values to mp_add_d and mp_sub_d functions. (mul): Must not pass signed value to mp_mul_d. Also, fixed type check on wrong argument in the (TAG_PTR, TAG_NUM) case.
-rw-r--r--ChangeLog8
-rw-r--r--arith.c48
2 files changed, 46 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index a2b1e2ab..980a5fc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2011-12-11 Kaz Kylheku <kaz@kylheku.com>
+ * arith.c (ABS): New macro.
+ (plus, minus): Bugfix: must not pass signed values to mp_add_d and
+ mp_sub_d functions.
+ (mul): Must not pass signed value to mp_mul_d. Also, fixed type check
+ on wrong argument in the (TAG_PTR, TAG_NUM) case.
+
+2011-12-11 Kaz Kylheku <kaz@kylheku.com>
+
Removing this crutch; it's not that useful.
* arith.txr: File removed.
diff --git a/arith.c b/arith.c
index 5ecb47e8..f87c5693 100644
--- a/arith.c
+++ b/arith.c
@@ -47,6 +47,7 @@
#define TAG_PAIR(A, B) ((A) << TAG_SHIFT | (B))
#define NOOP(A, B)
#define CNUM_BIT ((int) sizeof (cnum) * CHAR_BIT)
+#define ABS(A) ((A) < 0 ? -(A) : (A))
static mp_int NUM_MAX_MP;
@@ -278,8 +279,12 @@ val plus(val anum, val bnum)
type_check(bnum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_add_d(mp(bnum), c_num(anum), mp(n));
- NOOP(mp(n), mp(n));
+ cnum a = c_num(anum);
+ cnum ap = ABS(a);
+ if (a > 0)
+ mp_add_d(mp(bnum), ap, mp(n));
+ else
+ mp_sub_d(mp(bnum), ap, mp(n));
} else {
mp_int tmp;
mp_init(&tmp);
@@ -294,7 +299,12 @@ val plus(val anum, val bnum)
type_check(anum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_add_d(mp(anum), c_num(bnum), mp(n));
+ cnum b = c_num(bnum);
+ cnum bp = ABS(b);
+ if (b > 0)
+ mp_add_d(mp(anum), bp, mp(n));
+ else
+ mp_sub_d(mp(bnum), bp, mp(n));
} else {
mp_int tmp;
mp_init(&tmp);
@@ -339,7 +349,12 @@ val minus(val anum, val bnum)
type_check(bnum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_sub_d(mp(bnum), c_num(anum), mp(n));
+ cnum a = c_num(anum);
+ cnum ap = ABS(a);
+ if (ap > 0)
+ mp_sub_d(mp(bnum), ap, mp(n));
+ else
+ mp_add_d(mp(bnum), ap, mp(n));
mp_neg(mp(n), mp(n));
} else {
mp_int tmp;
@@ -355,7 +370,12 @@ val minus(val anum, val bnum)
type_check(anum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_sub_d(mp(anum), c_num(bnum), mp(n));
+ cnum b = c_num(bnum);
+ cnum bp = ABS(b);
+ if (b > 0)
+ mp_sub_d(mp(anum), bp, mp(n));
+ else
+ mp_add_d(mp(anum), bp, mp(n));
} else {
mp_int tmp;
mp_init(&tmp);
@@ -406,8 +426,8 @@ val mul(val anum, val bnum)
return bignum_dbl_ipt(product);
return num(product);
#else
- cnum ap = (a < 0) ? -a : a;
- cnum bp = (b < 0) ? -b : b;
+ cnum ap = ABS(a);
+ cnum bp = ABS(b);
if (highest_bit(ap) + highest_bit(bp) < CNUM_BIT - 1) {
cnum product = a * b;
if (product >= NUM_MIN && product <= NUM_MAX)
@@ -431,7 +451,11 @@ val mul(val anum, val bnum)
type_check(bnum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_mul_d(mp(bnum), c_num(anum), mp(n));
+ cnum a = c_num(anum);
+ cnum ap = ABS(a);
+ mp_mul_d(mp(bnum), ap, mp(n));
+ if (ap < 0)
+ mp_neg(mp(n), mp(n));
} else {
mp_int tmp;
mp_init(&tmp);
@@ -443,10 +467,14 @@ val mul(val anum, val bnum)
case TAG_PAIR(TAG_PTR, TAG_NUM):
{
val n;
- type_check(bnum, BGNUM);
+ type_check(anum, BGNUM);
n = make_bignum();
if (sizeof (int_ptr_t) <= sizeof (mp_digit)) {
- mp_mul_d(mp(anum), c_num(bnum), mp(n));
+ cnum b = c_num(bnum);
+ cnum bp = ABS(b);
+ mp_mul_d(mp(anum), bp, mp(n));
+ if (b < 0)
+ mp_neg(mp(n), mp(n));
} else {
mp_int tmp;
mp_init(&tmp);