婆罗门
精华
|
战斗力 鹅
|
回帖 0
注册时间 2015-3-20
|
本帖最后由 Xerxes_2 于 2024-12-15 14:52 编辑
代码逻辑严格参照之前的 JS 版
纯控制台程序,要做手机 App 的话比较麻烦,先写个桌面平台的,暂时编了 x86 Win 和 arm macOS,其他平台可以自己编,不难
另外由于测试时间短,方差大,可以多跑几次取最小值 更新跑 100 次取平均,print写错了 50 次不影响
- use bigdecimal::{BigDecimal, Context, One};
- use std::{borrow::Cow, num::NonZero};
- fn main() {
- println!("开始计算, 50次……");
- let mut res = Vec::with_capacity(50);
- const BIT: usize = 500;
- for _ in 0..100 {
- let start = std::time::Instant::now();
- let cx = Context::new(
- NonZero::new(1006).unwrap(),
- bigdecimal::RoundingMode::HalfEven,
- );
- let mut polygon = BigDecimal::from(6);
- let r = BigDecimal::one();
- let mut big_m = Cow::Borrowed(&r);
- loop {
- let big_g = (&r.square() - (big_m.as_ref() / 2u8).square())
- .sqrt_with_context(&cx)
- .unwrap();
- let j = &r - big_g;
- let m = ((big_m.as_ref() / 2u8).square() + j.square())
- .sqrt_with_context(&cx)
- .unwrap();
- polygon = polygon * 2u8;
- let perimeter = &polygon * &m;
- let pi = &perimeter / 2u8;
- big_m = Cow::Owned(m);
- let pi_string = pi.to_string();
- const PI: &str = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989";
- if pi_string[0..BIT + 2] == PI[0..BIT + 2] {
- res.push(start.elapsed());
- break;
- }
- }
- }
- let sum = res.iter().sum::<std::time::Duration>();
- let min = res.iter().min().unwrap();
- let max = res.iter().max().unwrap();
- let avg = sum / res.len() as u32;
- println!("平均耗时: {:?}", avg);
- println!("最短耗时: {:?}", min);
- println!("最长耗时: {:?}", max);
- let variance = res
- .iter()
- .map(|x| {
- let x = x.as_secs_f64() * 1_000.0;
- (x - avg.as_secs_f64() * 1_000.0).powi(2)
- })
- .sum::<f64>()
- / res.len() as f64;
- println!("标准差: {}ms", variance.sqrt());
- println!("按Enter退出……");
- let _ = std::io::stdin().read_line(&mut String::new());
- }
复制代码
再更新一个用 gmp 的,这个应该就是目前算法的极限了
- use rug::{
- Float, Integer,
- float::Round,
- ops::{AddAssignRound, DivAssignRound},
- };
- fn main() {
- println!("开始计算, 100次……");
- let mut res = Vec::with_capacity(100);
- const BIT: usize = 500;
- for _ in 0..100 {
- let start = std::time::Instant::now();
- let mut polygon = Integer::from(6);
- const R: &Integer = Integer::ONE;
- let mut big_m = Float::with_val(1669, 1);
- loop {
- big_m.square_mut();
- big_m.div_assign_round(4, Round::Nearest);
- let big_g = (R - big_m.to_owned()).sqrt();
- let j = R - big_g;
- big_m.add_assign_round(j.square(), Round::Nearest);
- big_m.sqrt_mut();
- polygon *= 2;
- let perimeter = big_m.to_owned() * &polygon;
- let mut pi = perimeter;
- pi.div_assign_round(2, Round::Nearest);
- let pi_string = pi.to_string();
- const PI: &str = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989";
- if let Some(slice) = pi_string.get(0..BIT + 2) {
- if slice == &PI[0..BIT + 2] {
- res.push(start.elapsed());
- break;
- }
- }
- }
- }
- let sum = res.iter().sum::<std::time::Duration>();
- let min = res.iter().min().unwrap();
- let max = res.iter().max().unwrap();
- let avg = sum / res.len() as u32;
- println!("平均耗时: {:?}", avg);
- println!("最短耗时: {:?}", min);
- println!("最长耗时: {:?}", max);
- let variance = res
- .iter()
- .map(|x| {
- let x = x.as_secs_f64() * 1_000.0;
- (x - avg.as_secs_f64() * 1_000.0).powi(2)
- })
- .sum::<f64>()
- / res.len() as f64;
- println!("标准差: {}ms", variance.sqrt());
- println!("按Enter退出……");
- let _ = std::io::stdin().read_line(&mut String::new());
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|