我在 Rust 和 Go 中处理大整数时遇到了一个有趣的问题。具体来说,在处理负除数时,两种语言的除法运算结果有所不同。这是两种语言的代码:
生锈
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);
}
走吧
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())
}
输出
铁锈:
-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931548
去:
-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931549
如您所见,Rust 将结果舍入为零,而 Go 将结果舍入到负无穷大。谁能解释为什么存在这种差异以及是否有办法在这种除法运算中协调这两种语言的行为?
num_bigint
似乎默认使用不同的舍入策略:
use num_bigint::BigInt;
use num_integer::Integer;
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);
}