Use fastnum::d128 (#41)
This commit is contained in:
parent
3bbc5c53a1
commit
2d89355566
@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Next
|
||||||
|
- Switch to the fastnum crate's d128
|
||||||
|
- Fix exp function
|
||||||
|
|
||||||
## 2.0.0 - 2025 May 30
|
## 2.0.0 - 2025 May 30
|
||||||
- Remove the `degrees` keyword which referred to `celcius` by default
|
- Remove the `degrees` keyword which referred to `celcius` by default
|
||||||
- Remove the `default_degrees` argument from `eval()` and `lex()`. Not necessary now that the `degrees` keyword is removed
|
- Remove the `default_degrees` argument from `eval()` and `lex()`. Not necessary now that the `degrees` keyword is removed
|
||||||
|
|||||||
103
Cargo.lock
generated
103
Cargo.lock
generated
@ -12,78 +12,42 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "autocfg"
|
||||||
version = "1.3.2"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "bnum"
|
||||||
version = "1.2.24"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
|
checksum = "f781dba93de3a5ef6dc5b17c9958b208f6f3f021623b360fb605ea51ce443f10"
|
||||||
dependencies = [
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpc"
|
name = "cpc"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"decimal",
|
"fastnum",
|
||||||
"regex",
|
"regex",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decimal"
|
name = "fastnum"
|
||||||
version = "2.1.0"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a8ab77e91baeb15034c3be91e87bff4665c9036216148e4996d9a9f5792114d"
|
checksum = "86cde0c9334bfed5ced962bd7acc266e02e254d71494787e4255d8ec4f7296d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"autocfg",
|
||||||
"cc",
|
"bnum",
|
||||||
"libc",
|
|
||||||
"ord_subset",
|
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.172"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ord_subset"
|
|
||||||
version = "3.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7ce14664caf5b27f5656ff727defd68ae1eb75ef3c4d95259361df1eb376bef"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.95"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@ -113,49 +77,6 @@ version = "0.8.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.219"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
|
||||||
dependencies = [
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.219"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.101"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
|
|||||||
@ -19,11 +19,8 @@ categories = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
decimal = { version = "2.1", default-features = false, features = [
|
fastnum = "0.2"
|
||||||
"serde",
|
unicode-segmentation = "1.12"
|
||||||
"ord_subset",
|
|
||||||
] }
|
|
||||||
unicode-segmentation = "1.10"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
|
|||||||
51
README.md
51
README.md
@ -11,9 +11,6 @@ It also lets you mix units, so for example `1 km - 1m` results in `999 Meter`.
|
|||||||
|
|
||||||
[List of all supported units](https://docs.rs/cpc/latest/cpc/units/enum.Unit.html)
|
[List of all supported units](https://docs.rs/cpc/latest/cpc/units/enum.Unit.html)
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> [fend](https://github.com/printfn/fend) is a great alternative to cpc
|
|
||||||
|
|
||||||
## CLI Installation
|
## CLI Installation
|
||||||
Install using `cargo`:
|
Install using `cargo`:
|
||||||
```
|
```
|
||||||
@ -27,26 +24,6 @@ To install it manually, grab the appropriate binary from the [GitHub Releases pa
|
|||||||
cpc '2h/3 to min'
|
cpc '2h/3 to min'
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Installation
|
|
||||||
Add `cpc` as a dependency in `Cargo.toml`.
|
|
||||||
|
|
||||||
## API Usage
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use cpc::eval;
|
|
||||||
use cpc::units::Unit;
|
|
||||||
|
|
||||||
match eval("3m + 1cm", true, Unit::Celsius, false) {
|
|
||||||
Ok(answer) => {
|
|
||||||
// answer: Number { value: 301, unit: Unit::Centimeter }
|
|
||||||
println!("Evaluated value: {} {:?}", answer.value, answer.unit)
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
println!("{e}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
```
|
```
|
||||||
3 + 4 * 2
|
3 + 4 * 2
|
||||||
@ -84,14 +61,29 @@ round(sqrt(2)^4)! liters
|
|||||||
- Speed
|
- Speed
|
||||||
- Temperature
|
- Temperature
|
||||||
|
|
||||||
|
## API Installation
|
||||||
|
Add `cpc` as a dependency in `Cargo.toml`.
|
||||||
|
|
||||||
|
## API Usage
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use cpc::eval;
|
||||||
|
use cpc::units::Unit;
|
||||||
|
|
||||||
|
match eval("3m + 1cm", true, Unit::Celsius, false) {
|
||||||
|
Ok(answer) => {
|
||||||
|
// answer: Number { value: 301, unit: Unit::Centimeter }
|
||||||
|
println!("Evaluated value: {} {:?}", answer.value, answer.unit)
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
println!("{e}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Accuracy
|
## Accuracy
|
||||||
cpc uses 128-bit Decimal Floating Point (d128) numbers instead of Binary Coded Decimals for better accuracy. The result cpc gives will still not always be 100% accurate. I would recommend rounding the result to 20 decimals or less.
|
cpc uses 128-bit Decimal Floating Point (d128) numbers instead of Binary Coded Decimals for better accuracy. The result cpc gives will still not always be 100% accurate. I would recommend rounding the result to 20 decimals or less.
|
||||||
|
|
||||||
## Performance
|
|
||||||
It's pretty fast and scales well. In my case, it usually runs in under 0.1ms. The biggest performance hit is functions like `log()`. `log(12345)` evaluates in 0.12ms, and `log(e)` in 0.25ms.
|
|
||||||
|
|
||||||
To see how fast it is, you can pass the `--verbose` flag in CLI, or the `verbose` argument to `eval()`.
|
|
||||||
|
|
||||||
## Dev Instructions
|
## Dev Instructions
|
||||||
|
|
||||||
### Get started
|
### Get started
|
||||||
@ -165,9 +157,6 @@ match string {
|
|||||||
|
|
||||||
### Potential Improvements
|
### Potential Improvements
|
||||||
- Support for conversion between Power, Current, Resistance and Voltage. Multiplication and division is currently supported, but not conversions using sqrt or pow.
|
- Support for conversion between Power, Current, Resistance and Voltage. Multiplication and division is currently supported, but not conversions using sqrt or pow.
|
||||||
- Move to pure-rust decimal implementation
|
|
||||||
- `rust_decimal`: Only supports numbers up to ~1E+29
|
|
||||||
- `bigdecimal`: Lacking math functions
|
|
||||||
- E notation, like 2E+10
|
- E notation, like 2E+10
|
||||||
- Unit types
|
- Unit types
|
||||||
- Currency: How to go about dynamically updating the weights?
|
- Currency: How to go about dynamically updating the weights?
|
||||||
|
|||||||
116
src/evaluator.rs
116
src/evaluator.rs
@ -7,7 +7,7 @@ use crate::Operator::{Caret, Divide, Minus, Modulo, Multiply, Plus};
|
|||||||
use crate::TextOperator::{Of, To};
|
use crate::TextOperator::{Of, To};
|
||||||
use crate::UnaryOperator::{Factorial, Percent};
|
use crate::UnaryOperator::{Factorial, Percent};
|
||||||
use crate::{Number, Token};
|
use crate::{Number, Token};
|
||||||
use decimal::d128;
|
use fastnum::{dec128 as d, D128};
|
||||||
|
|
||||||
/// Evaluate an [`AstNode`] into a [`Number`]
|
/// Evaluate an [`AstNode`] into a [`Number`]
|
||||||
pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
||||||
@ -20,14 +20,14 @@ pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
|||||||
/// Factorials do not work with decimal numbers.
|
/// Factorials do not work with decimal numbers.
|
||||||
///
|
///
|
||||||
/// All return values of this function are hard-coded.
|
/// All return values of this function are hard-coded.
|
||||||
pub fn factorial(input: d128) -> d128 {
|
pub fn factorial(input: D128) -> D128 {
|
||||||
lookup_factorial(input.into())
|
lookup_factorial(input.try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of a [`struct@d128`]
|
/// Returns the square root of a [`struct@d128`]
|
||||||
pub fn sqrt(input: d128) -> d128 {
|
pub fn sqrt(input: D128) -> D128 {
|
||||||
let mut n = d128!(1);
|
let mut n = d!(1);
|
||||||
let half = d128!(0.5);
|
let half = d!(0.5);
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
n = (n + input / n) * half;
|
n = (n + input / n) * half;
|
||||||
}
|
}
|
||||||
@ -35,10 +35,10 @@ pub fn sqrt(input: d128) -> d128 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cube root of a [`struct@d128`]
|
/// Returns the cube root of a [`struct@d128`]
|
||||||
pub fn cbrt(input: d128) -> d128 {
|
pub fn cbrt(input: D128) -> D128 {
|
||||||
let mut n: d128 = input;
|
let mut n: D128 = input;
|
||||||
// hope that 20 iterations makes it accurate enough
|
// hope that 20 iterations makes it accurate enough
|
||||||
let three = d128!(3);
|
let three = d!(3);
|
||||||
for _ in 0..20 {
|
for _ in 0..20 {
|
||||||
let z2 = n * n;
|
let z2 = n * n;
|
||||||
n = n - ((n * z2 - input) / (three * z2));
|
n = n - ((n * z2 - input) / (three * z2));
|
||||||
@ -46,60 +46,23 @@ pub fn cbrt(input: d128) -> d128 {
|
|||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pi() -> d128 {
|
|
||||||
d128!(3.14159265358979323846264338327950288)
|
|
||||||
}
|
|
||||||
fn pi2() -> d128 {
|
|
||||||
d128!(6.283185307179586476925286766559005768)
|
|
||||||
}
|
|
||||||
fn pi_half() -> d128 {
|
|
||||||
d128!(1.570796326794896619231321691639751)
|
|
||||||
}
|
|
||||||
fn eulers_number() -> d128 {
|
|
||||||
d128!(2.718281828459045235360287471352662)
|
|
||||||
}
|
|
||||||
fn rounding_base() -> d128 {
|
|
||||||
// DO NOT add trailing zeroes
|
|
||||||
d128!(0.0000000000000000000000000000001)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the sine of a [`struct@d128`]
|
/// Returns the sine of a [`struct@d128`]
|
||||||
pub fn sin(mut input: d128) -> d128 {
|
pub fn sin(input: D128) -> D128 {
|
||||||
input %= pi2();
|
let result =input.sin();
|
||||||
|
match result.is_zero() {
|
||||||
let negative_correction = if input.is_negative() {
|
true => D128::ZERO,
|
||||||
input -= pi();
|
false => result,
|
||||||
d128!(-1)
|
|
||||||
} else {
|
|
||||||
d128!(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
let one = d128!(1);
|
|
||||||
let two = d128!(2);
|
|
||||||
let neg_one = -one;
|
|
||||||
|
|
||||||
let precision = 37;
|
|
||||||
let mut result = d128!(0);
|
|
||||||
for i_int in 0..precision {
|
|
||||||
let i = d128::from(i_int);
|
|
||||||
let calc_result = two * i + one;
|
|
||||||
result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let unrounded_result = negative_correction * result;
|
|
||||||
|
|
||||||
// This uses bankers rounding
|
|
||||||
unrounded_result.quantize(rounding_base())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cosine of a [`struct@d128`]
|
/// Returns the cosine of a [`struct@d128`]
|
||||||
pub fn cos(input: d128) -> d128 {
|
pub fn cos(input: D128) -> D128 {
|
||||||
sin(pi_half() - input)
|
input.cos()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the tangent of a [`struct@d128`]
|
/// Returns the tangent of a [`struct@d128`]
|
||||||
pub fn tan(input: d128) -> d128 {
|
pub fn tan(input: D128) -> D128 {
|
||||||
sin(input) / cos(input)
|
input.tan()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate an [`AstNode`] into a [`Number`]
|
/// Evaluate an [`AstNode`] into a [`Number`]
|
||||||
@ -110,11 +73,11 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
Token::Number(number) => Ok(Number::new(*number, Unit::NoUnit)),
|
Token::Number(number) => Ok(Number::new(*number, Unit::NoUnit)),
|
||||||
Token::Constant(constant) => match constant {
|
Token::Constant(constant) => match constant {
|
||||||
Pi => Ok(Number::new(
|
Pi => Ok(Number::new(
|
||||||
pi(),
|
D128::PI,
|
||||||
Unit::NoUnit,
|
Unit::NoUnit,
|
||||||
)),
|
)),
|
||||||
E => Ok(Number::new(
|
E => Ok(Number::new(
|
||||||
eulers_number(),
|
D128::E,
|
||||||
Unit::NoUnit,
|
Unit::NoUnit,
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
@ -148,8 +111,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
Ln => {
|
Ln => {
|
||||||
if child_answer.unit.category() == UnitType::NoType {
|
if child_answer.unit.category() == UnitType::NoType {
|
||||||
let unrounded_result = child_answer.value.ln();
|
let result = child_answer.value.ln();
|
||||||
let result = unrounded_result.quantize(unrounded_result * d128!(10));
|
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
Err("ln() only accepts UnitType::NoType".to_string())
|
Err("ln() only accepts UnitType::NoType".to_string())
|
||||||
@ -157,7 +119,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
Exp => {
|
Exp => {
|
||||||
if child_answer.unit.category() == UnitType::NoType {
|
if child_answer.unit.category() == UnitType::NoType {
|
||||||
let result = child_answer.value.exp(child_answer.value);
|
let result = child_answer.value.exp();
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
Err("exp() only accepts UnitType::NoType".to_string())
|
Err("exp() only accepts UnitType::NoType".to_string())
|
||||||
@ -165,35 +127,35 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
Round => {
|
Round => {
|
||||||
// .quantize() rounds .5 to nearest even integer, so we correct that
|
// .quantize() rounds .5 to nearest even integer, so we correct that
|
||||||
let mut result = child_answer.value.quantize(d128!(1));
|
let mut result = child_answer.value.quantize(d!(1));
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
// If the result was rounded down by 0.5, correct by +1
|
// If the result was rounded down by 0.5, correct by +1
|
||||||
if rounding_change == d128!(-0.5) {
|
if rounding_change == d!(-0.5) {
|
||||||
result += d128!(1);
|
result += d!(1);
|
||||||
}
|
}
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
}
|
}
|
||||||
Ceil => {
|
Ceil => {
|
||||||
let mut result = child_answer.value.quantize(d128!(1));
|
let mut result = child_answer.value.quantize(d!(1));
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if rounding_change.is_negative() {
|
if rounding_change.is_negative() {
|
||||||
result += d128!(1);
|
result += d!(1);
|
||||||
}
|
}
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
}
|
}
|
||||||
Floor => {
|
Floor => {
|
||||||
let mut result = child_answer.value.quantize(d128!(1));
|
let mut result = child_answer.value.quantize(d!(1));
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if !rounding_change.is_negative() {
|
if !rounding_change.is_negative() {
|
||||||
result -= d128!(1);
|
result -= d!(1);
|
||||||
}
|
}
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
}
|
}
|
||||||
Abs => {
|
Abs => {
|
||||||
let mut result = child_answer.value.abs();
|
let mut result = child_answer.value.abs();
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if rounding_change == d128!(-0.5) {
|
if rounding_change == d!(-0.5) {
|
||||||
result += d128!(1);
|
result += d!(1);
|
||||||
}
|
}
|
||||||
Ok(Number::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
}
|
}
|
||||||
@ -232,7 +194,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
let child_answer = evaluate_node(child_node)?;
|
let child_answer = evaluate_node(child_node)?;
|
||||||
match operator {
|
match operator {
|
||||||
Percent => Ok(Number::new(
|
Percent => Ok(Number::new(
|
||||||
child_answer.value / d128!(100),
|
child_answer.value / d!(100),
|
||||||
child_answer.unit,
|
child_answer.unit,
|
||||||
)),
|
)),
|
||||||
Factorial => {
|
Factorial => {
|
||||||
@ -326,7 +288,7 @@ mod tests {
|
|||||||
let result = eval(input, true, false).unwrap();
|
let result = eval(input, true, false).unwrap();
|
||||||
assert_eq!(result.unit, Unit::NoUnit);
|
assert_eq!(result.unit, Unit::NoUnit);
|
||||||
|
|
||||||
result.get_simplified_value().to_string()
|
result.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -334,7 +296,7 @@ mod tests {
|
|||||||
assert_eq!(eval_num("-2(-3)"), "6");
|
assert_eq!(eval_num("-2(-3)"), "6");
|
||||||
assert_eq!(eval_num("-2(3)"), "-6");
|
assert_eq!(eval_num("-2(3)"), "-6");
|
||||||
assert_eq!(eval_num("(3)-2"), "1");
|
assert_eq!(eval_num("(3)-2"), "1");
|
||||||
assert_eq!(eval_default("-1km to m"), Number::new(d128!(-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("-1+2"), "1");
|
assert_eq!(eval_num("-1+2"), "1");
|
||||||
@ -347,13 +309,15 @@ mod tests {
|
|||||||
assert_eq!(eval_num("sqrt(25)"), "5");
|
assert_eq!(eval_num("sqrt(25)"), "5");
|
||||||
|
|
||||||
assert_eq!(eval_num("log(100)"), "2");
|
assert_eq!(eval_num("log(100)"), "2");
|
||||||
assert_eq!(eval_num("log(2)"), "0.301029995663981195213738894724493");
|
assert_eq!(eval_num("log(2)"), "0.301029995663981195213738894724493026768");
|
||||||
|
|
||||||
assert_eq!(eval_num("ln(1)"), "0");
|
assert_eq!(eval_num("ln(1)"), "0");
|
||||||
assert_eq!(eval_num("ln(2)"), "0.693147180559945309417232121458177");
|
assert_eq!(eval_num("ln(2)"), "0.69314718055994530941723212145817656808");
|
||||||
assert_eq!(eval_num("ln(e)"), "1");
|
assert_eq!(eval_num("ln(e)"), "1");
|
||||||
assert_eq!(eval_num("ln(e^2)"), "2");
|
assert_eq!(eval_num("ln(e^2)"), "2");
|
||||||
|
|
||||||
|
assert_eq!(eval_num("exp(1)"), "2.71828182845904523536028747135266249776");
|
||||||
|
|
||||||
assert_eq!(eval_num("round(1.4)"), "1");
|
assert_eq!(eval_num("round(1.4)"), "1");
|
||||||
assert_eq!(eval_num("round(1.6)"), "2");
|
assert_eq!(eval_num("round(1.6)"), "2");
|
||||||
assert_eq!(eval_num("round(1.5)"), "2");
|
assert_eq!(eval_num("round(1.5)"), "2");
|
||||||
@ -367,7 +331,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(eval_num("abs(-3)"), "3");
|
assert_eq!(eval_num("abs(-3)"), "3");
|
||||||
|
|
||||||
assert_eq!(eval_num("sin(2)"), "0.9092974268256816953960198659117");
|
assert_eq!(eval_num("sin(2)"), "0.9092974268256816953960198659117448427");
|
||||||
assert_eq!(eval_num("sin(-2)"), "-0.9092974268256816953960198659117");
|
assert_eq!(eval_num("sin(-2)"), "-0.9092974268256816953960198659117448427");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/lexer.rs
11
src/lexer.rs
@ -1,6 +1,6 @@
|
|||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::str::FromStr;
|
use fastnum::decimal::Context;
|
||||||
use decimal::d128;
|
use fastnum::D128;
|
||||||
use crate::Token;
|
use crate::Token;
|
||||||
use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, RightParen};
|
use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, RightParen};
|
||||||
use crate::UnaryOperator::{Percent, Factorial};
|
use crate::UnaryOperator::{Percent, Factorial};
|
||||||
@ -98,14 +98,9 @@ fn parse_token(c: &str, lexer: &mut Lexer) -> Result<(), String> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d128::set_status(decimal::Status::empty());
|
match D128::from_str(&number_string, Context::default()) {
|
||||||
match d128::from_str(&number_string) {
|
|
||||||
Ok(number) => {
|
Ok(number) => {
|
||||||
if d128::get_status().is_empty() {
|
|
||||||
tokens.push(Token::Number(number));
|
tokens.push(Token::Number(number));
|
||||||
} else {
|
|
||||||
return Err(format!("Error lexing d128 number: {}", number_string));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
return Err(format!("Error lexing d128 number: {}", number_string));
|
return Err(format!("Error lexing d128 number: {}", number_string));
|
||||||
|
|||||||
39
src/lib.rs
39
src/lib.rs
@ -23,7 +23,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::units::Unit;
|
use crate::units::Unit;
|
||||||
use decimal::d128;
|
use fastnum::{dec128 as d, D128};
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
@ -47,37 +47,32 @@ pub mod units;
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cpc::{eval,Number};
|
/// use cpc::{eval,Number};
|
||||||
/// use cpc::units::Unit;
|
/// use cpc::units::Unit;
|
||||||
/// use decimal::d128;
|
/// use fastnum::dec128;
|
||||||
///
|
///
|
||||||
/// let x = Number {
|
/// let x = Number {
|
||||||
/// value: d128!(100),
|
/// value: dec128!(100),
|
||||||
/// unit: Unit::Meter,
|
/// unit: Unit::Meter,
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Number {
|
pub struct Number {
|
||||||
/// The number part of a [`Number`] struct
|
/// The number part of a [`Number`] struct
|
||||||
pub value: d128,
|
pub value: D128,
|
||||||
/// The unit of a [`Number`] struct. This can be [`NoType`](units::UnitType::NoType)
|
/// The unit of a [`Number`] struct. This can be [`NoType`](units::UnitType::NoType)
|
||||||
pub unit: Unit,
|
pub unit: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
pub const fn new(value: d128, unit: Unit) -> Number {
|
pub const fn new(value: D128, unit: Unit) -> Number {
|
||||||
Number { value, unit }
|
Number { value, unit }
|
||||||
}
|
}
|
||||||
pub fn get_simplified_value(&self) -> d128 {
|
pub fn get_simplified_value(&self) -> D128 {
|
||||||
// The order here matters, reduce must be first
|
self.value.reduce()
|
||||||
// sin(pi) results in 0E-32, but .reduce() changes is to 0
|
|
||||||
let mut value = self.value.reduce();
|
|
||||||
// 0.2/0.01 results in 2E+1, but adding 0 changes it to 20
|
|
||||||
value = value + d128!(0);
|
|
||||||
value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for Number {
|
impl Display for Number {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let value = self.get_simplified_value();
|
let value = self.get_simplified_value();
|
||||||
let word = match self.value == d128!(1) {
|
let word = match self.value == d!(1) {
|
||||||
true => self.unit.singular(),
|
true => self.unit.singular(),
|
||||||
false => self.unit.plural(),
|
false => self.unit.plural(),
|
||||||
};
|
};
|
||||||
@ -199,7 +194,7 @@ pub enum LexerKeyword {
|
|||||||
pub enum Token {
|
pub enum Token {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
UnaryOperator(UnaryOperator),
|
UnaryOperator(UnaryOperator),
|
||||||
Number(d128),
|
Number(D128),
|
||||||
FunctionIdentifier(FunctionIdentifier),
|
FunctionIdentifier(FunctionIdentifier),
|
||||||
Constant(Constant),
|
Constant(Constant),
|
||||||
/// Used by the parser only
|
/// Used by the parser only
|
||||||
@ -218,7 +213,7 @@ pub enum Token {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! numtok {
|
macro_rules! numtok {
|
||||||
( $num:literal ) => {
|
( $num:literal ) => {
|
||||||
Token::Number(d128!($num))
|
Token::Number(fastnum::dec128!($num))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,12 +300,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_evaluations() {
|
fn test_evaluations() {
|
||||||
assert_eq!(default_eval("-2(-3)"), Number::new(d128!(6), Unit::NoUnit));
|
assert_eq!(default_eval("-2(-3)"), Number::new(d!(6), Unit::NoUnit));
|
||||||
assert_eq!(default_eval("-2(3)"), Number::new(d128!(-6), Unit::NoUnit));
|
assert_eq!(default_eval("-2(3)"), Number::new(d!(-6), Unit::NoUnit));
|
||||||
assert_eq!(default_eval("(3)-2"), Number::new(d128!(1), Unit::NoUnit));
|
assert_eq!(default_eval("(3)-2"), Number::new(d!(1), Unit::NoUnit));
|
||||||
assert_eq!(default_eval("-1km to m"), Number::new(d128!(-1000), Unit::Meter));
|
assert_eq!(default_eval("-1km to m"), Number::new(d!(-1000), Unit::Meter));
|
||||||
assert_eq!(default_eval("2*-3*0.5"), Number::new(d128!(-3), Unit::NoUnit));
|
assert_eq!(default_eval("2*-3*0.5"), Number::new(d!(-3), Unit::NoUnit));
|
||||||
assert_eq!(default_eval("-3^2"), Number::new(d128!(-9), Unit::NoUnit));
|
assert_eq!(default_eval("-3^2"), Number::new(d!(-9), Unit::NoUnit));
|
||||||
assert_eq!(default_eval("-1+2"), Number::new(d128!(1), Unit::NoUnit));
|
assert_eq!(default_eval("-1+2"), Number::new(d!(1), Unit::NoUnit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2062
src/lookup.rs
2062
src/lookup.rs
File diff suppressed because it is too large
Load Diff
543
src/units.rs
543
src/units.rs
@ -1,4 +1,4 @@
|
|||||||
use decimal::d128;
|
use fastnum::{dec128 as d, D128, D256};
|
||||||
use crate::Number;
|
use crate::Number;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
@ -62,7 +62,7 @@ macro_rules! create_units {
|
|||||||
),*
|
),*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn weight(&self) -> d128 {
|
pub fn weight(&self) -> D128 {
|
||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
Unit::$variant => $properties.1
|
Unit::$variant => $properties.1
|
||||||
@ -88,229 +88,229 @@ macro_rules! create_units {
|
|||||||
}
|
}
|
||||||
|
|
||||||
create_units!(
|
create_units!(
|
||||||
NoUnit: (NoType, d128!(1), "", ""),
|
NoUnit: (NoType, d!(1), "", ""),
|
||||||
|
|
||||||
Nanosecond: (Time, d128!(1), "nanosecond", "nanoseconds"),
|
Nanosecond: (Time, d!(1), "nanosecond", "nanoseconds"),
|
||||||
Microsecond: (Time, d128!(1000), "microsecond", "microseconds"),
|
Microsecond: (Time, d!(1000), "microsecond", "microseconds"),
|
||||||
Millisecond: (Time, d128!(1000000), "millisecond", "milliseconds"),
|
Millisecond: (Time, d!(1000000), "millisecond", "milliseconds"),
|
||||||
Second: (Time, d128!(1000000000), "second", "seconds"),
|
Second: (Time, d!(1000000000), "second", "seconds"),
|
||||||
Minute: (Time, d128!(60000000000), "minute", "minutes"),
|
Minute: (Time, d!(60000000000), "minute", "minutes"),
|
||||||
Hour: (Time, d128!(3600000000000), "hour", "hours"),
|
Hour: (Time, d!(3600000000000), "hour", "hours"),
|
||||||
Day: (Time, d128!(86400000000000), "day", "days"),
|
Day: (Time, d!(86400000000000), "day", "days"),
|
||||||
Week: (Time, d128!(604800000000000), "week", "weeks"),
|
Week: (Time, d!(604800000000000), "week", "weeks"),
|
||||||
Month: (Time, d128!(2629746000000000), "month", "months"),
|
Month: (Time, d!(2629746000000000), "month", "months"),
|
||||||
Quarter: (Time, d128!(7889238000000000), "quarter", "quarters"),
|
Quarter: (Time, d!(7889238000000000), "quarter", "quarters"),
|
||||||
Year: (Time, d128!(31556952000000000), "year", "years"),
|
Year: (Time, d!(31556952000000000), "year", "years"),
|
||||||
Decade: (Time, d128!(315569520000000000), "decade", "decades"),
|
Decade: (Time, d!(315569520000000000), "decade", "decades"),
|
||||||
Century: (Time, d128!(3155695200000000000), "century", "centuries"),
|
Century: (Time, d!(3155695200000000000), "century", "centuries"),
|
||||||
Millenium: (Time, d128!(31556952000000000000), "millenium", "millenia"),
|
Millenium: (Time, d!(31556952000000000000), "millenium", "millenia"),
|
||||||
|
|
||||||
Millimeter: (Length, d128!(1), "millimeter", "millimeters"),
|
Millimeter: (Length, d!(1), "millimeter", "millimeters"),
|
||||||
Centimeter: (Length, d128!(10), "centimeter", "centimeters"),
|
Centimeter: (Length, d!(10), "centimeter", "centimeters"),
|
||||||
Decimeter: (Length, d128!(100), "decimeter", "decimeters"),
|
Decimeter: (Length, d!(100), "decimeter", "decimeters"),
|
||||||
Meter: (Length, d128!(1000), "meter", "meters"),
|
Meter: (Length, d!(1000), "meter", "meters"),
|
||||||
Kilometer: (Length, d128!(1000000), "kilometer", "kilometers"),
|
Kilometer: (Length, d!(1000000), "kilometer", "kilometers"),
|
||||||
Inch: (Length, d128!(25.4), "inch", "inches"),
|
Inch: (Length, d!(25.4), "inch", "inches"),
|
||||||
Foot: (Length, d128!(304.8), "foot", "feet"),
|
Foot: (Length, d!(304.8), "foot", "feet"),
|
||||||
Yard: (Length, d128!(914.4), "yard", "yards"),
|
Yard: (Length, d!(914.4), "yard", "yards"),
|
||||||
Mile: (Length, d128!(1609344), "mile", "miles"),
|
Mile: (Length, d!(1609344), "mile", "miles"),
|
||||||
// 1-dimensional only:
|
// 1-dimensional only:
|
||||||
Marathon: (Length, d128!(42195000), "marathon", "marathons"),
|
Marathon: (Length, d!(42195000), "marathon", "marathons"),
|
||||||
NauticalMile: (Length, d128!(1852000), "nautical mile", "nautical miles"),
|
NauticalMile: (Length, d!(1852000), "nautical mile", "nautical miles"),
|
||||||
LightYear: (Length, d128!(9460730472580800000), "light year", "light years"),
|
LightYear: (Length, d!(9460730472580800000), "light year", "light years"),
|
||||||
LightSecond: (Length, d128!(299792458000), "light second", "light seconds"),
|
LightSecond: (Length, d!(299792458000), "light second", "light seconds"),
|
||||||
|
|
||||||
SquareMillimeter: (Area, d128!(1), "square millimeter", "square millimeters"),
|
SquareMillimeter: (Area, d!(1), "square millimeter", "square millimeters"),
|
||||||
SquareCentimeter: (Area, d128!(100), "square centimeter", "square centimeters"),
|
SquareCentimeter: (Area, d!(100), "square centimeter", "square centimeters"),
|
||||||
SquareDecimeter: (Area, d128!(10000), "square decimeter", "square decimeters"),
|
SquareDecimeter: (Area, d!(10000), "square decimeter", "square decimeters"),
|
||||||
SquareMeter: (Area, d128!(1000000), "square meter", "square meters"),
|
SquareMeter: (Area, d!(1000000), "square meter", "square meters"),
|
||||||
SquareKilometer: (Area, d128!(1000000000000), "square kilometer", "square kilometers"),
|
SquareKilometer: (Area, d!(1000000000000), "square kilometer", "square kilometers"),
|
||||||
SquareInch: (Area, d128!(645.16), "square inch", "square inches"),
|
SquareInch: (Area, d!(645.16), "square inch", "square inches"),
|
||||||
SquareFoot: (Area, d128!(92903.04), "square foot", "square feet"),
|
SquareFoot: (Area, d!(92903.04), "square foot", "square feet"),
|
||||||
SquareYard: (Area, d128!(836127.36), "square yard", "square yards"),
|
SquareYard: (Area, d!(836127.36), "square yard", "square yards"),
|
||||||
SquareMile: (Area, d128!(2589988110336.00), "square mile", "square miles"),
|
SquareMile: (Area, d!(2589988110336.00), "square mile", "square miles"),
|
||||||
// 2-dimensional only
|
// 2-dimensional only
|
||||||
Are: (Area, d128!(100000000), "are", "ares"),
|
Are: (Area, d!(100000000), "are", "ares"),
|
||||||
Decare: (Area, d128!(1000000000), "decare", "decare"),
|
Decare: (Area, d!(1000000000), "decare", "decare"),
|
||||||
Hectare: (Area, d128!(10000000000), "hectare", "hectares"),
|
Hectare: (Area, d!(10000000000), "hectare", "hectares"),
|
||||||
Acre: (Area, d128!(4046856422.40), "acre", "acres"),
|
Acre: (Area, d!(4046856422.40), "acre", "acres"),
|
||||||
|
|
||||||
CubicMillimeter: (Volume, d128!(1), "cubic millimeter", "cubic millimeters"),
|
CubicMillimeter: (Volume, d!(1), "cubic millimeter", "cubic millimeters"),
|
||||||
CubicCentimeter: (Volume, d128!(1000), "cubic centimeter", "cubic centimeters"),
|
CubicCentimeter: (Volume, d!(1000), "cubic centimeter", "cubic centimeters"),
|
||||||
CubicDecimeter: (Volume, d128!(1000000), "cubic decimeter", "cubic decimeters"),
|
CubicDecimeter: (Volume, d!(1000000), "cubic decimeter", "cubic decimeters"),
|
||||||
CubicMeter: (Volume, d128!(1000000000), "cubic meter", "cubic meters"),
|
CubicMeter: (Volume, d!(1000000000), "cubic meter", "cubic meters"),
|
||||||
CubicKilometer: (Volume, d128!(1000000000000000000), "cubic kilometer", "cubic kilometers"),
|
CubicKilometer: (Volume, d!(1000000000000000000), "cubic kilometer", "cubic kilometers"),
|
||||||
CubicInch: (Volume, d128!(16387.064), "cubic inch", "cubic inches"),
|
CubicInch: (Volume, d!(16387.064), "cubic inch", "cubic inches"),
|
||||||
CubicFoot: (Volume, d128!(28316846.592), "cubic foot", "cubic feet"),
|
CubicFoot: (Volume, d!(28316846.592), "cubic foot", "cubic feet"),
|
||||||
CubicYard: (Volume, d128!(764554857.984), "cubic yard", "cubic yards"),
|
CubicYard: (Volume, d!(764554857.984), "cubic yard", "cubic yards"),
|
||||||
CubicMile: (Volume, d128!(4168181825440579584), "cubic mile", "cubic miles"),
|
CubicMile: (Volume, d!(4168181825440579584), "cubic mile", "cubic miles"),
|
||||||
// 3-dimensional only
|
// 3-dimensional only
|
||||||
Milliliter: (Volume, d128!(1000), "milliliter", "milliliters"),
|
Milliliter: (Volume, d!(1000), "milliliter", "milliliters"),
|
||||||
Centiliter: (Volume, d128!(10000), "centiliter", "centiliters"),
|
Centiliter: (Volume, d!(10000), "centiliter", "centiliters"),
|
||||||
Deciliter: (Volume, d128!(100000), "deciliter", "deciliters"),
|
Deciliter: (Volume, d!(100000), "deciliter", "deciliters"),
|
||||||
Liter: (Volume, d128!(1000000), "liter", "liters"),
|
Liter: (Volume, d!(1000000), "liter", "liters"),
|
||||||
Teaspoon: (Volume, d128!(4928.92159375), "teaspoon", "teaspoons"),
|
Teaspoon: (Volume, d!(4928.92159375), "teaspoon", "teaspoons"),
|
||||||
Tablespoon: (Volume, d128!(14786.76478125), "tablespoon", "tablespoons"),
|
Tablespoon: (Volume, d!(14786.76478125), "tablespoon", "tablespoons"),
|
||||||
FluidOunce: (Volume, d128!(29573.5295625), "fluid ounce", "fluid ounces"),
|
FluidOunce: (Volume, d!(29573.5295625), "fluid ounce", "fluid ounces"),
|
||||||
Cup: (Volume, d128!(236588.2365), "cup", "cups"),
|
Cup: (Volume, d!(236588.2365), "cup", "cups"),
|
||||||
Pint: (Volume, d128!(473176.473), "pint", "pints"),
|
Pint: (Volume, d!(473176.473), "pint", "pints"),
|
||||||
Quart: (Volume, d128!(946352.946), "quart", "quarts"),
|
Quart: (Volume, d!(946352.946), "quart", "quarts"),
|
||||||
Gallon: (Volume, d128!(3785411.784), "gallon", "gallons"),
|
Gallon: (Volume, d!(3785411.784), "gallon", "gallons"),
|
||||||
OilBarrel: (Volume, d128!(158987294.928), "oil barrel", "oil barrels"),
|
OilBarrel: (Volume, d!(158987294.928), "oil barrel", "oil barrels"),
|
||||||
|
|
||||||
Milligram: (Mass, d128!(0.001), "milligram", "milligrams"),
|
Milligram: (Mass, d!(0.001), "milligram", "milligrams"),
|
||||||
Gram: (Mass, d128!(1), "gram", "grams"),
|
Gram: (Mass, d!(1), "gram", "grams"),
|
||||||
Hectogram: (Mass, d128!(100), "hectogram", "hectograms"),
|
Hectogram: (Mass, d!(100), "hectogram", "hectograms"),
|
||||||
Kilogram: (Mass, d128!(1000), "kilogram", "kilograms"),
|
Kilogram: (Mass, d!(1000), "kilogram", "kilograms"),
|
||||||
MetricTon: (Mass, d128!(1000000), "metric ton", "metric tons"),
|
MetricTon: (Mass, d!(1000000), "metric ton", "metric tons"),
|
||||||
Ounce: (Mass, d128!(28.349523125), "ounce", "ounces"),
|
Ounce: (Mass, d!(28.349523125), "ounce", "ounces"),
|
||||||
Pound: (Mass, d128!(453.59237), "pound", "pounds"),
|
Pound: (Mass, d!(453.59237), "pound", "pounds"),
|
||||||
Stone: (Mass, d128!(6350.29318), "stone", "stones"),
|
Stone: (Mass, d!(6350.29318), "stone", "stones"),
|
||||||
ShortTon: (Mass, d128!(907184.74), "short ton", "short tons"),
|
ShortTon: (Mass, d!(907184.74), "short ton", "short tons"),
|
||||||
LongTon: (Mass, d128!(1016046.9088), "long ton", "long tons"),
|
LongTon: (Mass, d!(1016046.9088), "long ton", "long tons"),
|
||||||
|
|
||||||
Bit: (DigitalStorage, d128!(1), "bit", "bits"),
|
Bit: (DigitalStorage, d!(1), "bit", "bits"),
|
||||||
Kilobit: (DigitalStorage, d128!(1000), "kilobit", "kilobits"),
|
Kilobit: (DigitalStorage, d!(1000), "kilobit", "kilobits"),
|
||||||
Megabit: (DigitalStorage, d128!(1000000), "megabit", "megabits"),
|
Megabit: (DigitalStorage, d!(1000000), "megabit", "megabits"),
|
||||||
Gigabit: (DigitalStorage, d128!(1000000000), "gigabit", "gigabits"),
|
Gigabit: (DigitalStorage, d!(1000000000), "gigabit", "gigabits"),
|
||||||
Terabit: (DigitalStorage, d128!(1000000000000), "terabit", "terabits"),
|
Terabit: (DigitalStorage, d!(1000000000000), "terabit", "terabits"),
|
||||||
Petabit: (DigitalStorage, d128!(1000000000000000), "petabit", "petabits"),
|
Petabit: (DigitalStorage, d!(1000000000000000), "petabit", "petabits"),
|
||||||
Exabit: (DigitalStorage, d128!(1000000000000000000), "exabit", "exabits"),
|
Exabit: (DigitalStorage, d!(1000000000000000000), "exabit", "exabits"),
|
||||||
Zettabit: (DigitalStorage, d128!(1000000000000000000000), "zettabit", "zettabits"),
|
Zettabit: (DigitalStorage, d!(1000000000000000000000), "zettabit", "zettabits"),
|
||||||
Yottabit: (DigitalStorage, d128!(1000000000000000000000000), "yottabit", "yottabits"),
|
Yottabit: (DigitalStorage, d!(1000000000000000000000000), "yottabit", "yottabits"),
|
||||||
Kibibit: (DigitalStorage, d128!(1024), "kibibit", "kibibits"),
|
Kibibit: (DigitalStorage, d!(1024), "kibibit", "kibibits"),
|
||||||
Mebibit: (DigitalStorage, d128!(1048576), "mebibit", "mebibits"),
|
Mebibit: (DigitalStorage, d!(1048576), "mebibit", "mebibits"),
|
||||||
Gibibit: (DigitalStorage, d128!(1073741824), "gibibit", "gibibits"),
|
Gibibit: (DigitalStorage, d!(1073741824), "gibibit", "gibibits"),
|
||||||
Tebibit: (DigitalStorage, d128!(1099511627776), "tebibit", "tebibits"),
|
Tebibit: (DigitalStorage, d!(1099511627776), "tebibit", "tebibits"),
|
||||||
Pebibit: (DigitalStorage, d128!(1125899906842624), "pebibit", "pebibits"),
|
Pebibit: (DigitalStorage, d!(1125899906842624), "pebibit", "pebibits"),
|
||||||
Exbibit: (DigitalStorage, d128!(1152921504606846976), "exbibit", "exbibits"),
|
Exbibit: (DigitalStorage, d!(1152921504606846976), "exbibit", "exbibits"),
|
||||||
Zebibit: (DigitalStorage, d128!(1180591620717411303424), "zebibit", "zebibits"),
|
Zebibit: (DigitalStorage, d!(1180591620717411303424), "zebibit", "zebibits"),
|
||||||
Yobibit: (DigitalStorage, d128!(1208925819614629174706176), "yobibit", "yobibits"),
|
Yobibit: (DigitalStorage, d!(1208925819614629174706176), "yobibit", "yobibits"),
|
||||||
Byte: (DigitalStorage, d128!(8), "byte", "bytes"),
|
Byte: (DigitalStorage, d!(8), "byte", "bytes"),
|
||||||
Kilobyte: (DigitalStorage, d128!(8000), "kilobyte", "kilobytes"),
|
Kilobyte: (DigitalStorage, d!(8000), "kilobyte", "kilobytes"),
|
||||||
Megabyte: (DigitalStorage, d128!(8000000), "megabyte", "megabytes"),
|
Megabyte: (DigitalStorage, d!(8000000), "megabyte", "megabytes"),
|
||||||
Gigabyte: (DigitalStorage, d128!(8000000000), "gigabyte", "gigabytes"),
|
Gigabyte: (DigitalStorage, d!(8000000000), "gigabyte", "gigabytes"),
|
||||||
Terabyte: (DigitalStorage, d128!(8000000000000), "terabyte", "terabytes"),
|
Terabyte: (DigitalStorage, d!(8000000000000), "terabyte", "terabytes"),
|
||||||
Petabyte: (DigitalStorage, d128!(8000000000000000), "petabyte", "petabytes"),
|
Petabyte: (DigitalStorage, d!(8000000000000000), "petabyte", "petabytes"),
|
||||||
Exabyte: (DigitalStorage, d128!(8000000000000000000), "exabyte", "exabytes"),
|
Exabyte: (DigitalStorage, d!(8000000000000000000), "exabyte", "exabytes"),
|
||||||
Zettabyte: (DigitalStorage, d128!(8000000000000000000000), "zettabyte", "zettabytes"),
|
Zettabyte: (DigitalStorage, d!(8000000000000000000000), "zettabyte", "zettabytes"),
|
||||||
Yottabyte: (DigitalStorage, d128!(8000000000000000000000000), "yottabyte", "yottabytes"),
|
Yottabyte: (DigitalStorage, d!(8000000000000000000000000), "yottabyte", "yottabytes"),
|
||||||
Kibibyte: (DigitalStorage, d128!(8192), "kibibyte", "kibibytes"),
|
Kibibyte: (DigitalStorage, d!(8192), "kibibyte", "kibibytes"),
|
||||||
Mebibyte: (DigitalStorage, d128!(8388608), "mebibyte", "mebibytes"),
|
Mebibyte: (DigitalStorage, d!(8388608), "mebibyte", "mebibytes"),
|
||||||
Gibibyte: (DigitalStorage, d128!(8589934592), "gibibyte", "gibibytes"),
|
Gibibyte: (DigitalStorage, d!(8589934592), "gibibyte", "gibibytes"),
|
||||||
Tebibyte: (DigitalStorage, d128!(8796093022208), "tebibyte", "tebibytes"),
|
Tebibyte: (DigitalStorage, d!(8796093022208), "tebibyte", "tebibytes"),
|
||||||
Pebibyte: (DigitalStorage, d128!(9007199254740992), "pebibyte", "pebibytes"),
|
Pebibyte: (DigitalStorage, d!(9007199254740992), "pebibyte", "pebibytes"),
|
||||||
Exbibyte: (DigitalStorage, d128!(9223372036854775808), "exbibyte", "exbibytes"),
|
Exbibyte: (DigitalStorage, d!(9223372036854775808), "exbibyte", "exbibytes"),
|
||||||
Zebibyte: (DigitalStorage, d128!(9444732965739290427392), "zebibyte", "zebibytes"),
|
Zebibyte: (DigitalStorage, d!(9444732965739290427392), "zebibyte", "zebibytes"),
|
||||||
Yobibyte: (DigitalStorage, d128!(9671406556917033397649408), "yobibyte", "yobibytes"),
|
Yobibyte: (DigitalStorage, d!(9671406556917033397649408), "yobibyte", "yobibytes"),
|
||||||
|
|
||||||
BitsPerSecond: (DataTransferRate, d128!(1), "bit per second", "bits per second"),
|
BitsPerSecond: (DataTransferRate, d!(1), "bit per second", "bits per second"),
|
||||||
KilobitsPerSecond: (DataTransferRate, d128!(1000), "kilobit per second", "kilobits per second"),
|
KilobitsPerSecond: (DataTransferRate, d!(1000), "kilobit per second", "kilobits per second"),
|
||||||
MegabitsPerSecond: (DataTransferRate, d128!(1000000), "megabit per second", "megabits per second"),
|
MegabitsPerSecond: (DataTransferRate, d!(1000000), "megabit per second", "megabits per second"),
|
||||||
GigabitsPerSecond: (DataTransferRate, d128!(1000000000), "gigabit per second", "gigabits per second"),
|
GigabitsPerSecond: (DataTransferRate, d!(1000000000), "gigabit per second", "gigabits per second"),
|
||||||
TerabitsPerSecond: (DataTransferRate, d128!(1000000000000), "terabit per second", "terabits per second"),
|
TerabitsPerSecond: (DataTransferRate, d!(1000000000000), "terabit per second", "terabits per second"),
|
||||||
PetabitsPerSecond: (DataTransferRate, d128!(1000000000000000), "petabit per second", "petabits per second"),
|
PetabitsPerSecond: (DataTransferRate, d!(1000000000000000), "petabit per second", "petabits per second"),
|
||||||
ExabitsPerSecond: (DataTransferRate, d128!(1000000000000000000), "exabit per second", "exabits per second"),
|
ExabitsPerSecond: (DataTransferRate, d!(1000000000000000000), "exabit per second", "exabits per second"),
|
||||||
ZettabitsPerSecond: (DataTransferRate, d128!(1000000000000000000000), "zettabit per second", "zettabits per second"),
|
ZettabitsPerSecond: (DataTransferRate, d!(1000000000000000000000), "zettabit per second", "zettabits per second"),
|
||||||
YottabitsPerSecond: (DataTransferRate, d128!(1000000000000000000000000), "yottabit per second", "yottabits per second"),
|
YottabitsPerSecond: (DataTransferRate, d!(1000000000000000000000000), "yottabit per second", "yottabits per second"),
|
||||||
KibibitsPerSecond: (DataTransferRate, d128!(1024), "kibibit per second", "kibibits per second"),
|
KibibitsPerSecond: (DataTransferRate, d!(1024), "kibibit per second", "kibibits per second"),
|
||||||
MebibitsPerSecond: (DataTransferRate, d128!(1048576), "mebibit per second", "mebibits per second"),
|
MebibitsPerSecond: (DataTransferRate, d!(1048576), "mebibit per second", "mebibits per second"),
|
||||||
GibibitsPerSecond: (DataTransferRate, d128!(1073741824), "gibibit per second", "gibibits per second"),
|
GibibitsPerSecond: (DataTransferRate, d!(1073741824), "gibibit per second", "gibibits per second"),
|
||||||
TebibitsPerSecond: (DataTransferRate, d128!(1099511627776), "tebibit per second", "tebibits per second"),
|
TebibitsPerSecond: (DataTransferRate, d!(1099511627776), "tebibit per second", "tebibits per second"),
|
||||||
PebibitsPerSecond: (DataTransferRate, d128!(1125899906842624), "pebibit per second", "pebibits per second"),
|
PebibitsPerSecond: (DataTransferRate, d!(1125899906842624), "pebibit per second", "pebibits per second"),
|
||||||
ExbibitsPerSecond: (DataTransferRate, d128!(1152921504606846976), "exbibit per second", "exbibits per second"),
|
ExbibitsPerSecond: (DataTransferRate, d!(1152921504606846976), "exbibit per second", "exbibits per second"),
|
||||||
ZebibitsPerSecond: (DataTransferRate, d128!(1180591620717411303424), "zebibit per second", "zebibits per second"),
|
ZebibitsPerSecond: (DataTransferRate, d!(1180591620717411303424), "zebibit per second", "zebibits per second"),
|
||||||
YobibitsPerSecond: (DataTransferRate, d128!(1208925819614629174706176), "yobibit per second", "yobibits per second"),
|
YobibitsPerSecond: (DataTransferRate, d!(1208925819614629174706176), "yobibit per second", "yobibits per second"),
|
||||||
BytesPerSecond: (DataTransferRate, d128!(8), "byte per second", "bytes per second"),
|
BytesPerSecond: (DataTransferRate, d!(8), "byte per second", "bytes per second"),
|
||||||
KilobytesPerSecond: (DataTransferRate, d128!(8000), "kilobyte per second", "kilobytes per second"),
|
KilobytesPerSecond: (DataTransferRate, d!(8000), "kilobyte per second", "kilobytes per second"),
|
||||||
MegabytesPerSecond: (DataTransferRate, d128!(8000000), "megabyte per second", "megabytes per second"),
|
MegabytesPerSecond: (DataTransferRate, d!(8000000), "megabyte per second", "megabytes per second"),
|
||||||
GigabytesPerSecond: (DataTransferRate, d128!(8000000000), "gigabyte per second", "gigabytes per second"),
|
GigabytesPerSecond: (DataTransferRate, d!(8000000000), "gigabyte per second", "gigabytes per second"),
|
||||||
TerabytesPerSecond: (DataTransferRate, d128!(8000000000000), "terabyte per second", "terabytes per second"),
|
TerabytesPerSecond: (DataTransferRate, d!(8000000000000), "terabyte per second", "terabytes per second"),
|
||||||
PetabytesPerSecond: (DataTransferRate, d128!(8000000000000000), "petabyte per second", "petabytes per second"),
|
PetabytesPerSecond: (DataTransferRate, d!(8000000000000000), "petabyte per second", "petabytes per second"),
|
||||||
ExabytesPerSecond: (DataTransferRate, d128!(8000000000000000000), "exabyte per second", "exabytes per second"),
|
ExabytesPerSecond: (DataTransferRate, d!(8000000000000000000), "exabyte per second", "exabytes per second"),
|
||||||
ZettabytesPerSecond: (DataTransferRate, d128!(8000000000000000000000), "zettabyte per second", "zettabytes per second"),
|
ZettabytesPerSecond: (DataTransferRate, d!(8000000000000000000000), "zettabyte per second", "zettabytes per second"),
|
||||||
YottabytesPerSecond: (DataTransferRate, d128!(8000000000000000000000000), "yottabyte per second", "yottabytes per second"),
|
YottabytesPerSecond: (DataTransferRate, d!(8000000000000000000000000), "yottabyte per second", "yottabytes per second"),
|
||||||
KibibytesPerSecond: (DataTransferRate, d128!(8192), "kibibyte per second", "kibibytes per second"),
|
KibibytesPerSecond: (DataTransferRate, d!(8192), "kibibyte per second", "kibibytes per second"),
|
||||||
MebibytesPerSecond: (DataTransferRate, d128!(8388608), "mebibyte per second", "mebibytes per second"),
|
MebibytesPerSecond: (DataTransferRate, d!(8388608), "mebibyte per second", "mebibytes per second"),
|
||||||
GibibytesPerSecond: (DataTransferRate, d128!(8589934592), "gibibyte per second", "gibibytes per second"),
|
GibibytesPerSecond: (DataTransferRate, d!(8589934592), "gibibyte per second", "gibibytes per second"),
|
||||||
TebibytesPerSecond: (DataTransferRate, d128!(8796093022208), "tebibyte per second", "tebibytes per second"),
|
TebibytesPerSecond: (DataTransferRate, d!(8796093022208), "tebibyte per second", "tebibytes per second"),
|
||||||
PebibytesPerSecond: (DataTransferRate, d128!(9007199254740992), "pebibyte per second", "pebibytes per second"),
|
PebibytesPerSecond: (DataTransferRate, d!(9007199254740992), "pebibyte per second", "pebibytes per second"),
|
||||||
ExbibytesPerSecond: (DataTransferRate, d128!(9223372036854775808), "exbibyte per second", "exbibytes per second"),
|
ExbibytesPerSecond: (DataTransferRate, d!(9223372036854775808), "exbibyte per second", "exbibytes per second"),
|
||||||
ZebibytesPerSecond: (DataTransferRate, d128!(9444732965739290427392), "zebibyte per second", "zebibytes per second"),
|
ZebibytesPerSecond: (DataTransferRate, d!(9444732965739290427392), "zebibyte per second", "zebibytes per second"),
|
||||||
YobibytesPerSecond: (DataTransferRate, d128!(9671406556917033397649408), "yobibyte per second", "yobibytes per second"),
|
YobibytesPerSecond: (DataTransferRate, d!(9671406556917033397649408), "yobibyte per second", "yobibytes per second"),
|
||||||
|
|
||||||
Millijoule: (Energy, d128!(0.001), "millijoule", "millijoules"),
|
Millijoule: (Energy, d!(0.001), "millijoule", "millijoules"),
|
||||||
Joule: (Energy, d128!(1), "joule", "joules"),
|
Joule: (Energy, d!(1), "joule", "joules"),
|
||||||
NewtonMeter: (Energy, d128!(1), "newton meter", "newton meters"),
|
NewtonMeter: (Energy, d!(1), "newton meter", "newton meters"),
|
||||||
Kilojoule: (Energy, d128!(1000), "kilojoule", "kilojoules"),
|
Kilojoule: (Energy, d!(1000), "kilojoule", "kilojoules"),
|
||||||
Megajoule: (Energy, d128!(1000000), "megajoule", "megajoules"),
|
Megajoule: (Energy, d!(1000000), "megajoule", "megajoules"),
|
||||||
Gigajoule: (Energy, d128!(1000000000), "gigajoule", "gigajoules"),
|
Gigajoule: (Energy, d!(1000000000), "gigajoule", "gigajoules"),
|
||||||
Terajoule: (Energy, d128!(1000000000000), "terajoule", "terajoules"),
|
Terajoule: (Energy, d!(1000000000000), "terajoule", "terajoules"),
|
||||||
Calorie: (Energy, d128!(4.1868), "calorie", "calories"),
|
Calorie: (Energy, d!(4.1868), "calorie", "calories"),
|
||||||
KiloCalorie: (Energy, d128!(4186.8), "kilocalorie", "kilocalories"),
|
KiloCalorie: (Energy, d!(4186.8), "kilocalorie", "kilocalories"),
|
||||||
BritishThermalUnit: (Energy, d128!(1055.05585262), "British thermal unit", "British thermal units"),
|
BritishThermalUnit: (Energy, d!(1055.05585262), "British thermal unit", "British thermal units"),
|
||||||
WattHour: (Energy, d128!(3600), "watt-hour", "watt-hours"),
|
WattHour: (Energy, d!(3600), "watt-hour", "watt-hours"),
|
||||||
KilowattHour: (Energy, d128!(3600000), "kilowatt-hour", "kilowatt-hours"),
|
KilowattHour: (Energy, d!(3600000), "kilowatt-hour", "kilowatt-hours"),
|
||||||
MegawattHour: (Energy, d128!(3600000000), "megawatt-hour", "megawatt-hours"),
|
MegawattHour: (Energy, d!(3600000000), "megawatt-hour", "megawatt-hours"),
|
||||||
GigawattHour: (Energy, d128!(3600000000000), "gigawatt-hour", "gigawatt-hours"),
|
GigawattHour: (Energy, d!(3600000000000), "gigawatt-hour", "gigawatt-hours"),
|
||||||
TerawattHour: (Energy, d128!(3600000000000000), "terawatt-hour", "terawatt-hours"),
|
TerawattHour: (Energy, d!(3600000000000000), "terawatt-hour", "terawatt-hours"),
|
||||||
PetawattHour: (Energy, d128!(3600000000000000000), "petawatt-hour", "petawatt-hours"),
|
PetawattHour: (Energy, d!(3600000000000000000), "petawatt-hour", "petawatt-hours"),
|
||||||
|
|
||||||
Milliwatt: (Power, d128!(0.001), "milliwatt", "milliwatts"),
|
Milliwatt: (Power, d!(0.001), "milliwatt", "milliwatts"),
|
||||||
Watt: (Power, d128!(1), "watt", "watts"),
|
Watt: (Power, d!(1), "watt", "watts"),
|
||||||
Kilowatt: (Power, d128!(1000), "kilowatt", "kilowatts"),
|
Kilowatt: (Power, d!(1000), "kilowatt", "kilowatts"),
|
||||||
Megawatt: (Power, d128!(1000000), "megawatt", "megawatts"),
|
Megawatt: (Power, d!(1000000), "megawatt", "megawatts"),
|
||||||
Gigawatt: (Power, d128!(1000000000), "gigawatt", "gigawatts"),
|
Gigawatt: (Power, d!(1000000000), "gigawatt", "gigawatts"),
|
||||||
Terawatt: (Power, d128!(1000000000000), "terawatt", "terawatts"),
|
Terawatt: (Power, d!(1000000000000), "terawatt", "terawatts"),
|
||||||
Petawatt: (Power, d128!(1000000000000000), "petawatt", "petawatts"),
|
Petawatt: (Power, d!(1000000000000000), "petawatt", "petawatts"),
|
||||||
// probably inexact:
|
// probably inexact:
|
||||||
BritishThermalUnitsPerMinute: (Power, d128!(0.0568690272188), "british thermal unit per minute", "british thermal units per minute"),
|
BritishThermalUnitsPerMinute: (Power, d!(0.0568690272188), "british thermal unit per minute", "british thermal units per minute"),
|
||||||
// probably inexact:
|
// probably inexact:
|
||||||
BritishThermalUnitsPerHour: (Power, d128!(3.412141633128), "british thermal unit per hour", "british thermal units per hour"),
|
BritishThermalUnitsPerHour: (Power, d!(3.412141633128), "british thermal unit per hour", "british thermal units per hour"),
|
||||||
// exact according to wikipedia:
|
// exact according to wikipedia:
|
||||||
Horsepower: (Power, d128!(745.69987158227022), "horsepower", "horsepower"),
|
Horsepower: (Power, d!(745.69987158227022), "horsepower", "horsepower"),
|
||||||
MetricHorsepower: (Power, d128!(735.49875), "metric horsepower", "metric horsepower"),
|
MetricHorsepower: (Power, d!(735.49875), "metric horsepower", "metric horsepower"),
|
||||||
|
|
||||||
Milliampere: (ElectricCurrent, d128!(0.001), "milliampere", "milliamperes"),
|
Milliampere: (ElectricCurrent, d!(0.001), "milliampere", "milliamperes"),
|
||||||
Ampere: (ElectricCurrent, d128!(1), "ampere", "amperes"),
|
Ampere: (ElectricCurrent, d!(1), "ampere", "amperes"),
|
||||||
Kiloampere: (ElectricCurrent, d128!(1000), "kiloampere", "kiloamperes"),
|
Kiloampere: (ElectricCurrent, d!(1000), "kiloampere", "kiloamperes"),
|
||||||
Abampere: (ElectricCurrent, d128!(10), "abampere", "abamperes"),
|
Abampere: (ElectricCurrent, d!(10), "abampere", "abamperes"),
|
||||||
|
|
||||||
Milliohm: (Resistance, d128!(0.001), "milliohm", "milliohms"),
|
Milliohm: (Resistance, d!(0.001), "milliohm", "milliohms"),
|
||||||
Ohm: (Resistance, d128!(1), "ohm", "ohms"),
|
Ohm: (Resistance, d!(1), "ohm", "ohms"),
|
||||||
Kiloohm: (Resistance, d128!(1000), "kiloohm", "kiloohms"),
|
Kiloohm: (Resistance, d!(1000), "kiloohm", "kiloohms"),
|
||||||
|
|
||||||
Millivolt: (Voltage, d128!(0.001), "millivolt", "millivolts"),
|
Millivolt: (Voltage, d!(0.001), "millivolt", "millivolts"),
|
||||||
Volt: (Voltage, d128!(1), "volt", "volts"),
|
Volt: (Voltage, d!(1), "volt", "volts"),
|
||||||
Kilovolt: (Voltage, d128!(1000), "kilovolt", "kilovolts"),
|
Kilovolt: (Voltage, d!(1000), "kilovolt", "kilovolts"),
|
||||||
|
|
||||||
Pascal: (Pressure, d128!(1), "pascal", "pascals"),
|
Pascal: (Pressure, d!(1), "pascal", "pascals"),
|
||||||
Kilopascal: (Pressure, d128!(1000), "kilopascal", "kilopascals"),
|
Kilopascal: (Pressure, d!(1000), "kilopascal", "kilopascals"),
|
||||||
Atmosphere: (Pressure, d128!(101325), "atmosphere", "atmospheres"),
|
Atmosphere: (Pressure, d!(101325), "atmosphere", "atmospheres"),
|
||||||
Millibar: (Pressure, d128!(100), "millibar", "millibars"),
|
Millibar: (Pressure, d!(100), "millibar", "millibars"),
|
||||||
Bar: (Pressure, d128!(100000), "bar", "bars"),
|
Bar: (Pressure, d!(100000), "bar", "bars"),
|
||||||
InchOfMercury: (Pressure, d128!(3386.389), "inch of mercury", "inches of mercury"),
|
InchOfMercury: (Pressure, d!(3386.389), "inch of mercury", "inches of mercury"),
|
||||||
// inexact:
|
// inexact:
|
||||||
PoundsPerSquareInch: (Pressure, d128!(6894.757293168361), "pound per square inch", "pounds per square inch"),
|
PoundsPerSquareInch: (Pressure, d!(6894.757293168361), "pound per square inch", "pounds per square inch"),
|
||||||
Torr: (Pressure, d128!(162.12), "torr", "torr"),
|
Torr: (Pressure, d!(162.12), "torr", "torr"),
|
||||||
|
|
||||||
Hertz: (Frequency, d128!(1), "hertz", "hertz"),
|
Hertz: (Frequency, d!(1), "hertz", "hertz"),
|
||||||
Kilohertz: (Frequency, d128!(1000), "kilohertz", "kilohertz"),
|
Kilohertz: (Frequency, d!(1000), "kilohertz", "kilohertz"),
|
||||||
Megahertz: (Frequency, d128!(1000000), "megahertz", "megahertz"),
|
Megahertz: (Frequency, d!(1000000), "megahertz", "megahertz"),
|
||||||
Gigahertz: (Frequency, d128!(1000000000), "gigahertz", "gigahertz"),
|
Gigahertz: (Frequency, d!(1000000000), "gigahertz", "gigahertz"),
|
||||||
Terahertz: (Frequency, d128!(1000000000000), "terahertz", "terahertz"),
|
Terahertz: (Frequency, d!(1000000000000), "terahertz", "terahertz"),
|
||||||
Petahertz: (Frequency, d128!(1000000000000000), "petahertz", "petahertz"),
|
Petahertz: (Frequency, d!(1000000000000000), "petahertz", "petahertz"),
|
||||||
RevolutionsPerMinute: (Frequency, d128!(60), "revolution per minute", "revolutions per minute"),
|
RevolutionsPerMinute: (Frequency, d!(60), "revolution per minute", "revolutions per minute"),
|
||||||
|
|
||||||
KilometersPerHour: (Speed, d128!(1), "kilometer per hour", "kilometers per hour"),
|
KilometersPerHour: (Speed, d!(1), "kilometer per hour", "kilometers per hour"),
|
||||||
MetersPerSecond: (Speed, d128!(3.6), "meter per second", "meters per second"),
|
MetersPerSecond: (Speed, d!(3.6), "meter per second", "meters per second"),
|
||||||
MilesPerHour: (Speed, d128!(1.609344), "mile per hour", "miles per hour"),
|
MilesPerHour: (Speed, d!(1.609344), "mile per hour", "miles per hour"),
|
||||||
FeetPerSecond: (Speed, d128!(1.09728), "foot per second", "feet per second"),
|
FeetPerSecond: (Speed, d!(1.09728), "foot per second", "feet per second"),
|
||||||
Knot: (Speed, d128!(1.852), "knot", "knots"),
|
Knot: (Speed, d!(1.852), "knot", "knots"),
|
||||||
|
|
||||||
Kelvin: (Temperature, d128!(0), "kelvin", "kelvin"),
|
Kelvin: (Temperature, d!(0), "kelvin", "kelvin"),
|
||||||
Celsius: (Temperature, d128!(0), "celsius", "celsius"),
|
Celsius: (Temperature, d!(0), "celsius", "celsius"),
|
||||||
Fahrenheit: (Temperature, d128!(0), "fahrenheit", "fahrenheit"),
|
Fahrenheit: (Temperature, d!(0), "fahrenheit", "fahrenheit"),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Returns the conversion factor between two units.
|
/// Returns the conversion factor between two units.
|
||||||
@ -320,7 +320,7 @@ create_units!(
|
|||||||
/// is 60.
|
/// is 60.
|
||||||
///
|
///
|
||||||
/// This is not sufficient for [`Temperature`] units.
|
/// This is not sufficient for [`Temperature`] units.
|
||||||
pub fn get_conversion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
pub fn get_conversion_factor(unit: Unit, to_unit: Unit) -> D128 {
|
||||||
unit.weight() / to_unit.weight()
|
unit.weight() / to_unit.weight()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,14 +336,14 @@ pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
|||||||
if number.unit.category() == UnitType::Temperature {
|
if number.unit.category() == UnitType::Temperature {
|
||||||
match (number.unit, to_unit) {
|
match (number.unit, to_unit) {
|
||||||
(Kelvin, Kelvin) => ok(value),
|
(Kelvin, Kelvin) => ok(value),
|
||||||
(Kelvin, Celsius) => ok(value-d128!(273.15)),
|
(Kelvin, Celsius) => ok(value-d!(273.15)),
|
||||||
(Kelvin, Fahrenheit) => ok(value*d128!(1.8)-d128!(459.67)),
|
(Kelvin, Fahrenheit) => ok(value*d!(1.8)-d!(459.67)),
|
||||||
(Celsius, Celsius) => ok(value),
|
(Celsius, Celsius) => ok(value),
|
||||||
(Celsius, Kelvin) => ok(value+d128!(273.15)),
|
(Celsius, Kelvin) => ok(value+d!(273.15)),
|
||||||
(Celsius, Fahrenheit) => ok(value*d128!(1.8)+d128!(32)),
|
(Celsius, Fahrenheit) => ok(value*d!(1.8)+d!(32)),
|
||||||
(Fahrenheit, Fahrenheit) => ok(value),
|
(Fahrenheit, Fahrenheit) => ok(value),
|
||||||
(Fahrenheit, Kelvin) => ok((value+d128!(459.67))*d128!(5)/d128!(9)),
|
(Fahrenheit, Kelvin) => ok((value+d!(459.67))*d!(5)/d!(9)),
|
||||||
(Fahrenheit, Celsius) => ok((value-d128!(32))/d128!(1.8)),
|
(Fahrenheit, Celsius) => ok((value-d!(32))/d!(1.8)),
|
||||||
_ => Err(format!("Error converting temperature {:?} to {:?}", number.unit, to_unit)),
|
_ => Err(format!("Error converting temperature {:?} to {:?}", number.unit, to_unit)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -400,113 +400,113 @@ pub fn subtract(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
pub fn to_ideal_unit(number: Number) -> Number {
|
pub fn to_ideal_unit(number: Number) -> Number {
|
||||||
let value = number.value * number.unit.weight();
|
let value = number.value * number.unit.weight();
|
||||||
if number.unit.category() == Length {
|
if number.unit.category() == Length {
|
||||||
if value >= d128!(1000000000000000000) { // ≈ 0.1 light years
|
if value >= d!(1000000000000000000) { // ≈ 0.1 light years
|
||||||
return Number::new(value/LightYear.weight(), LightYear)
|
return Number::new(value/LightYear.weight(), LightYear)
|
||||||
} else if value >= d128!(1000000) { // 1 km
|
} else if value >= d!(1000000) { // 1 km
|
||||||
return Number::new(value/Kilometer.weight(), Kilometer)
|
return Number::new(value/Kilometer.weight(), Kilometer)
|
||||||
} else if value >= d128!(1000) { // 1 m
|
} else if value >= d!(1000) { // 1 m
|
||||||
return Number::new(value/Meter.weight(), Meter)
|
return Number::new(value/Meter.weight(), Meter)
|
||||||
} else if value >= d128!(10) { // 1 cm
|
} else if value >= d!(10) { // 1 cm
|
||||||
return Number::new(value/Centimeter.weight(), Centimeter)
|
return Number::new(value/Centimeter.weight(), Centimeter)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value, Millimeter)
|
return Number::new(value, Millimeter)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Time {
|
} else if number.unit.category() == Time {
|
||||||
if value >= d128!(31556952000000000) {
|
if value >= d!(31556952000000000) {
|
||||||
return Number::new(value/Year.weight(), Year);
|
return Number::new(value/Year.weight(), Year);
|
||||||
} else if value >= d128!(86400000000000) {
|
} else if value >= d!(86400000000000) {
|
||||||
return Number::new(value/Day.weight(), Day);
|
return Number::new(value/Day.weight(), Day);
|
||||||
} else if value >= d128!(3600000000000) {
|
} else if value >= d!(3600000000000) {
|
||||||
return Number::new(value/Hour.weight(), Hour);
|
return Number::new(value/Hour.weight(), Hour);
|
||||||
} else if value >= d128!(60000000000) {
|
} else if value >= d!(60000000000) {
|
||||||
return Number::new(value/Minute.weight(), Minute);
|
return Number::new(value/Minute.weight(), Minute);
|
||||||
} else if value >= d128!(1000000000) {
|
} else if value >= d!(1000000000) {
|
||||||
return Number::new(value/Second.weight(), Second);
|
return Number::new(value/Second.weight(), Second);
|
||||||
} else if value >= d128!(1000000) {
|
} else if value >= d!(1000000) {
|
||||||
return Number::new(value/Millisecond.weight(), Millisecond);
|
return Number::new(value/Millisecond.weight(), Millisecond);
|
||||||
} else if value >= d128!(1000) {
|
} else if value >= d!(1000) {
|
||||||
return Number::new(value/Microsecond.weight(), Microsecond);
|
return Number::new(value/Microsecond.weight(), Microsecond);
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value, Nanosecond);
|
return Number::new(value, Nanosecond);
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Area {
|
} else if number.unit.category() == Area {
|
||||||
if value >= d128!(1000000000000) { // 1 km2
|
if value >= d!(1000000000000) { // 1 km2
|
||||||
return Number::new(value/SquareKilometer.weight(), SquareKilometer)
|
return Number::new(value/SquareKilometer.weight(), SquareKilometer)
|
||||||
} else if value >= d128!(10000000000) { // 1 hectare
|
} else if value >= d!(10000000000) { // 1 hectare
|
||||||
return Number::new(value/Hectare.weight(), Hectare)
|
return Number::new(value/Hectare.weight(), Hectare)
|
||||||
} else if value >= d128!(1000000) { // 1 m2
|
} else if value >= d!(1000000) { // 1 m2
|
||||||
return Number::new(value/SquareMeter.weight(), SquareMeter)
|
return Number::new(value/SquareMeter.weight(), SquareMeter)
|
||||||
} else if value >= d128!(100) { // 1 cm2
|
} else if value >= d!(100) { // 1 cm2
|
||||||
return Number::new(value/SquareCentimeter.weight(), SquareCentimeter)
|
return Number::new(value/SquareCentimeter.weight(), SquareCentimeter)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value, SquareMillimeter)
|
return Number::new(value, SquareMillimeter)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Volume {
|
} else if number.unit.category() == Volume {
|
||||||
if value >= d128!(1000000000000000000) { // 1 km3
|
if value >= d!(1000000000000000000) { // 1 km3
|
||||||
return Number::new(value/CubicKilometer.weight(), CubicKilometer)
|
return Number::new(value/CubicKilometer.weight(), CubicKilometer)
|
||||||
} else if value >= d128!(1000000000) { // 1 m3
|
} else if value >= d!(1000000000) { // 1 m3
|
||||||
return Number::new(value/CubicMeter.weight(), CubicMeter)
|
return Number::new(value/CubicMeter.weight(), CubicMeter)
|
||||||
} else if value >= d128!(1000000) { // 1 l
|
} else if value >= d!(1000000) { // 1 l
|
||||||
return Number::new(value/Liter.weight(), Liter)
|
return Number::new(value/Liter.weight(), Liter)
|
||||||
} else if value >= d128!(1000) { // 1 ml
|
} else if value >= d!(1000) { // 1 ml
|
||||||
return Number::new(value/Milliliter.weight(), Milliliter)
|
return Number::new(value/Milliliter.weight(), Milliliter)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value, CubicMillimeter)
|
return Number::new(value, CubicMillimeter)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Energy {
|
} else if number.unit.category() == Energy {
|
||||||
if value >= d128!(3600000000000000000) { // 1 petawatthour
|
if value >= d!(3600000000000000000) { // 1 petawatthour
|
||||||
return Number::new(value/PetawattHour.weight(), PetawattHour)
|
return Number::new(value/PetawattHour.weight(), PetawattHour)
|
||||||
} else if value >= d128!(3600000000000000) { // 1 terawatthour
|
} else if value >= d!(3600000000000000) { // 1 terawatthour
|
||||||
return Number::new(value/TerawattHour.weight(), TerawattHour)
|
return Number::new(value/TerawattHour.weight(), TerawattHour)
|
||||||
} else if value >= d128!(3600000000000) { // 1 gigawatthour
|
} else if value >= d!(3600000000000) { // 1 gigawatthour
|
||||||
return Number::new(value/GigawattHour.weight(), GigawattHour)
|
return Number::new(value/GigawattHour.weight(), GigawattHour)
|
||||||
} else if value >= d128!(3600000000) { // 1 megawatthour
|
} else if value >= d!(3600000000) { // 1 megawatthour
|
||||||
return Number::new(value/MegawattHour.weight(), MegawattHour)
|
return Number::new(value/MegawattHour.weight(), MegawattHour)
|
||||||
} else if value >= d128!(3600000) { // 1 kilowatthour
|
} else if value >= d!(3600000) { // 1 kilowatthour
|
||||||
return Number::new(value/KilowattHour.weight(), KilowattHour)
|
return Number::new(value/KilowattHour.weight(), KilowattHour)
|
||||||
} else if value >= d128!(3600) { // 1 watthour
|
} else if value >= d!(3600) { // 1 watthour
|
||||||
return Number::new(value/WattHour.weight(), WattHour)
|
return Number::new(value/WattHour.weight(), WattHour)
|
||||||
} else if value >= d128!(1) { // 1 joule
|
} else if value >= d!(1) { // 1 joule
|
||||||
return Number::new(value, Joule)
|
return Number::new(value, Joule)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Millijoule.weight(), Millijoule)
|
return Number::new(value/Millijoule.weight(), Millijoule)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Power {
|
} else if number.unit.category() == Power {
|
||||||
if value >= d128!(1000000000000000) { // 1 petawatt
|
if value >= d!(1000000000000000) { // 1 petawatt
|
||||||
return Number::new(value/Petawatt.weight(), Petawatt)
|
return Number::new(value/Petawatt.weight(), Petawatt)
|
||||||
} else if value >= d128!(1000000000000) { // 1 terawatt
|
} else if value >= d!(1000000000000) { // 1 terawatt
|
||||||
return Number::new(value/Terawatt.weight(), Terawatt)
|
return Number::new(value/Terawatt.weight(), Terawatt)
|
||||||
} else if value >= d128!(1000000000) { // 1 gigawatt
|
} else if value >= d!(1000000000) { // 1 gigawatt
|
||||||
return Number::new(value/Gigawatt.weight(), Gigawatt)
|
return Number::new(value/Gigawatt.weight(), Gigawatt)
|
||||||
} else if value >= d128!(1000000) { // megawatt
|
} else if value >= d!(1000000) { // megawatt
|
||||||
return Number::new(value/Megawatt.weight(), Megawatt)
|
return Number::new(value/Megawatt.weight(), Megawatt)
|
||||||
} else if value >= d128!(1000) { // 1 kilowatt
|
} else if value >= d!(1000) { // 1 kilowatt
|
||||||
return Number::new(value/Kilowatt.weight(), Kilowatt)
|
return Number::new(value/Kilowatt.weight(), Kilowatt)
|
||||||
} else if value >= d128!(1) { // 1 watt
|
} else if value >= d!(1) { // 1 watt
|
||||||
return Number::new(value, Watt)
|
return Number::new(value, Watt)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Milliwatt.weight(), Milliwatt)
|
return Number::new(value/Milliwatt.weight(), Milliwatt)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == ElectricCurrent {
|
} else if number.unit.category() == ElectricCurrent {
|
||||||
if value >= d128!(1000) { // 1 kiloampere
|
if value >= d!(1000) { // 1 kiloampere
|
||||||
return Number::new(value/Kiloampere.weight(), Kiloampere)
|
return Number::new(value/Kiloampere.weight(), Kiloampere)
|
||||||
} else if value >= d128!(1) { // 1 ampere
|
} else if value >= d!(1) { // 1 ampere
|
||||||
return Number::new(value, Ampere)
|
return Number::new(value, Ampere)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Milliampere.weight(), Milliampere)
|
return Number::new(value/Milliampere.weight(), Milliampere)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Resistance {
|
} else if number.unit.category() == Resistance {
|
||||||
if value >= d128!(1000) { // 1 kiloohm
|
if value >= d!(1000) { // 1 kiloohm
|
||||||
return Number::new(value/Kiloohm.weight(), Kiloohm)
|
return Number::new(value/Kiloohm.weight(), Kiloohm)
|
||||||
} else if value >= d128!(1) { // 1 ohm
|
} else if value >= d!(1) { // 1 ohm
|
||||||
return Number::new(value, Ohm)
|
return Number::new(value, Ohm)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Milliohm.weight(), Milliohm)
|
return Number::new(value/Milliohm.weight(), Milliohm)
|
||||||
}
|
}
|
||||||
} else if number.unit.category() == Voltage {
|
} else if number.unit.category() == Voltage {
|
||||||
if value >= d128!(1000) { // 1 kilovolt
|
if value >= d!(1000) { // 1 kilovolt
|
||||||
return Number::new(value/Kilovolt.weight(), Kilovolt)
|
return Number::new(value/Kilovolt.weight(), Kilovolt)
|
||||||
} else if value >= d128!(1) { // 1 volt
|
} else if value >= d!(1) { // 1 volt
|
||||||
return Number::new(value, Volt)
|
return Number::new(value, Volt)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Millivolt.weight(), Millivolt)
|
return Number::new(value/Millivolt.weight(), Millivolt)
|
||||||
@ -519,15 +519,15 @@ pub fn to_ideal_unit(number: Number) -> Number {
|
|||||||
pub fn to_ideal_joule_unit(number: Number) -> Number {
|
pub fn to_ideal_joule_unit(number: Number) -> Number {
|
||||||
let value = number.value * number.unit.weight();
|
let value = number.value * number.unit.weight();
|
||||||
if number.unit.category() == Energy {
|
if number.unit.category() == Energy {
|
||||||
if value >= d128!(1000000000000) { // 1 terajoule
|
if value >= d!(1000000000000) { // 1 terajoule
|
||||||
return Number::new(value/Terajoule.weight(), Terajoule)
|
return Number::new(value/Terajoule.weight(), Terajoule)
|
||||||
} else if value >= d128!(1000000000) { // 1 gigajoule
|
} else if value >= d!(1000000000) { // 1 gigajoule
|
||||||
return Number::new(value/Gigajoule.weight(), Gigajoule)
|
return Number::new(value/Gigajoule.weight(), Gigajoule)
|
||||||
} else if value >= d128!(1000000) { // 1 megajoule
|
} else if value >= d!(1000000) { // 1 megajoule
|
||||||
return Number::new(value/Megajoule.weight(), Megajoule)
|
return Number::new(value/Megajoule.weight(), Megajoule)
|
||||||
} else if value >= d128!(1000) { // 1 kilojoule
|
} else if value >= d!(1000) { // 1 kilojoule
|
||||||
return Number::new(value/Kilojoule.weight(), Kilojoule)
|
return Number::new(value/Kilojoule.weight(), Kilojoule)
|
||||||
} else if value >= d128!(1) { // 1 joule
|
} else if value >= d!(1) { // 1 joule
|
||||||
return Number::new(value/Joule.weight(), Joule)
|
return Number::new(value/Joule.weight(), Joule)
|
||||||
} else {
|
} else {
|
||||||
return Number::new(value/Millijoule.weight(), Millijoule)
|
return Number::new(value/Millijoule.weight(), Millijoule)
|
||||||
@ -754,6 +754,15 @@ 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`].
|
||||||
@ -765,28 +774,28 @@ pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
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(left.value.pow(right.value), left.unit))
|
Ok(Number::new(do_pow(left.value, right.value), left.unit))
|
||||||
} else if right.value == d128!(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 == d128!(2) {
|
} else if lcat == Length && right.unit == NoUnit && right.value == d!(2) {
|
||||||
// x km ^ 2
|
// x km ^ 2
|
||||||
let result = (left.value * left.unit.weight()).pow(right.value);
|
let result = do_pow(left.value * left.unit.weight(), 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 == d128!(3) {
|
} else if lcat == Length && right.unit == NoUnit && right.value == d!(3) {
|
||||||
// x km ^ 3
|
// x km ^ 3
|
||||||
let result = (left.value * left.unit.weight()).pow(right.value);
|
let result = do_pow(left.value * left.unit.weight(), 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 == d128!(1) {
|
} else if lcat == Length && rcat == Length && right.value == d!(1) {
|
||||||
// x km ^ 1 km
|
// x km ^ 1 km
|
||||||
Ok(multiply(left, right)?)
|
Ok(multiply(left, right)?)
|
||||||
} else if lcat == Length && rcat == Length && right.value == d128!(2) {
|
} else if lcat == Length && rcat == Length && right.value == d!(2) {
|
||||||
// x km ^ 2 km
|
// x km ^ 2 km
|
||||||
let pow2 = multiply(left, Number::new(d128!(1), right.unit))?;
|
let pow2 = multiply(left, Number::new(d!(1), right.unit))?;
|
||||||
let pow3 = multiply(pow2, Number::new(d128!(1), right.unit))?;
|
let pow3 = multiply(pow2, Number::new(d!(1), right.unit))?;
|
||||||
Ok(pow3)
|
Ok(pow3)
|
||||||
} else if lcat == Length && rcat == Area && right.value == d128!(1) {
|
} else if lcat == Length && rcat == Area && right.value == d!(1) {
|
||||||
// x km ^ km2
|
// x km ^ km2
|
||||||
Ok(multiply(left, Number::new(d128!(1), right.unit))?)
|
Ok(multiply(left, Number::new(d!(1), right.unit))?)
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
@ -794,7 +803,9 @@ pub fn pow(left: Number, right: Number) -> Result<Number, String> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use fastnum::decimal::Context;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
macro_rules! assert_float_eq {
|
macro_rules! assert_float_eq {
|
||||||
( $actual:expr, $expected:literal ) => {
|
( $actual:expr, $expected:literal ) => {
|
||||||
@ -808,7 +819,7 @@ mod tests {
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
let value_string = &value.to_string();
|
let value_string = &value.to_string();
|
||||||
let value_d128 = d128::from_str(value_string).unwrap();
|
let value_d128 = D128::from_str(value_string, Context::default()).unwrap();
|
||||||
let number = Number::new(value_d128, unit);
|
let number = Number::new(value_d128, unit);
|
||||||
|
|
||||||
let result = convert(number, to_unit);
|
let result = convert(number, to_unit);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user