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]]
|
[[package]]
|
||||||
name = "fastnum"
|
name = "fastnum"
|
||||||
version = "0.2.8"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86cde0c9334bfed5ced962bd7acc266e02e254d71494787e4255d8ec4f7296d4"
|
checksum = "b875e26379edd7866a74cec720c6ae7bea3107aaf9fd3b14d7449d87d4c1986b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bnum",
|
"bnum",
|
||||||
|
|||||||
@ -299,6 +299,8 @@ mod tests {
|
|||||||
assert_eq!(eval_default("-1km to m"), Number::new(d!(-1000), Unit::Meter));
|
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("2*-3*0.5"), "-3");
|
||||||
assert_eq!(eval_num("-3^2"), "-9");
|
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");
|
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;
|
use crate::Number;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[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`]
|
/// 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`].
|
/// - 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`]
|
/// - If you take [`Length`] to the power of [`Area`], the result has a unit of [`Volume`]
|
||||||
/// - etc.
|
/// - etc.
|
||||||
pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
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 lcat = left.unit.category();
|
||||||
let rcat = left.unit.category();
|
let rcat = left.unit.category();
|
||||||
if left.unit == NoUnit && right.unit == NoUnit {
|
if left.unit == NoUnit && right.unit == NoUnit {
|
||||||
// 3 ^ 2
|
// 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 {
|
} else if right.value == d!(1) && right.unit == NoUnit {
|
||||||
Ok(left)
|
Ok(left)
|
||||||
} else if lcat == Length && right.unit == NoUnit && right.value == d!(2) {
|
} else if lcat == Length && right.unit == NoUnit && right.value == d!(2) {
|
||||||
// x km ^ 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)))
|
Ok(to_ideal_unit(Number::new(result, SquareMillimeter)))
|
||||||
} else if lcat == Length && right.unit == NoUnit && right.value == d!(3) {
|
} else if lcat == Length && right.unit == NoUnit && right.value == d!(3) {
|
||||||
// x km ^ 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)))
|
Ok(to_ideal_unit(Number::new(result, CubicMillimeter)))
|
||||||
} else if lcat == Length && rcat == Length && right.value == d!(1) {
|
} else if lcat == Length && rcat == Length && right.value == d!(1) {
|
||||||
// x km ^ 1 km
|
// x km ^ 1 km
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user