Untitled

mail@pastecode.io avatar
unknown
golang
3 years ago
1.2 kB
3
Indexable
Never
package main

import (
	"fmt"
	"math/big"
)

const (
	// numBits
	prec = uint(400000)
)

// [start, end)
func partialSum(start, end int, prevFact <-chan *big.Float, nextFact chan<- *big.Float) *big.Float {
	fSum := big.NewFloat(0)
	fSum.SetPrec(prec)
	fCurr := big.NewFloat(1)
	fCurr.SetPrec(prec)
	fNz := big.NewFloat(0)
	fNz.SetPrec(prec)
	one := big.NewFloat(1)

	for i := start; i < end; i++ {
		if i > 0 {
			fCurr.Mul(fCurr, big.NewFloat(float64(i)))
		}
		fNz.Quo(one, fCurr)

		fSum.Add(fSum, fNz)
	}

	fPrev := <-prevFact
	nextFact <- fCurr.Mul(fCurr, fPrev)

	fSum.Quo(fSum, fPrev)

	return fSum
}

func main() {

	n := 50000
	gran := n / 8

	sumChan := make(chan *big.Float)

	chans := make([]chan *big.Float, n)
	for i := 0; i < n/gran+1; i++ {
		chans[i] = make(chan *big.Float, 1)
	}
	chans[0] <- big.NewFloat(1)

	for i := 0; i < n/gran; i++ {
		go func(idx int) {
			start := idx * gran
			end := (idx + 1) * gran
			if n >= end {
				end = n
			}
			sumChan <- partialSum(start, end, chans[idx], chans[idx+1])
		}(i)
	}

	sum := big.NewFloat(0)
	sum.SetPrec(prec)
	for i := 0; i < n/gran; i++ {
		currSum := <-sumChan
		sum.Add(sum, currSum)
	}

	fmt.Printf("%v\n", sum)

}