Skip to content

Commit

Permalink
feat: add to_f64 impl
Browse files Browse the repository at this point in the history
  • Loading branch information
OliverNChalk committed Sep 15, 2024
1 parent 193da3a commit ef44355
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to `const-decimal`.

## Unreleased

## 0.2.1

- Added `Decimal::to_f64(&self)`.

## 0.2.0

- Added `BorshSerialize` and `BorshDeserialize` behind `borsh` feature flag.
- Added `AddAssign`, `SubAssign`, `MulAssign`, and `DivAssign`.
- Implemented `Decimal::from_scaled(integer: I, decimals: u8)`.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "const-decimal"
description = "Integer-backed decimals with constant precision"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
license = "MIT OR Apache-2.0"
authors = ["Oliver Chalk"]
Expand Down
2 changes: 2 additions & 0 deletions benches/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod add;
mod div;
mod mul;
mod sub;
mod to_f64;

fn to_sign<I>(positive: bool) -> I
where
Expand Down Expand Up @@ -73,4 +74,5 @@ fn bench_integers<const D: u8, I>(
sub::bench_all::<D, I>(group);
mul::bench_all::<D, I>(group, lo_range.clone(), hi_mul_range);
div::bench_all::<D, I>(group, lo_range, hi_div_range);
to_f64::bench_all::<D, I>(group);
}
49 changes: 49 additions & 0 deletions benches/to_f64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use const_decimal::{Decimal, ScaledInteger};
use criterion::measurement::WallTime;
use criterion::{black_box, BatchSize, BenchmarkGroup};
use num_traits::PrimInt;
use prop::strategy::ValueTree;
use prop::test_runner::TestRunner;
use proptest::prelude::*;

pub fn bench_all<const D: u8, I>(group: &mut BenchmarkGroup<'_, WallTime>)
where
I: ScaledInteger<D> + Arbitrary,
{
bench_primitive_to_f64::<I>(group);
bench_decimal_to_f64::<D, I>(group);
}

fn bench_primitive_to_f64<I>(group: &mut BenchmarkGroup<'_, WallTime>)
where
I: PrimInt + Arbitrary,
{
// Use proptest to generate arbitrary input values.
let mut runner = TestRunner::deterministic();
let input = (I::arbitrary(), I::arbitrary());

group.bench_function("primitive/to_f64", |bencher| {
bencher.iter_batched(
|| input.new_tree(&mut runner).unwrap().current(),
|(a, b)| black_box(black_box(a) + black_box(b)),
BatchSize::SmallInput,
)
});
}

fn bench_decimal_to_f64<const D: u8, I>(group: &mut BenchmarkGroup<'_, WallTime>)
where
I: ScaledInteger<D> + Arbitrary,
{
// Use proptest to generate arbitrary input values.
let mut runner = TestRunner::deterministic();
let input = I::arbitrary().prop_map(|a| Decimal::<_, D>(a));

group.bench_function("decimal/to_f64", |bencher| {
bencher.iter_batched(
|| input.new_tree(&mut runner).unwrap().current(),
|a| black_box(a.to_f64()),
BatchSize::SmallInput,
)
});
}
26 changes: 25 additions & 1 deletion src/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Decimal, Int128_18, Int64_9, Uint128_18, Uint64_9};
use crate::{Decimal, Int128_18, Int64_9, ScaledInteger, Uint128_18, Uint64_9};

// TODO: Implement From generically where the result cannot overflow.
// TODO: Implement TryFrom generically where the result can overflow.
Expand All @@ -19,14 +19,27 @@ impl From<Int64_9> for Int128_18 {
}
}

impl<I, const D: u8> Decimal<I, D>
where
I: ScaledInteger<D>,
{
// SAFETY: `num_traits::to_f64` does not panic on primitive types.
#[allow(clippy::missing_panics_doc)]
pub fn to_f64(&self) -> f64 {
self.0.to_f64().unwrap() / I::SCALING_FACTOR.to_f64().unwrap()
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;

use proptest::prelude::Arbitrary;
use proptest::proptest;
use proptest::test_runner::TestRunner;

use super::*;
use crate::macros::generate_tests_for_common_variants;

#[test]
fn uint128_18_from_uint64_9() {
Expand Down Expand Up @@ -63,4 +76,15 @@ mod tests {
})
.unwrap();
}

generate_tests_for_common_variants!(to_f64_does_not_panic);

fn to_f64_does_not_panic<I, const D: u8>()
where
I: ScaledInteger<D> + Arbitrary,
{
proptest!(|(a: Decimal<I, D>)| {
a.to_f64();
});
}
}
6 changes: 1 addition & 5 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ macro_rules! apply_to_common_variants {
};
}

#[cfg(feature = "borsh")]
macro_rules! generate_tests_for_common_variants {
($f:ident) => {
crate::macros::generate_test!($f, u8, 1);
Expand All @@ -29,7 +28,6 @@ macro_rules! generate_tests_for_common_variants {
};
}

#[cfg(feature = "borsh")]
macro_rules! generate_test {
($f:ident, $underlying:ty, $decimals:literal) => {
::paste::paste! {
Expand All @@ -41,6 +39,4 @@ macro_rules! generate_test {
};
}

pub(crate) use apply_to_common_variants;
#[cfg(feature = "borsh")]
pub(crate) use {generate_test, generate_tests_for_common_variants};
pub(crate) use {apply_to_common_variants, generate_test, generate_tests_for_common_variants};

0 comments on commit ef44355

Please sign in to comment.