缓慢的int.big计算,只在一个线程上

时间:2016-09-20 19:07:39

标签: go distributed-computing biginteger

我在测试中使用以下代码:

package main

import "fmt"
import "math/big"

func main() {
    input := "3333333333333333333.......tested with 100'000x3 , tested with 1'000'0000x3, tested with 10'000'000x3"
    bi := big.NewInt(0)
    if _, ok := bi.SetString(input, 10); ok {
        fmt.Printf("number = %v\n", bi)

        testval := new(big.Int)
        testval.SetString("3", 10)

        resultat, isGanzzahl := myDiv(bi, testval)
        fmt.Printf("isGanzzahl = %v, resultat = %v\n", isGanzzahl, resultat)
    } else {
        fmt.Printf("error parsing line %#v\n", input)
    }
}

func myDiv(minuend *big.Int, subtrahend *big.Int) (*big.Int, bool) {
    zerotest := big.NewInt(0)

    modulus := new(big.Int)
    modulus = modulus.Mod(minuend, subtrahend)

    if zerotest.Cmp(modulus) == 0 {
        res := big.NewInt(0)
        res.Quo(minuend, subtrahend)
        return res, true
    } else {
        return big.NewInt(0), false
    }
}
  • 100'000 x 3/3 ==甚至没有第二个季度
  • 1'000'000 x 3/3 == 9.45秒
  • 10'000'000 x 3/3 == 16.1分钟

我正在寻找一种让这种情况发生得更快的方法。如果我想在多线程中执行此操作,如何使用go-routines?是否有更快的方法进行更大数字的划分?

由于这仅用于测试,我计划使用100'000'000 -1,000'000'000位数的数字(这将是1GB的RAM使用)。但是10亿个数字不起作用,因为它需要数年才能完成。

如果是N / M会怎么样?其中N = 10亿位,M = 1000万位。这甚至可以在强大的家用电脑上使用吗?

如何将这项工作分发到多台小型计算机(例如AWS),我将如何看待?或者我需要做些什么?

1 个答案:

答案 0 :(得分:3)

如果您的号码长度超过100000位,则需要使用快速傅里叶变换进行乘法和除法:https://en.wikipedia.org/wiki/Multiplication_algorithm#Fourier_transform_methods。基本思想是将数字视为多项式,x为10的幂(如果你想要二元系统,则为2的幂)。使用快速傅里叶变换乘以多项式,然后传播进位以从多项式获得数字。即如果我们需要将19乘以19并且我们使用x = 10 1 ,我们将得到(1 * x + 9)*(1 * x + 9)= x 2 + 18 * x + 81.现在我们传播进位将多项式转换回数:x 2 + 18 * x + 81 = x 2 +(18 + 8) * x + 1 = x 2 + 26 * x + 1 =(1 + 2)* x 2 + 6 * x + 1 = 3 * x 2 + 6 * x + 1 = 361.诀窍是多项式可以使用快速傅里叶变换有效地相乘(O(N * log(N)时间)。乘积多项式的系数大于数字,所以你需要仔细选择x,以避免整数溢出或精度问题。

不太可能有golang库,因此您需要自己编写。以下是一些可用作起点的短FFT实现:

http://codeforces.com/contest/632/submission/16449753 http://codeforces.com/contest/632/submission/16445979 http://codeforces.com/contest/632/submission/16449040 http://codeforces.com/contest/632/submission/16448169

如果你决定使用FFT模数素数,请参阅这篇文章,以便选择模数:http://petr-mitrichev.blogspot.com/2015/04/this-week-in-competitive-programming.html