Split BBP to own mod.

This commit is contained in:
2016-06-04 09:42:32 +02:00
parent e8e1211abd
commit 75b63a9a78
2 changed files with 98 additions and 96 deletions

93
src/bbp.rs Normal file
View File

@@ -0,0 +1,93 @@
pub fn get_byte(id: i32) -> u8 {
let pid : f64 = 4.0 * series(1, id) - 2.0 * series(4, id) - series(5, id) - series(6, id);
let mut y : f64 = (pid - (pid as i32) as f64 + 1.0).abs(); // TODO use .trunc() instead
y = 16.0 * (y - y.floor()); // TODO use .trunc() instead of floor?
let first : u8 = y as u8;
y = 16.0 * (y - y.floor()); // TODO use .trunc() instead of floor?
let second : u8 = y as u8;
(first << 4) | second
}
fn series(m: i32, id: i32) -> f64 {
const EPS : f64 = 1e-17;
let mut ak : f64;
let mut t : f64;
let mut s : f64 = 0.0;
for k in 0..id {
ak = (8 * k + m) as f64;
t = expm((id - k) as f64, ak);
s += t / ak;
s -= (s as i32) as f64; // TODO: use .truc() instead.
}
for k in id..id + 101 {
ak = (8 * k + m) as f64;
t = 16f64.powi(id - k) / ak;
if t < EPS {
break;
}
s += t;
s -= (s as i32) as f64; // TODO: use .truc() instead.
}
s
}
fn expm(p: f64, ak: f64) -> f64 {
if ak == 1.0 {
return 0.0;
}
const NTP : usize = 25;
lazy_static! {
static ref TP : Vec<f64> = {
let mut v = vec![1f64; NTP];
for i in 1..NTP {
v[i] = 2.0 * v[i - 1];
}
v
};
}
let mut i : usize = 0;
while TP[i] <= p {
i += 1;
}
let mut pt = TP[i - 1];
let mut p1 : f64 = p; // TODO: use p instead of p1?
let mut r : f64 = 1.0;
for _ in 1..i + 1 {
if p1 >= pt {
r = 16.0 * r;
r = r - ((r / ak) as i32) as f64 * ak; // TODO: use .truc() instead.
p1 -= pt;
}
pt = 0.5 * pt;
if pt >= 1.0 {
r *= r;
r -= ((r / ak) as i32) as f64 * ak; // TODO: use .truc() instead.
}
}
r
}

View File

@@ -1,6 +1,7 @@
extern crate getopts; extern crate getopts;
extern crate byteorder; extern crate byteorder;
extern crate pbr; extern crate pbr;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@@ -15,6 +16,8 @@ use getopts::Options;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian}; use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use pbr::{ProgressBar, Units}; use pbr::{ProgressBar, Units};
mod bbp;
fn main() { fn main() {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
@@ -68,7 +71,7 @@ fn compress(input: &String, output: &String) {
let b = b.unwrap(); let b = b.unwrap();
for n in 0..i32::MAX { for n in 0..i32::MAX {
if b == get_byte(n) { if b == bbp::get_byte(n) {
i = n; i = n;
break; break;
} }
@@ -105,102 +108,8 @@ fn extract(input: &String, output: &String) {
let mut c = Cursor::new(&buf); let mut c = Cursor::new(&buf);
let index = c.read_i32::<LittleEndian>().unwrap(); let index = c.read_i32::<LittleEndian>().unwrap();
output_file.write_all(&[get_byte(index)]).unwrap(); output_file.write_all(&[bbp::get_byte(index)]).unwrap();
pb.add(size as u64); pb.add(size as u64);
} }
} }
fn get_byte(id: i32) -> u8 {
let pid : f64 = 4.0 * series(1, id) - 2.0 * series(4, id) - series(5, id) - series(6, id);
let mut y : f64 = (pid - (pid as i32) as f64 + 1.0).abs();
y = 16.0 * (y - y.floor());
let first : u8 = y as u8;
y = 16.0 * (y - y.floor());
let second : u8 = y as u8;
(first << 4) | second
}
fn series(m: i32, id: i32) -> f64 {
const EPS : f64 = 1e-17;
let mut ak : f64;
let mut t : f64;
let mut s : f64 = 0.0;
for k in 0..id {
ak = (8 * k + m) as f64;
t = expm((id - k) as f64, ak);
s += t / ak;
s -= (s as i32) as f64;
}
for k in id..id + 101 {
ak = (8 * k + m) as f64;
t = 16f64.powi(id - k) / ak;
if t < EPS {
break;
}
s += t;
s -= (s as i32) as f64;
}
s
}
fn expm(p: f64, ak: f64) -> f64 {
if ak == 1.0 {
return 0.0;
}
const NTP : usize = 25;
lazy_static! {
static ref TP : Vec<f64> = {
let mut v = vec![1f64; NTP];
for i in 1..NTP {
v[i] = 2.0 * v[i - 1];
}
v
};
}
let mut i : usize = 0;
while TP[i] <= p {
i += 1;
}
let mut pt = TP[i - 1];
let mut p1 : f64 = p;
let mut r : f64 = 1.0;
for _ in 1..i + 1 {
if p1 >= pt {
r = 16.0 * r;
r = r - ((r / ak) as i32) as f64 * ak;
p1 -= pt;
}
pt = 0.5 * pt;
if pt >= 1.0 {
r *= r;
r -= ((r / ak) as i32) as f64 * ak;
}
}
r
}