use crate::ptr::Ptr;
use crate::types::owner::Owner;
use crate::types::precision::Precision;
use crate::types::rounding_mode::RoundingMode;
use crate::types::rounding_rpsp::RPSP;
use crate::types::sci::Sci;
impl Sci {
pub(crate) fn round_assign(&mut self, precision: Precision, rounding: RoundingMode) {
let len = self.precision_len(precision);
if len < 0 {
if let (RoundingMode::RPSP(RPSP), Precision::Decimals(d)) = (rounding, precision) {
self.exponent = -d;
self.assign_one();
} else {
self.assign_zero();
}
} else if len >= self.len {
} else if !rounding.round_away_from_zero(
self.sign.is_negative(),
if len == 0 { 0 } else { self.data[len - 1] },
self.data[len],
len + 1 == self.len,
) {
self.truncate_assign(Precision::Digits(len));
} else if len == 0 {
self.exponent += self.len;
self.assign_one();
} else {
self.exponent += self.len - len;
self.len = len;
let mut ptr = make_writeable(self);
ptr.mut_offset(self.len - 1);
while self.len > 0 && *ptr == 9 {
self.len -= 1;
self.exponent += 1;
ptr.dec();
}
if self.len == 0 {
self.assign_one();
} else {
*ptr += 1;
}
}
}
}
fn make_writeable(sci: &mut Sci) -> Ptr {
match sci.owner.make_writeable() {
Ok(_) => {
}
Err(_) => {
let vec = sci.data.as_slice(sci.len).to_vec();
sci.data = Ptr::new(vec.as_slice());
sci.owner = Owner::new_vec(vec);
}
}
sci.data.as_mutable() }