Using integer math to get a percentage in Rust

67 Views Asked by At

I have to calculate some percentages but I have to avoid using floats in Rust.

i have this data structure

let data = Vec<Identity, u64>

from this i can sum all the u64's to get a total which we'll call the total maturity

let total_maturity = data.iter().map(|(,b)| b).sum()

so now i have the total maturity across all of them. it should be fairly trivial to get the percentage of maturity for each neuron but how i do i express this.

With floats it would be simple and the resulting vec of percentages associated with a neuron would be like [0.3, 0.4, 0.1 ....]

I've heard of using integer math but im not sure how it really works.

1

There are 1 best solutions below

2
drewtato On BEST ANSWER

You can simply multiply all your numbers by 100 before dividing them.

let data: Vec<u64> = vec![3, 4, 1, 2];
let total_maturity: u64 = data.iter().sum();

let percentages: Vec<u64> = data
    .iter()
    .map(|b| b * 100 / total_maturity)
    .collect();

println!("{:?}", percentages);
// [30, 40, 10, 20]

If you need more precision, you can multiply by a larger number. Just remember that you will need to reintroduce the decimal point if you ever need to display them or perform math on them.

let data: Vec<u64> = vec![3, 4, 1, 9992];
let total_maturity: u64 = data.iter().sum();
let percentages: Vec<u64> = data
    .iter()
    .map(|b| b * 10_000 / total_maturity)
    .collect();

let formatted: Vec<String> = percentages
    .iter()
    .map(|&p| {
        let whole = p / 100;
        let frac = p % 100;
        format!("{whole}.{frac:.02}%")
        // or you could convert them to floats
        // format!("{}", p as f32 / 100.0)
    })
    .collect();

println!("{:?}", formatted);
// ["0.3%", "0.4%", "0.1%", "99.92%"]

If you want something more flexible, there is the rust_decimal crate.