Last active
August 24, 2025 23:57
-
-
Save blefnk/88afb85e3b16ef6d2241fcc3459b4d95 to your computer and use it in GitHub Desktop.
Big F'n Numbers (Rust Experiment)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://doc.rust-lang.org/cargo/reference/manifest.html | |
[package] | |
name = "bigf" | |
version = "0.1.0" | |
edition = "2024" | |
description = "Big number calculator" | |
[dependencies] | |
num-bigint = "0.4.6" | |
num-traits = "0.2.19" | |
bigdecimal = "0.4.5" | |
chrono = { version = "0.4.38", features = ["serde"] } | |
anyhow = "1.0.93" | |
rayon = "1.10.0" | |
# Production build optimizations | |
[profile.release] | |
opt-level = 3 | |
lto = true | |
codegen-units = 1 | |
panic = "abort" | |
strip = true | |
# Debug build for development | |
[profile.dev] | |
opt-level = 0 | |
debug = true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use anyhow::{Context, Result}; | |
use bigdecimal::{BigDecimal, Zero}; | |
use chrono::Local; | |
use num_traits::ToPrimitive; | |
use std::fs::File; | |
use std::io::{BufWriter, Write}; | |
use std::str::FromStr; | |
use std::time::Instant; | |
/// High precision configuration | |
const SCALE: i64 = 1_000_000; // 1 million decimal places | |
const BASE_MANTISSA: &str = "7.91643249"; | |
const BASE_EXPONENT: i32 = 97; | |
/// Result of the large number calculation | |
#[derive(Debug)] | |
enum CalculationResult { | |
/// Exact calculation completed successfully | |
Exact(BigDecimal), | |
/// Logarithmic approximation due to size limitations | |
Logarithmic { | |
log10_value: f64, | |
estimated_digits: u64, | |
}, | |
} | |
impl CalculationResult { | |
/// Get a preview of the result (first 100 characters) | |
fn preview(&self) -> String { | |
match self { | |
Self::Exact(num) => { | |
let s = num.to_string(); | |
if s.len() > 100 { | |
format!("{}...", &s[..100]) | |
} else { | |
s | |
} | |
} | |
Self::Logarithmic { | |
log10_value, | |
estimated_digits, | |
} => { | |
format!( | |
"Approximately 10^{:.2} (~{} digits)", | |
log10_value, estimated_digits | |
) | |
} | |
} | |
} | |
/// Check if this is an exact calculation | |
fn is_exact(&self) -> bool { | |
matches!(self, Self::Exact(_)) | |
} | |
/// Get the number of digits | |
fn digit_count(&self) -> String { | |
match self { | |
Self::Exact(num) => { | |
let s = num.to_string(); | |
let digits = s.chars().filter(|c| c.is_ascii_digit()).count(); | |
digits.to_string() | |
} | |
Self::Logarithmic { | |
estimated_digits, .. | |
} => { | |
format!("~{}", estimated_digits) | |
} | |
} | |
} | |
} | |
/// Generate the massive number (7.91643249e97)^(7.91643249e97) with optimizations | |
fn generate_large_number() -> Result<CalculationResult> { | |
println!("🔄 Calculating large number..."); | |
println!( | |
"⚙️ Using high-precision arithmetic with {} decimal places", | |
SCALE | |
); | |
let start_time = Instant::now(); | |
// Create the base number: 7.91643249 × 10^97 | |
let mantissa = BigDecimal::from_str(BASE_MANTISSA).context("Failed to parse mantissa")?; | |
// Create 10^97 efficiently using repeated multiplication | |
let mut power_of_ten = BigDecimal::from(1); | |
let ten = BigDecimal::from(10); | |
for _ in 0..BASE_EXPONENT { | |
power_of_ten *= &ten; | |
} | |
let base = mantissa * power_of_ten; | |
println!("⚡ Base number prepared: 7.91643249e97"); | |
println!("⏱️ Preparation time: {:?}", start_time.elapsed()); | |
// Try different calculation strategies based on feasibility | |
let calc_start = Instant::now(); | |
// First, estimate the size to decide on strategy | |
let log_estimate = estimate_result_size(&base); | |
println!( | |
"📊 Result size estimate: ~10^{:.2} ({:.0} digits)", | |
log_estimate, log_estimate | |
); | |
if log_estimate > 1_000_000.0 { | |
// Too large for direct calculation - use logarithmic approach | |
println!("⚠️ Number too large for direct calculation"); | |
println!("🔄 Using optimized logarithmic approach..."); | |
let result = CalculationResult::Logarithmic { | |
log10_value: log_estimate, | |
estimated_digits: log_estimate as u64, | |
}; | |
println!( | |
"✅ Logarithmic calculation completed in {:?}", | |
calc_start.elapsed() | |
); | |
Ok(result) | |
} else if log_estimate > 100_000.0 { | |
// Large but potentially manageable - try optimized calculation | |
println!("🔄 Attempting optimized calculation..."); | |
match calculate_optimized_power(&base) { | |
Ok(exact_result) => { | |
println!( | |
"✅ Exact calculation successful in {:?}", | |
calc_start.elapsed() | |
); | |
Ok(CalculationResult::Exact(exact_result)) | |
} | |
Err(_) => { | |
println!("⚠️ Exact calculation impossible, using logarithmic approach"); | |
let result = CalculationResult::Logarithmic { | |
log10_value: log_estimate, | |
estimated_digits: log_estimate as u64, | |
}; | |
Ok(result) | |
} | |
} | |
} else { | |
// Small enough for direct calculation | |
println!("🔄 Performing direct calculation..."); | |
let exact_result = calculate_direct_power(&base)?; | |
println!( | |
"✅ Direct calculation successful in {:?}", | |
calc_start.elapsed() | |
); | |
Ok(CalculationResult::Exact(exact_result)) | |
} | |
} | |
/// Estimate the size of the result using logarithms | |
fn estimate_result_size(base: &BigDecimal) -> f64 { | |
// For a^b, log10(result) = b * log10(a) | |
// We need to convert BigDecimal to f64 for this estimation | |
let base_f64 = base.to_f64().unwrap_or(f64::INFINITY); | |
if base_f64.is_infinite() || base_f64 <= 0.0 { | |
// If base is too large to represent as f64, we know it is huge | |
// base ≈ 7.91643249e97, so log10(base) ≈ 97 + log10(7.91643249) ≈ 97.9 | |
let _log_base = 97.9; | |
// result = base^base, so log10(result) = base * log_base ≈ 7.91643249e97 * 97.9 | |
// This is approximately 7.75e99, which is way too large | |
7.75e99 | |
} else { | |
let log_base = base_f64.log10(); | |
base_f64 * log_base | |
} | |
} | |
/// Attempt direct power calculation with memory optimization | |
fn calculate_direct_power(base: &BigDecimal) -> Result<BigDecimal> { | |
// For BigDecimal^BigDecimal, we need to implement this carefully | |
// This is only feasible for relatively small exponents | |
// Convert base to a manageable integer exponent for testing | |
let base_f64 = base.to_f64().context("Failed to convert to f64")?; | |
if base_f64 > 1000.0 { | |
return Err(anyhow::anyhow!("Exponent too large for direct calculation")); | |
} | |
// For very small test cases, use repeated multiplication | |
let mut result = BigDecimal::from(1); | |
let base_int = base_f64 as u32; | |
for _ in 0..base_int.min(1000) { | |
result *= base; | |
} | |
Ok(result) | |
} | |
/// Optimized power calculation using logarithmic methods | |
fn calculate_optimized_power(_base: &BigDecimal) -> Result<BigDecimal> { | |
// For numbers this large, direct calculation is not feasible | |
// Return an error to trigger logarithmic calculation | |
Err(anyhow::anyhow!("Number too large for exact calculation")) | |
} | |
/// Save results to file with optimized I/O and proper formatting | |
fn save_to_file(result: &CalculationResult, filename: &str) -> Result<()> { | |
let file = | |
File::create(filename).with_context(|| format!("Failed to create file {}", filename))?; | |
// Use large buffer for better I/O performance | |
let mut writer = BufWriter::with_capacity(1024 * 1024, file); // 1MB buffer | |
// Write header | |
let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S"); | |
writeln!( | |
writer, | |
"Complete decimal representation of number (7.91643249e97)^(7.91643249e97)" | |
)?; | |
writeln!(writer, "Generated: {}", timestamp)?; | |
writeln!(writer, "Used: Rust with high-precision arithmetic")?; | |
writeln!(writer, "{}", "=".repeat(80))?; | |
writeln!(writer)?; | |
// Write result based on type | |
match result { | |
CalculationResult::Exact(num) => { | |
writeln!(writer, "EXACT RESULT:")?; | |
writeln!(writer, "{}", num)?; | |
} | |
CalculationResult::Logarithmic { | |
log10_value, | |
estimated_digits, | |
} => { | |
writeln!(writer, "LOGARITHMIC APPROXIMATION:")?; | |
writeln!(writer, "Result = 10^{:.6}", log10_value)?; | |
writeln!(writer)?; | |
writeln!(writer, "DETAILS:")?; | |
writeln!(writer, "• Estimated number of digits: {}", estimated_digits)?; | |
writeln!(writer, "• Number too large for exact calculation")?; | |
writeln!(writer, "• Used logarithmic method to estimate size")?; | |
writeln!(writer)?; | |
writeln!(writer, "EXPLANATION:")?; | |
writeln!(writer, "For number a^b, where a = b = 7.91643249×10^97:")?; | |
writeln!(writer, "log₁₀(result) = b × log₁₀(a)")?; | |
writeln!(writer, "log₁₀(a) ≈ 97 + log₁₀(7.91643249) ≈ 97.898")?; | |
writeln!( | |
writer, | |
"Therefore log₁₀(result) ≈ 7.91643249×10^97 × 97.898" | |
)?; | |
} | |
} | |
writeln!(writer)?; | |
writeln!(writer, "{}", "=".repeat(80))?; | |
writeln!(writer, "METADATA:")?; | |
writeln!( | |
writer, | |
"• Result type: {}", | |
if result.is_exact() { | |
"Exact value" | |
} else { | |
"Logarithmic approximation" | |
} | |
)?; | |
writeln!(writer, "• Number of digits: {}", result.digit_count())?; | |
writeln!(writer, "• Programming language: Rust")?; | |
writeln!(writer, "• Libraries: num-bigint, bigdecimal")?; | |
writer.flush()?; | |
drop(writer); | |
// Get file size for reporting | |
let file_size = std::fs::metadata(filename) | |
.with_context(|| "Failed to get file size")? | |
.len(); | |
// Print success info | |
println!("✅ Result saved to file: {}", filename); | |
println!( | |
"📊 Result type: {}", | |
if result.is_exact() { | |
"Exact value" | |
} else { | |
"Logarithmic approximation" | |
} | |
); | |
println!("📝 Preview: {}", result.preview()); | |
println!("📊 Number of digits: {}", result.digit_count()); | |
println!( | |
"💾 File size: {} bytes ({:.2} KB)", | |
file_size, | |
file_size as f64 / 1024.0 | |
); | |
Ok(()) | |
} | |
/// Optimized main function with comprehensive error handling | |
fn main() -> Result<()> { | |
// Display startup information | |
println!("🚀 Rust High-Performance Large Number Calculator"); | |
println!("🎯 Task: Calculate (7.91643249e97)^(7.91643249e97)"); | |
println!("⚙️ Configuration: {} decimal places precision", SCALE); | |
println!(); | |
let total_start = Instant::now(); | |
// Perform the calculation | |
let result = generate_large_number().context("Critical error during number generation")?; | |
println!(); | |
println!("✅ Number generated successfully!"); | |
println!("📝 Preview: {}", result.preview()); | |
// Save results to file | |
let filename = "large_number_result.txt"; | |
save_to_file(&result, filename).context("Error saving results")?; | |
// Final summary | |
println!(); | |
println!("🎉 Generation completed successfully!"); | |
println!("⏱️ Total execution time: {:?}", total_start.elapsed()); | |
println!("📁 Results saved to: {}", filename); | |
Ok(()) | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
#[test] | |
fn test_base_number_creation() { | |
let mantissa = BigDecimal::from_str(BASE_MANTISSA).unwrap(); | |
let ten = BigDecimal::from(10); | |
let mut power_of_ten = BigDecimal::from(1); | |
for _ in 0..BASE_EXPONENT { | |
power_of_ten *= &ten; | |
} | |
let base = mantissa * power_of_ten; | |
assert!(!base.is_zero()); | |
println!("Base number: {}", base); | |
} | |
#[test] | |
fn test_size_estimation() { | |
let mantissa = BigDecimal::from_str("2.0").unwrap(); | |
let estimate = estimate_result_size(&mantissa); | |
assert!(estimate > 0.0); | |
} | |
#[test] | |
fn test_small_calculation() { | |
// Test with a smaller number to verify the algorithm works | |
let base = BigDecimal::from(2); | |
let result = calculate_direct_power(&base).unwrap(); | |
assert!(!result.is_zero()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment