aboutsummaryrefslogtreecommitdiff
path: root/src/big_int.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-05-30 16:45:49 +0100
committergingerBill <bill@gingerbill.org>2020-05-30 16:45:49 +0100
commitd8bc2030e618180185b61725b12cec90bfaaae26 (patch)
treea573ad1f072e0fcb229f53ff3309626f00f55621 /src/big_int.cpp
parent5eaef091e20ff15fd528bed06611e43654903f9e (diff)
Fix `big_int_to_f64`
Diffstat (limited to 'src/big_int.cpp')
-rw-r--r--src/big_int.cpp57
1 files changed, 51 insertions, 6 deletions
diff --git a/src/big_int.cpp b/src/big_int.cpp
index 5985f7eaf..f361009d2 100644
--- a/src/big_int.cpp
+++ b/src/big_int.cpp
@@ -291,7 +291,8 @@ void big_int_from_string(BigInt *dst, String const &s) {
big_int_from_u64(&b, base);
big_int_init(dst, &BIG_INT_ZERO);
- for (isize i = 0; i < len; i++) {
+ isize i = 0;
+ for (; i < len; i++) {
Rune r = cast(Rune)text[i];
if (r == '_') {
continue;
@@ -304,6 +305,32 @@ void big_int_from_string(BigInt *dst, String const &s) {
big_int_mul_eq(dst, &b);
big_int_add_eq(dst, &val);
}
+ if (i < len && (text[i] == 'e' || text[i] == 'E')) {
+ i += 1;
+ GB_ASSERT(base == 10);
+ GB_ASSERT(text[i] != '-');
+ if (text[i] == '+') {
+ i += 1;
+ }
+ u64 exp = 0;
+ for (; i < len; i++) {
+ char r = cast(char)text[i];
+ if (r == '_') {
+ continue;
+ }
+ u64 v = 0;
+ if (gb_char_is_digit(r)) {
+ v = u64_digit_value(r);
+ } else {
+ break;
+ }
+ exp *= 10;
+ exp += v;
+ }
+ for (u64 x = 0; x < exp; x++) {
+ big_int_mul_eq(dst, &b);
+ }
+ }
big_int_normalize(dst);
}
@@ -341,12 +368,30 @@ i64 big_int_to_i64(BigInt const *x) {
}
f64 big_int_to_f64(BigInt const *x) {
- if (x->neg) {
- i64 i = big_int_to_i64(x);
- return cast(f64)i;
+ switch (x->len) {
+ case 0:
+ return 0.0;
+ case 1:
+ if (x->neg) {
+ i64 i = big_int_to_i64(x);
+ return cast(f64)i;
+ } else {
+ u64 u = big_int_to_u64(x);
+ return cast(f64)u;
+ }
+ }
+
+
+ u64 const *words = big_int_ptr(x);
+ f64 base = pow(2.0, gb_size_of(u64));
+ // TODO(bill): clean up this code and make it more accurate
+ f64 res = 0;
+ for (isize i = x->len-1; i >= 0; i--) {
+ res *= base;
+ u64 w = words[i];
+ res += cast(f64)w;
}
- u64 u = big_int_to_u64(x);
- return cast(f64)u;
+ return res;
}
bool bi__alias(BigInt const *dst, BigInt const *src) {