"""
from __future__ import print_function
import sys
+from math import ceil, log
from fractions import Fraction
from collections import namedtuple
MIN_SIG = 2 ** (N - 1)
MAX_SIG = (2 ** N) - 1
-
# Hand-rolled fp representation without arithmetic or any other operations.
# The significand is normalized and always N bit, but the exponent is
# unrestricted in range.
ulp_err = abs_err / Fraction(2) ** z.exp
return float(ulp_err)
-LICENSE = """
+HEADER = """
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+
+//! Tables of approximations of powers of ten.
+//! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py`
"""
+
def main():
+ print(HEADER.strip())
+ print()
+ print_proper_powers()
+ print()
+ print_short_powers(32, 24)
+ print()
+ print_short_powers(64, 53)
+
+
+def print_proper_powers():
MIN_E = -305
MAX_E = 305
e_range = range(MIN_E, MAX_E+1)
err = error(1, e, z)
assert err < 0.5
powers.append(z)
- typ = "([u64; {0}], [i16; {0}])".format(len(e_range))
- print(LICENSE.strip())
- print("// Table of approximations of powers of ten.")
- print("// DO NOT MODIFY: Generated by a src/etc/dec2flt_table.py")
print("pub const MIN_E: i16 = {};".format(MIN_E))
print("pub const MAX_E: i16 = {};".format(MAX_E))
print()
+ typ = "([u64; {0}], [i16; {0}])".format(len(powers))
print("pub const POWERS: ", typ, " = ([", sep='')
for z in powers:
print(" 0x{:x},".format(z.sig))
print("]);")
+def print_short_powers(num_bits, significand_size):
+ max_sig = 2**significand_size - 1
+ # The fast path bails out for exponents >= ceil(log5(max_sig))
+ max_e = int(ceil(log(max_sig, 5)))
+ e_range = range(max_e)
+ typ = "[f{}; {}]".format(num_bits, len(e_range))
+ print("pub const F", num_bits, "_SHORT_POWERS: ", typ, " = [", sep='')
+ for e in e_range:
+ print(" 1e{},".format(e))
+ print("];")
+
+
if __name__ == '__main__':
main()
if f > T::max_sig() {
return None;
}
- let e = e as i16; // Can't overflow because e.abs() <= LOG5_OF_EXP_N
// The case e < 0 cannot be folded into the other branch. Negative powers result in
// a repeating fractional part in binary, which are rounded, which causes real
// (and occasioally quite significant!) errors in the final result.
- // The case `e == 0`, however, is unnecessary for correctness. It's just measurably faster.
- if e == 0 {
- Some(T::from_int(f))
- } else if e > 0 {
- Some(T::from_int(f) * fp_to_float(power_of_ten(e)))
+ if e >= 0 {
+ Some(T::from_int(f) * T::short_fast_pow10(e as usize))
} else {
- Some(T::from_int(f) / fp_to_float(power_of_ten(-e)))
+ Some(T::from_int(f) / T::short_fast_pow10(e.abs() as usize))
}
}
use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
use num::Float;
use num::dec2flt::num::{self, Big};
+use num::dec2flt::table;
#[derive(Copy, Clone, Debug)]
pub struct Unpacked {
/// represented, the other code in this module makes sure to never let that happen.
fn from_int(x: u64) -> Self;
+ /// Get the value 10^e from a pre-computed table. Panics for e >= ceil_log5_of_max_sig().
+ fn short_fast_pow10(e: usize) -> Self;
+
// FIXME Everything that follows should be associated constants, but taking the value of an
// associated constant from a type parameter does not work (yet?)
// A possible workaround is having a `FloatInfo` struct for all the constants, but so far
x as f32
}
+ fn short_fast_pow10(e: usize) -> Self {
+ table::F32_SHORT_POWERS[e]
+ }
+
fn max_normal_digits() -> usize {
35
}
x as f64
}
+ fn short_fast_pow10(e: usize) -> Self {
+ table::F64_SHORT_POWERS[e]
+ }
+
fn max_normal_digits() -> usize {
305
}
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Table of approximations of powers of ten.
-// DO NOT MODIFY: Generated by a src/etc/dec2flt_table.py
+
+//! Tables of approximations of powers of ten.
+//! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py`
+
pub const MIN_E: i16 = -305;
pub const MAX_E: i16 = 305;
946,
950,
]);
+
+pub const F32_SHORT_POWERS: [f32; 11] = [
+ 1e0,
+ 1e1,
+ 1e2,
+ 1e3,
+ 1e4,
+ 1e5,
+ 1e6,
+ 1e7,
+ 1e8,
+ 1e9,
+ 1e10,
+];
+
+pub const F64_SHORT_POWERS: [f64; 23] = [
+ 1e0,
+ 1e1,
+ 1e2,
+ 1e3,
+ 1e4,
+ 1e5,
+ 1e6,
+ 1e7,
+ 1e8,
+ 1e9,
+ 1e10,
+ 1e11,
+ 1e12,
+ 1e13,
+ 1e14,
+ 1e15,
+ 1e16,
+ 1e17,
+ 1e18,
+ 1e19,
+ 1e20,
+ 1e21,
+ 1e22,
+];