1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::str;
use std::str::FromStr;
use crate::arithmetic::sign::Sign;
use crate::arithmetic::sliceops::*;
fn string_format(x: u64) -> String {
let k = x.to_string();
let leading = (0..(19 - k.len())).map(|_| "0").collect::<String>();
leading + &k
}
pub(crate) fn to_string(sign: Sign, digits: Vec<u64>) -> String {
if digits.is_empty() {
return "".to_string();
}
if digits.len() == 1 {
let p = digits[0].to_string();
if sign == Sign::Negative {
return "-".to_owned() + &p;
} else {
return p;
}
}
let mut k = vec![];
let mut x = digits;
x.push(0u64);
loop {
let idx = sig_pos(&x[..]);
if idx == 0 {
break;
}
k.push(div_slice(&mut x[..idx], 0x8AC7230489E80000u64));
}
k.push(x[0] % 0x8AC7230489E80000u64);
let mut count = 0usize;
for i in k.iter().rev() {
if *i > 0u64 {
break;
}
count += 1;
}
k.truncate(k.len() - count);
let len = k.len() - 1;
let interim = k[..len]
.iter()
.rev()
.map(|x| string_format(*x))
.collect::<Vec<String>>();
let last = k[len].to_string() + &interim.join("");
if sign == Sign::Negative {
return "-".to_string() + &last;
}
last
}
pub(crate) fn from_string(string: &str) -> Option<Vec<u64>> {
let b = string.bytes().all(|c| c.is_ascii_digit());
if !b {
return None;
}
let ln = 19usize;
let strln = string.len();
let strem = strln % ln;
let t = string.as_bytes();
let start = 0usize;
let mut k = vec![];
for i in 0..strln / ln {
k.push(str::from_utf8(&t[(strln - (i + 1) * ln)..(strln - i * ln)]).unwrap())
}
if strem != 0 {
if str::from_utf8(&t[start..strem]).unwrap() != "" {
k.push(str::from_utf8(&t[start..strem]).unwrap());
}
}
let x = k
.iter()
.rev()
.map(|x| u64::from_str(x).unwrap())
.collect::<Vec<u64>>(); let mut z = vec![0];
for i in 0..x.len() {
let mut carry = scale_slice(&mut z[..], 0x8AC7230489E80000);
if carry > 0 {
z.push(carry)
}
carry = add_slice(&mut z[..], &x[i..(i + 1)]) as u64;
if carry > 0 {
z.push(carry)
}
}
Some(z)
}