From ec4a41f031005282a9160d5ddef1680ebf663c51 Mon Sep 17 00:00:00 2001 From: Aras14HD Date: Thu, 22 Jan 2026 12:21:49 +0100 Subject: [PATCH 1/2] fix off by one error at formatting negative floats --- factorion-lib/src/calculation_results.rs | 30 +++++++++++++++++++++++- factorion-lib/src/parse.rs | 18 ++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/factorion-lib/src/calculation_results.rs b/factorion-lib/src/calculation_results.rs index ce21f7b..85ee49c 100644 --- a/factorion-lib/src/calculation_results.rs +++ b/factorion-lib/src/calculation_results.rs @@ -568,11 +568,14 @@ fn truncate(number: &Integer, consts: &Consts) -> (String, bool) { } } fn format_float(acc: &mut String, number: &Float, consts: &Consts) -> std::fmt::Result { - // a.b x 10^c + // -a.b x 10^c + // - // a // .b // x 10^c let mut number = number.clone(); + let negative = number.is_sign_negative(); + number = number.abs(); let exponent = number .clone() .log10() @@ -605,6 +608,9 @@ fn format_float(acc: &mut String, number: &Float, consts: &Consts) -> std::fmt:: } decimal_part.push(digit); } + if negative { + acc.write_str("-")?; + } write!(acc, "{whole_number}")?; if !decimal_part.is_empty() && decimal_part != "0" { acc.write_str(".")?; @@ -756,6 +762,28 @@ mod tests { ); } + #[test] + fn test_format_float() { + let consts = Consts::default(); + let x = Float::with_val(consts.float_precision, 1.5); + let mut acc = String::new(); + format_float(&mut acc, &x, &consts).unwrap(); + assert_eq!(acc, "1.5"); + let x = Float::with_val(consts.float_precision, -1.5); + let mut acc = String::new(); + format_float(&mut acc, &x, &consts).unwrap(); + assert_eq!(acc, "-1.5"); + let x = Float::with_val(consts.float_precision, 1); + let mut acc = String::new(); + format_float(&mut acc, &x, &consts).unwrap(); + assert_eq!(acc, "1"); + let x = Float::with_val(consts.float_precision, 1.5) + * Float::with_val(consts.float_precision, 50000).exp10(); + let mut acc = String::new(); + format_float(&mut acc, &x, &consts).unwrap(); + assert_eq!(acc, "1.5 × 10^50000"); + } + #[test] fn test_factorial_format() { let consts = Consts::default(); diff --git a/factorion-lib/src/parse.rs b/factorion-lib/src/parse.rs index 1420330..30a63a5 100644 --- a/factorion-lib/src/parse.rs +++ b/factorion-lib/src/parse.rs @@ -1156,6 +1156,24 @@ mod test { ); } #[test] + fn test_negative_decimal() { + let consts = Consts::default(); + let jobs = parse( + "a factorial (-1.5)!", + true, + &consts, + &NumFormat::V1(&locale::v1::NumFormat { decimal: '.' }), + ); + assert_eq!( + jobs, + [CalculationJob { + base: CalculationBase::Num(Float::with_val(FLOAT_PRECISION, -1.5).into()), + level: 1, + negative: 0 + }] + ); + } + #[test] fn test_paren_negation() { let consts = Consts::default(); let jobs = parse( From 0f3b8e0ea60ac412e0268c8c3e20f99b9c5d7a49 Mon Sep 17 00:00:00 2001 From: Aras14HD Date: Thu, 22 Jan 2026 12:29:48 +0100 Subject: [PATCH 2/2] bump version fix --- Cargo.lock | 6 +++--- factorion-bot-discord/Cargo.toml | 4 ++-- factorion-bot-reddit/Cargo.toml | 4 ++-- factorion-lib/Cargo.toml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efb47ed..f5fc24e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "factorion-bot-discord" -version = "2.1.10" +version = "2.1.11" dependencies = [ "anyhow", "dotenvy", @@ -414,7 +414,7 @@ dependencies = [ [[package]] name = "factorion-bot-reddit" -version = "5.2.10" +version = "5.2.11" dependencies = [ "anyhow", "base64 0.22.1", @@ -434,7 +434,7 @@ dependencies = [ [[package]] name = "factorion-lib" -version = "4.1.10" +version = "4.1.11" dependencies = [ "arbtest", "chrono", diff --git a/factorion-bot-discord/Cargo.toml b/factorion-bot-discord/Cargo.toml index 0faa25f..dda5e49 100644 --- a/factorion-bot-discord/Cargo.toml +++ b/factorion-bot-discord/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factorion-bot-discord" -version = "2.1.10" +version = "2.1.11" edition = "2024" description = "factorion-bot (for factorials and related) on Discord" license = "MIT" @@ -10,7 +10,7 @@ keywords = ["factorial", "termial", "bot", "math", "discord"] categories = ["mathematics", "web-programming", "parser-implementations"] [dependencies] -factorion-lib = { path = "../factorion-lib", version = "4.1.10", features = ["serde", "influxdb"] } +factorion-lib = { path = "../factorion-lib", version = "4.1.11", features = ["serde", "influxdb"] } serenity = { version = "0.12", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] } tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread", "time"] } dotenvy = "^0.15.7" diff --git a/factorion-bot-reddit/Cargo.toml b/factorion-bot-reddit/Cargo.toml index 85661ef..a8a5e7c 100644 --- a/factorion-bot-reddit/Cargo.toml +++ b/factorion-bot-reddit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factorion-bot-reddit" -version = "5.2.10" +version = "5.2.11" edition = "2024" description = "factorion-bot (for factorials and related) on Reddit" license = "MIT" @@ -10,7 +10,7 @@ keywords = ["factorial", "termial", "bot", "math"] categories = ["mathematics", "web-programming", "parser-implementations"] [dependencies] -factorion-lib = {path = "../factorion-lib", version = "4.1.10", features = ["serde", "influxdb"]} +factorion-lib = {path = "../factorion-lib", version = "4.1.11", features = ["serde", "influxdb"]} reqwest = { version = "0.12.26", features = ["json", "native-tls"], default-features = false } serde = { version = "1.0.219", default-features = false, features = ["derive"] } serde_json = "1.0.140" diff --git a/factorion-lib/Cargo.toml b/factorion-lib/Cargo.toml index 42f5b41..6c0515b 100644 --- a/factorion-lib/Cargo.toml +++ b/factorion-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "factorion-lib" -version = "4.1.10" +version = "4.1.11" edition = "2024" description = "A library used to create bots to recognize and calculate factorials and related concepts" license = "MIT"