summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-10-12 22:45:04 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2007-10-12 22:45:04 (GMT)
commitd1e50094aeeac30936cdea9c4109db800a1ef203 (patch)
treef86799fdab22c47dc5e99ce5c8f47f45ed716bbe
parent450cb03f088f80c7f9665cb317f82594da3f379e (diff)
downloadpbn-d1e50094aeeac30936cdea9c4109db800a1ef203.zip
pbn-d1e50094aeeac30936cdea9c4109db800a1ef203.tar.gz
pbn-d1e50094aeeac30936cdea9c4109db800a1ef203.tar.bz2
pbn-d1e50094aeeac30936cdea9c4109db800a1ef203.tar.xz
Add absolute value compare; pbn_addsub() should use it
Add pbn_abscmp() to compare absolute values; this is what pbn_addsub() actually wanted to use.
-rw-r--r--pbn.h5
-rw-r--r--pbn_add.c20
-rw-r--r--pbn_cmp.c24
3 files changed, 35 insertions, 14 deletions
diff --git a/pbn.h b/pbn.h
index 2ae2f4a..491cd9d 100644
--- a/pbn.h
+++ b/pbn.h
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 2007 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,9 @@ struct pbn {
struct pbn *pbn_addsub(struct pbn *, struct pbn *, int issub);
#define pbn_add(x,y) pbn_addsub(x,y,0)
#define pbn_sub(x,y) pbn_addsub(x,y,1)
-/* pbn_cmp() does NOT consume a reference! */
+/* pbn_cmp() and pbn_abscmp() do NOT consume a reference! */
int pbn_cmp(const struct pbn *, const struct pbn *);
+int pbn_abscmp(const struct pbn *, const struct pbn *);
struct pbn *pbn_mul(struct pbn *, struct pbn *);
struct pbn *pbn_shr(struct pbn *, int);
diff --git a/pbn_add.c b/pbn_add.c
index 197a282..931a27b 100644
--- a/pbn_add.c
+++ b/pbn_add.c
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 2007 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -50,16 +50,16 @@ struct pbn *pbn_addsub(struct pbn *s1, struct pbn *s2, int issub)
s1 = s2;
s2 = t;
}
-
+
d = pbn_cow(s1, len);
d->bits = bits;
-
+
c = 0;
for (i = 0; i < len; i++) {
c += d->num[i];
if (i < s2->len)
c += s2->num[i];
-
+
d->num[i] = c;
c >>= PBN_ATOM_BITS;
}
@@ -80,7 +80,7 @@ struct pbn *pbn_addsub(struct pbn *s1, struct pbn *s2, int issub)
}
/* Now s1 is the addend and s2 is the subtrahend */
- if (pbn_cmp(pbn_ref(s1), pbn_ref(s2)) < 0) {
+ if (pbn_abscmp(pbn_ref(s1), pbn_ref(s2)) < 0) {
/* addend is smaller than subtrahend, reverse and
invert minus */
struct pbn *t = s1;
@@ -88,29 +88,29 @@ struct pbn *pbn_addsub(struct pbn *s1, struct pbn *s2, int issub)
s2 = t;
dminus = !dminus;
}
-
+
if (s1->ref > s2->ref) {
d = pbn_cow(s2, len);
-
+
c = 0;
for (i = 0; i < len; i++) {
c -= d->num[i];
if (i < s1->len)
c += s1->num[i];
-
+
d->num[i] = c;
c >>= PBN_ATOM_BITS;
}
pbn_free(s1);
} else {
d = pbn_cow(s1, len);
-
+
c = 0;
for (i = 0; i < len; i++) {
c += d->num[i];
if (i < s2->len)
c -= s2->num[i];
-
+
d->num[i] = c;
c >>= PBN_ATOM_BITS;
}
diff --git a/pbn_cmp.c b/pbn_cmp.c
index f67de79..d8fadf1 100644
--- a/pbn_cmp.c
+++ b/pbn_cmp.c
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- *
- *
+ *
* Copyright 2007 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -42,4 +42,24 @@ int pbn_cmp(const struct pbn *s1, const struct pbn *s2)
return 0;
}
-
+/* Compare the absolute values of s1 and s2 */
+int pbn_abscmp(const struct pbn *s1, const struct pbn *s2)
+{
+ int i;
+
+ if (s1->bits < s2->bits)
+ return -1;
+ else if (s1->bits > s2->bits)
+ return 1;
+
+ i = (s1->bits+PBN_ATOM_BITS-1)/PBN_ATOM_BITS;
+ while (i >= 0) {
+ if (s1->num[i] > s2->num[i])
+ return 1;
+ else if (s1->num[i] < s2->num[i])
+ return -1;
+ i--;
+ }
+
+ return 0;
+}