Add functions to convert to longs
diff --git a/include/bc/bc.h b/include/bc/bc.h
index 1a2b7c3..b4ae8b9 100644
--- a/include/bc/bc.h
+++ b/include/bc/bc.h
@@ -111,6 +111,9 @@
BC_STATUS_PARSE_EOF,
BC_STATUS_PARSE_BUG,
+ BC_STATUS_MATH_NEGATIVE,
+ BC_STATUS_MATH_NON_INTEGER,
+ BC_STATUS_MATH_OVERFLOW,
BC_STATUS_MATH_DIVIDE_BY_ZERO,
BC_STATUS_MATH_NEG_SQRT,
BC_STATUS_MATH_INVALID_STRING,
diff --git a/include/bc/num.h b/include/bc/num.h
index 288b929..172b0ca 100644
--- a/include/bc/num.h
+++ b/include/bc/num.h
@@ -105,6 +105,9 @@
BcStatus bc_num_print(BcNum* n, size_t base);
BcStatus bc_num_fprint(BcNum* n, size_t base, FILE* f);
+BcStatus bc_num_long(BcNum* n, long* result);
+BcStatus bc_num_ulong(BcNum* n, unsigned long* result);
+
BcStatus bc_num_add(BcNum* a, BcNum* b, BcNum* result, size_t scale);
BcStatus bc_num_sub(BcNum* a, BcNum* b, BcNum* result, size_t scale);
BcStatus bc_num_mul(BcNum* a, BcNum* b, BcNum* result, size_t scale);
diff --git a/src/bc/bc.c b/src/bc/bc.c
index 9a4e8a0..d4af68a 100644
--- a/src/bc/bc.c
+++ b/src/bc/bc.c
@@ -99,6 +99,8 @@
"Math",
"Math",
"Math",
+ "Math",
+ "Math",
"Runtime",
"Runtime",
@@ -175,10 +177,11 @@
"end of file",
"bug in parser",
+ "negative number",
+ "non integer number",
+ "overflow",
"divide by zero",
"negative square root",
- "invalid input base",
- "invalid output base",
"invalid number string",
"couldn't open file",
diff --git a/src/bc/num.c b/src/bc/num.c
index 64e3a83..28009e8 100644
--- a/src/bc/num.c
+++ b/src/bc/num.c
@@ -212,6 +212,59 @@
return status;
}
+BcStatus bc_num_long(BcNum* n, long* result) {
+
+ size_t i;
+ unsigned long temp;
+ unsigned long prev;
+
+ if (!n || !result) return BC_STATUS_INVALID_PARAM;
+
+ if (n->radix != n->len) return BC_STATUS_MATH_NON_INTEGER;
+
+ temp = 0;
+
+ for (i = 0; i < n->len; ++i) {
+
+ prev = temp;
+
+ temp *= 10;
+ temp += n->num[i];
+
+ if (temp < prev) return BC_STATUS_MATH_OVERFLOW;
+ }
+
+ *result = temp;
+
+ return BC_STATUS_SUCCESS;
+}
+
+BcStatus bc_num_ulong(BcNum* n, unsigned long* result) {
+
+ size_t i;
+ unsigned long prev;
+
+ if (!n || !result) return BC_STATUS_INVALID_PARAM;
+
+ if (n->radix != n->len) return BC_STATUS_MATH_NON_INTEGER;
+
+ if (n->neg) return BC_STATUS_MATH_NEGATIVE;
+
+ *result = 0;
+
+ for (i = 0; i < n->len; ++i) {
+
+ prev = *result;
+
+ *result *= 10;
+ *result += n->num[i];
+
+ if (*result < prev) return BC_STATUS_MATH_OVERFLOW;
+ }
+
+ return BC_STATUS_SUCCESS;
+}
+
BcStatus bc_num_add(BcNum* a, BcNum* b, BcNum* result, size_t scale) {
return bc_num_binary(a, b, result, scale, bc_num_alg_a, a->len + b->len + 1);
}