1use crate::helpers::pow_mod;
2use std::fmt::{Display, Formatter, LowerHex, UpperHex};
3
4mod display;
5
6#[derive(Clone, Debug, Default)]
8pub struct PiViewerBase256 {
9 start: u64,
10 buffer: Vec<u8>,
11}
12
13impl PiViewerBase256 {
14 pub fn new(start: u64, length: u64) -> Self {
16 let mut buffer = vec![0; length as usize];
17 for delta in 0..length {
18 let index = delta + start;
19 let digit = bbp256(index);
20 unsafe {
21 *buffer.get_unchecked_mut(delta as usize) = digit;
22 }
23 }
24 Self { start, buffer }
25 }
26}
27
28pub fn bbp256(digit: u64) -> u8 {
30 let f = [(1, 256.0), (4, -128.0), (5, -64.0), (6, -64.0), (9, 16.0), (12, -8.0), (13, -4.0), (14, -4.0)]
31 .iter()
32 .map(|&(j, k)| k * series_sum(digit, j))
33 .sum::<f64>();
34 ((f - f.floor()) * 256.0).floor() as u8
35}
36
37fn series_sum(digit: u64, j: u64) -> f64 {
38 let fraction1: f64 = (0..digit + 1)
39 .map(|i| pow_mod(16, digit - i, 16 * i + j) as f64 / (16 * i + j) as f64)
40 .fold(0.0, |x, y| (x + y).fract());
41 let fraction2: f64 = (digit + 1..)
42 .map(|i| 256.0_f64.powi(-((i - digit) as i32)) / ((16 * i + j) as f64))
43 .take_while(|&x| x.abs() > 1e-16_f64)
44 .sum();
45 fraction1 + fraction2
46}