Remove pow accuracy workaround
https://github.com/neogenie/fastnum/issues/28
This commit is contained in:
parent
f918f3d5e0
commit
9b49d8c418
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -60,9 +60,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastnum"
|
||||
version = "0.2.8"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86cde0c9334bfed5ced962bd7acc266e02e254d71494787e4255d8ec4f7296d4"
|
||||
checksum = "b875e26379edd7866a74cec720c6ae7bea3107aaf9fd3b14d7449d87d4c1986b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bnum",
|
||||
|
||||
@ -299,6 +299,8 @@ mod tests {
|
||||
assert_eq!(eval_default("-1km to m"), Number::new(d!(-1000), Unit::Meter));
|
||||
assert_eq!(eval_num("2*-3*0.5"), "-3");
|
||||
assert_eq!(eval_num("-3^2"), "-9");
|
||||
assert_eq!(eval_num("e^2"), "7.3890560989306502272304274605750078132");
|
||||
assert_eq!(eval_num("e^2.5"), "12.1824939607034734380701759511679661832");
|
||||
assert_eq!(eval_num("-1+2"), "1");
|
||||
}
|
||||
|
||||
|
||||
18
src/units.rs
18
src/units.rs
@ -1,4 +1,4 @@
|
||||
use fastnum::{dec128 as d, D128, D256};
|
||||
use fastnum::{dec128 as d, D128};
|
||||
use crate::Number;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
@ -754,15 +754,6 @@ pub fn modulo(left: Number, right: Number) -> Result<Number, String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_pow(left: D128, right: D128) -> D128 {
|
||||
// Do pow with d256 for higher accuracy
|
||||
let left = D256::try_from(left.transmute()).unwrap();
|
||||
let right = D256::try_from(right.transmute()).unwrap();
|
||||
let result = left.pow(right);
|
||||
let result_d128: D128 = result.transmute();
|
||||
result_d128
|
||||
}
|
||||
|
||||
/// Returns a [`Number`] to the power of another [`Number`]
|
||||
///
|
||||
/// - If you take [`Length`] to the power of [`NoType`], the result has a unit of [`Area`].
|
||||
@ -770,20 +761,21 @@ fn do_pow(left: D128, right: D128) -> D128 {
|
||||
/// - If you take [`Length`] to the power of [`Area`], the result has a unit of [`Volume`]
|
||||
/// - etc.
|
||||
pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
||||
// I tried converting `right` to use powi, but somehow that was slower
|
||||
let lcat = left.unit.category();
|
||||
let rcat = left.unit.category();
|
||||
if left.unit == NoUnit && right.unit == NoUnit {
|
||||
// 3 ^ 2
|
||||
Ok(Number::new(do_pow(left.value, right.value), left.unit))
|
||||
Ok(Number::new(left.value.pow(right.value), left.unit))
|
||||
} else if right.value == d!(1) && right.unit == NoUnit {
|
||||
Ok(left)
|
||||
} else if lcat == Length && right.unit == NoUnit && right.value == d!(2) {
|
||||
// x km ^ 2
|
||||
let result = do_pow(left.value * left.unit.weight(), right.value);
|
||||
let result = (left.value * left.unit.weight()).pow(right.value);
|
||||
Ok(to_ideal_unit(Number::new(result, SquareMillimeter)))
|
||||
} else if lcat == Length && right.unit == NoUnit && right.value == d!(3) {
|
||||
// x km ^ 3
|
||||
let result = do_pow(left.value * left.unit.weight(), right.value);
|
||||
let result = (left.value * left.unit.weight()).pow(right.value);
|
||||
Ok(to_ideal_unit(Number::new(result, CubicMillimeter)))
|
||||
} else if lcat == Length && rcat == Length && right.value == d!(1) {
|
||||
// x km ^ 1 km
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user