From 70d3b1330e30b3c9868335db1731ff4d8d53c8c8 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 31 Jul 2026 23:20:39 -0400 Subject: [PATCH] Use GMP factor removal for decimals --- benches/main.rs | 21 ++++++++++++++++++++- src/decimal.rs | 24 +++++++++--------------- src/lib.rs | 1 + 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/benches/main.rs b/benches/main.rs index 5e61542..309062e 100644 --- a/benches/main.rs +++ b/benches/main.rs @@ -1,9 +1,27 @@ use { criterion::{Criterion, criterion_group, criterion_main}, + rug::{Integer, Rational}, std::hint::black_box, - val::{Environment, Evaluator}, + val::{Config, Environment, Evaluator, Number}, }; +fn bench_decimal_display(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group("decimal_display"); + + for &(factor, exponent) in &[(2, 100), (2, 1_000), (5, 100), (5, 1_000)] { + let mut denominator = Integer::from(Integer::u_pow_u(factor, exponent)); + denominator *= 3; + + let number = Number::Exact(Rational::from((1, denominator))); + + group.bench_function(format!("3 * {factor}^{exponent}"), |bencher| { + bencher.iter(|| black_box(number.display(Config::default()))); + }); + } + + group.finish(); +} + fn bench_increment_value(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("increment_value"); @@ -104,6 +122,7 @@ fn bench_recursive_factorial(criterion: &mut Criterion) { criterion_group!( benches, + bench_decimal_display, bench_increment_value, bench_prime_count, bench_recursive_factorial diff --git a/src/decimal.rs b/src/decimal.rs index 2b0e0df..965ff76 100644 --- a/src/decimal.rs +++ b/src/decimal.rs @@ -64,10 +64,15 @@ impl Decimal { pub(crate) fn from_rational(number: &Rational) -> Option { let mut denominator = number.denom().clone(); - let (twos, fives) = ( - Self::remove_factor(&mut denominator, 2), - Self::remove_factor(&mut denominator, 5), - ); + let twos = usize::try_from( + denominator.remove_factor_mut(&MiniInteger::from(2).borrow()), + ) + .unwrap(); + + let fives = usize::try_from( + denominator.remove_factor_mut(&MiniInteger::from(5).borrow()), + ) + .unwrap(); if denominator != 1 { return None; @@ -110,17 +115,6 @@ impl Decimal { } } - fn remove_factor(number: &mut Integer, factor: u32) -> usize { - let mut count = 0; - - while number.is_divisible_u(factor) { - *number /= factor; - count += 1; - } - - count - } - fn scientific_string(&self, exponent: i64) -> String { let mantissa = if self.digits.len() == 1 { self.digits.clone() diff --git a/src/lib.rs b/src/lib.rs index 6497098..b117ba9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ use { rug::{ Complete, Float, Integer, Rational, float::{Constant, Round}, + integer::MiniInteger, ops::Pow, }, std::{