在不使用更大容器的情况下乘以固定大小的分数

时间:2018-05-30 09:32:39

标签: math language-agnostic numerical-methods

我有三个大小为128位的无符号数:abc其中ab< = {{1我希望能够以尽可能高的精度计算c

如果(a * b) / cab是64位整数,我首先计算128位数字中的c,然后除以{{1}获得准确的结果。但是,我正在处理128位数字,并且我没有原生256位类型来执行乘法a * b

是否有办法在保持128位的世界时高精度地计算c

我的(失败)尝试:

  1. 计算a * b。这看起来有点不对称,正如预期的那样,我没有得到非常准确的结果。

  2. 正在计算:(a * b) / c = a / (c / b) = ((((a+b)/c)^2 - ((a-b)/c)^2)*c)/4这也给了我非常不准确的结果。

1 个答案:

答案 0 :(得分:2)

这个问题原本被标记为,所以我假设在我的回答中,即使标签现已被删除。

正如其他人在评论中所说的那样,除非你对这些数字大小的界限有所保证,否则你总是需要增加一个大小,否则你就冒了乘法溢出的风险。 Rust中没有比u128更大的原始类型。

通常的解决方案是切换到支持任意精度算术的结构,通常称为“bignums”或“bigints”。但是,与使用本机整数类型相比,它们的性能要差得多。

在Rust中,您可以使用num-bigint包:

extern crate num_bigint;

use num_bigint::BigUint;

fn main() {
    let a: u128 = 234234234234991231;
    let b: u128 = 989087987;
    let c: u128 = 123;

    let big_a: BigUint = a.into();
    let big_b: BigUint = b.into();
    let big_c: BigUint = c.into();

    let answer = big_a * big_b / big_c;

    println!("answer: {}",  answer);
    // answer: 1883563148178650094572699
}