Convert BigFloat to BigUint (from num_bigint)
Janmajayamall opened this issue · 8 comments
Thanks for the lib! It has been immensely helpful.
I am running into issues converting a BigFloat instance to BigUint (from num_bigint). My naive try is
let mut consts = Consts::new().unwrap();
let mut value = BigFloat::from(1.2);
let (sign, radix_repr, ex) = value
.round(0, ROUNDING_MODE)
.convert_to_radix(astro_float::Radix::Dec, ROUNDING_MODE, &mut consts)
.unwrap();
// Assume sign is always positive
let value_biguint = BigUint::from_radix_be(&radix_repr, 10).unwrap();
I though that setting to n to 0 (i.e. fractional digits are decimal) will round the value to 1, hence mantissa will 1 and exp will be 0. But this isn't the case. Probably I am misreding the docs. Can you point me to a function using which I can round the value towards 0 and mantissa will drop rounded-off digits?
round
is the function that can round fractional part of a number.
What's the value of this ROUNDING_MODE
?
Also, rounding will not change exponent of a number, unless there was overflow during rounding.
What's the value of this ROUNDING_MODE ?
It is set to none - RoundingMode::None
Ok, so seems like the only way is to read the mantissa after rounding as a string. Drop off digits after decimal as per the exponent. Then parse the resulting string of digits into BigUint. Do you think there's a better way to do this?
This is what I came up with:
let mut consts = Consts::new().unwrap();
let mut value = AstroBFloat::from(1.2);
let (sign, radix_repr, mut ex) = value
.round(0, ROUNDING_MODE)
.convert_to_radix(astro_float::Radix::Dec, ROUNDING_MODE, &mut consts)
.unwrap();
if ex < 0 {
ex = 0;
}
// Assume sign is always positive
let value_biguint = BigUint::from_radix_be(&radix_repr[..ex as usize], 10).unwrap();
Sorry for late reply!
Is this what you had in mind ?
// PRECISION = 256
// MANTISSA_LEN = 4
let value = value.0.clone();
let (raw, _, s, _, _) = value.as_raw_parts().unwrap();
let exponent = value.exponent().unwrap();
let mut bits = exponent;
let mut index = MATISSA_LEN - 1;
let mut res = BigInt::zero();
while bits > 0 {
res += (BigInt::from_u64(raw[index as usize]).unwrap())
<< (astro_float::WORD_BIT_SIZE * index);
bits -= astro_float::WORD_BIT_SIZE as i32;
index -= 1;
}
res >>= (PRECISION as i32) - exponent;
res = if s.is_negative() { res.neg() } else { res }
Closing the issue as it is not a bug.