1

What is the maximum number of digits that can be parsed as u128. I am encountering Err(ParseIntError { kind: Overflow }) while trying to parse 50 digit positive integer.

My error:

...
...
result: id 89 "40789923115535562561142322423255033685442488917353"      Err(ParseIntError { kind: Overflow })
result: id 90 "44889911501440648020369068063960672322193204149535"      Err(ParseIntError { kind: Overflow })
result: id 91 "41503128880339536053299340368006977710650566631954"      Err(ParseIntError { kind: Overflow })
result: id 92 "81234880673210146739058568557934581403627822703280"      Err(ParseIntError { kind: Overflow })
result: id 93 "82616570773948327592232845941706525094512325230608"      Err(ParseIntError { kind: Overflow })
result: id 94 "22918802058777319719839450180888072429661980811197"      Err(ParseIntError { kind: Overflow })
result: id 95 "77158542502016545090413245809786882778948721859617"      Err(ParseIntError { kind: Overflow })
result: id 96 "72107838435069186155435662884062257473692284509516"      Err(ParseIntError { kind: Overflow })
result: id 97 "20849603980134001723930671666823555245252804609722"      Err(ParseIntError { kind: Overflow })
result: id 98 "53503534226472524250874054075591789781264330331690"      Err(ParseIntError { kind: Overflow })
...
...

Corresponding code for this:

fn read_num(a: &mut Reader<File>) -> Result<u128, Error> {
    let mut sum: u128 = 0;
    for(idx, res) in a.records().enumerate() {
        let res = res.unwrap();
        let val: StringRecord = res;
        let ii = val.get(0).unwrap().trim().parse::<u128>().unwrpa();
        println!("result: id {} {:?}\t {:?}", idx, val.get(0).unwrap(), ii);
    }; // This is formatted
    Ok(sum)
}

I initially thought it must be due the new line character at the end of every line, but trim supposed to remove that and it looks to me that it is removing, because the unparsed output doesn't seem to have anything except the \t formatter in the println!

Is the overflow due to inherent limitation or something that I am doing wrong?

Bussller
  • 1,961
  • 6
  • 36
  • 50
  • Thanks @RayToal. I have just found that. Does that mean, I cannot parse a 50digit positive integer at all using Rust primitive types? – Bussller Jun 15 '19 at 07:52
  • 2
    The largest u128 is 2**128-1 = 340282366920938463463374607431768211455, so you can't get 50 digits. – Ray Toal Jun 15 '19 at 07:53
  • Any work around? – Bussller Jun 15 '19 at 07:54
  • Do you need the integer values, or can you leave them as strings? There exist crates such as [num-bigint](https://github.com/rust-num/num-bigint) that can help you if you need to parse them. Disclaimer: I haven't tried it. – Ray Toal Jun 15 '19 at 07:54
  • I need integer value. Thanks, let me try `num-bigint`. – Bussller Jun 15 '19 at 07:57
  • I also found [this crate](https://rust-num.github.io/num/num/index.html) ... There is a parse example from strings on [this page](https://rust-num.github.io/num/num/struct.BigInt.html). – Ray Toal Jun 15 '19 at 08:00
  • 2
    @RayToal Perhaps you would like to leave that as answer? – Peter Hall Jun 15 '19 at 12:45
  • Yes good idea, thanks, just did. (I waited until I could actually find time to write working code.) – Ray Toal Jun 15 '19 at 15:23
  • 1
    One decimal digit corresponds to log_2(10) ~ 3.32 bits, so 50 decimal digits require about 166 bits. – starblue Jun 16 '19 at 06:22

1 Answers1

2

The largest u128 is 2**128-1 = 340282366920938463463374607431768211455, which is less than 50 digits, so you will have to use struct num::bigint::BigInt (from the num crate).

You can parse big integers via the FromStr trait. Here is an example of parsing two 50-digit numbers and (super bonus fun time) multiplying them:

extern crate num;

use num::BigInt;
use std::str::FromStr;
use std::ops::Mul;

fn main() {
    let x = BigInt::from_str("9879878782352398572398755757923351299981243778899").unwrap();
    let y = BigInt::from_str("3234235766473868388883432903721391827312463782828").unwrap();
    println!("{}", x.mul(y));
}
Ray Toal
  • 86,166
  • 18
  • 182
  • 232