Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Rust handle rounding in conversion of f64 to i64?

Tags:

rust

I've done a little testing of currency-handling in eg. Go and Dart. Basically, I think the best way to handle currencies is to convert doubles to integer in order that all calculations are made using integers, and I think that is the accepted way. However, different languages treat the conversion to integer differently. For example Go truncates doubles therefore, it is I believe necessary to add a rounding factor to compensate. Using Rust, I have found that doing a straight conversion (see below) appears to work, but I'm unsure how Rust actually handles the conversion using what appear to be two alternatives for handling the conversion.

How does Rust handle the rounding of f64 to i64 and what is the best method to use - "as i64" or "to_i64()"?

Based on timings that I did, the two methods here don't appear identical, however the results may be. ("as i64" appeared marginally faster).

Example (simplified to use only 2 decimal places - single currency):

fn fCcyDblToInt(dCcyAmt: f64) -> i64 {
 //  return (dCcyAmt * 100.0).to_i64(); 
 return (dCcyAmt * 100.0) as i64;
}

Edited 14 hours after initial post:

After doing some more testing, the following appears to me to be the way to handle conversion of float to integer using Rust:

fn fCcyDblToInt(dCcyAmt:f64) -> i64 {
  let dRound: f64 = if dCcyAmt > 0.0 { 0.5 } else if dCcyAmt < 0.0 {-0.5 } else {0.0};
 // return ((dCcyAmt * 100.0) +dRound).to_i64();
  return ((dCcyAmt * 100.0) +dRound) as i64;      
}

I'm fairly comfortable with that, because it's how I've handled it elsewhere, however I'll test some more.

like image 385
Brian Oh Avatar asked Oct 26 '13 13:10

Brian Oh


People also ask

How do you convert int to float in Rust?

To convert an integer to a float in Rust, use as f64 . This is a useful means to convert from various interchangeable types, you can use inline also.

What is f64 rust?

pub fn powi(self, n: i32) -> f64Raises a number to an integer power. Using this function is generally faster than using powf .


1 Answers

f64 has a round method 😊 Therefore you can do this:

fn currency_double_to_int(amount: f64) -> i64 {
    (amount * 100.0).round() as i64
}

That way you should get the standard rounding every time instead of the truncation. The rounding, I suspect, is the same as the libc rounding. See also this playpen for a little demonstration.

like image 57
ArtemGr Avatar answered Sep 23 '22 14:09

ArtemGr