Reputation: 215
I've encountered an interesting issue while working with large integers in Rust and Go. Specifically, the results of division operations differ between the two languages when dealing with negative dividends. Here is the code for both languages:
Rust
use num_bigint::BigInt;
use std::str::FromStr;
fn main() {
let n = BigInt::from_str("-4068122527548036313624952687320999183219209139149389824425650628448701979991259532638609685663741905551578447595775644964695361846038949186131821248175179900695219937607954907860922507949244416").unwrap();
let d = BigInt::from_str(
"115792089237316195423570985008687907852837564279074904382605163141518161494337",
)
.unwrap();
let res = &n / &d;
println!("res:{}", result);
}
Go
package main
import "math/big"
func main() {
var n, d, res big.Int
n.SetString("-4068122527548036313624952687320999183219209139149389824425650628448701979991259532638609685663741905551578447595775644964695361846038949186131821248175179900695219937607954907860922507949244416", 10)
d.SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10)
res.Div(&n, &d)
println("res:", res.String())
}
Output
Rust: -35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931548
Go: -35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931549
As you can see, Rust rounds the result towards zero, while Go rounds towards negative infinity. Can anyone explain why this difference exists and whether there is a way to align the behavior of these two languages in such division operations?
Upvotes: -5
Views: 116
Reputation: 455
num_bigint
appears to be using a different rounding strategy per default:
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::ops::euclid::Euclid;
use std::str::FromStr;
fn main() {
let n = BigInt::from_str("-4068122527548036313624952687320999183219209139149389824425650628448701979991259532638609685663741905551578447595775644964695361846038949186131821248175179900695219937607954907860922507949244416").unwrap();
let d = BigInt::from_str(
"115792089237316195423570985008687907852837564279074904382605163141518161494337",
)
.unwrap();
let rust = BigInt::from_str("-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931548").unwrap();
let go = BigInt::from_str("-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931549").unwrap();
let res = &n / &d;
assert_eq!(res, rust);
let res = n.div_floor(&d);
assert_eq!(res, go);
let res = n.div_euclid(&d);
assert_eq!(res, go);
}
Upvotes: 3