lib-nested/nested/src/editors/integer/add.rs

71 lines
1.9 KiB
Rust
Raw Normal View History

2021-04-29 01:32:59 +02:00
use {
2023-02-13 18:39:45 +01:00
r3vi::{
view::{
InnerViewPort, OuterViewPort,
sequence::*,
},
buffer::{
vec::*
},
projection::projection_helper::*,
2021-11-19 12:19:52 +01:00
},
std::sync::{Arc, RwLock},
2021-04-29 01:32:59 +02:00
};
fn posint_add(
radix: usize,
a: impl SequenceView<Item = usize>,
2021-11-19 12:19:52 +01:00
b: impl SequenceView<Item = usize>,
2021-04-29 01:32:59 +02:00
) -> Vec<usize> {
let mut carry = 0;
let mut result = Vec::new();
2021-11-19 12:19:52 +01:00
for digit_idx in 0..std::cmp::max(a.len().unwrap_or(0), b.len().unwrap_or(0)) {
let sum = a.get(&digit_idx).unwrap_or(0) + b.get(&digit_idx).unwrap_or(0) + carry;
2021-04-29 01:32:59 +02:00
result.push(sum % radix);
2021-11-19 12:19:52 +01:00
carry = if sum > radix { sum - radix } else { 0 };
2021-04-29 01:32:59 +02:00
}
if carry > 0 {
result.push(carry);
}
result
}
pub struct Add {
radix: usize,
a: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
b: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
c: VecBuffer<usize>,
2021-11-19 12:19:52 +01:00
_proj_helper: ProjectionHelper<usize, Self>,
2021-04-29 01:32:59 +02:00
}
impl Add {
pub fn new(
radix: usize,
a: OuterViewPort<dyn SequenceView<Item = usize>>,
b: OuterViewPort<dyn SequenceView<Item = usize>>,
2021-11-19 12:19:52 +01:00
c: InnerViewPort<RwLock<Vec<usize>>>, //<dyn SequenceView<Item = usize>>
2021-04-29 01:32:59 +02:00
) -> Arc<RwLock<Self>> {
let mut proj_helper = ProjectionHelper::new(c.0.update_hooks.clone());
2021-11-19 12:19:52 +01:00
let add = Arc::new(RwLock::new(Add {
radix,
a: proj_helper.new_sequence_arg(0, a, |s: &mut Self, _digit_idx| s.update()),
b: proj_helper.new_sequence_arg(1, b, |s: &mut Self, _digit_idx| s.update()),
c: VecBuffer::with_port(c),
2021-11-19 12:19:52 +01:00
_proj_helper: proj_helper,
}));
2021-04-29 01:32:59 +02:00
add
}
fn update(&mut self) {
self.c.clear();
for digit in posint_add(self.radix, self.a.clone(), self.b.clone()) {
self.c.push(digit);
}
}
}