Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 贝拉德';计算Pi的s算法_Algorithm_Fortran_Pi - Fatal编程技术网

Algorithm 贝拉德';计算Pi的s算法

Algorithm 贝拉德';计算Pi的s算法,algorithm,fortran,pi,Algorithm,Fortran,Pi,对于一个大学项目,我想用Fortran实现Bellard算法来计算pi的第n位。我在math.stackexchange上偶然发现了这个问题: 有了这个问题的答案,我成功地实现了代码,但我没有得到结果,我无法找出我做错了什么: PROGRAM pi IMPLICIT NONE INTEGER :: find_number_of_primes, number_primes, last_digit, digit, N, & eps, i, j, multiplicity, test RE

对于一个大学项目,我想用Fortran实现Bellard算法来计算pi的第n位。我在math.stackexchange上偶然发现了这个问题:

有了这个问题的答案,我成功地实现了代码,但我没有得到结果,我无法找出我做错了什么:

PROGRAM pi

IMPLICIT NONE

INTEGER :: find_number_of_primes, number_primes, last_digit, digit, N, &
eps, i, j, multiplicity, test
REAL :: log2, base, v_max, m, s, v, b, A, pi_sum
INTEGER, ALLOCATABLE :: primes(:)   

digit = 3
eps = 2
base = 10
N = INT((digit+eps)*log2(base))
pi_sum = 0

number_primes = find_number_of_primes(2*N)
ALLOCATE(primes(number_primes))
CALL get_primes(number_primes, primes)

DO i=1,SIZE(primes)
    v_max = INT(log(REAL(2*N))/log(REAL(primes(i))))
    m = primes(i)**v_max
    s = 0
    v = 0
    b = 1
    A = 1
    DO j = 1,(N)
        b = MOD((j/(primes(i)**multiplicity(digit, j)) * b), m)
        A = MOD((2*j-1)/(primes(i)**multiplicity(primes(i), (2*j-1)))*A, m)
        v = v - multiplicity(primes(i),j)+multiplicity(primes(i),(2*j-1))
        IF (v > 0) THEN
            s = MOD(s*j*b*(A**(-1))*a**(v_max-v), m)
        END IF
    END DO
    s = MOD(s * base**(digit-1), m)
    pi_sum = pi_sum + MOD((s/m), REAL(1))
END DO

PRINT*, pi_sum  

END PROGRAM
自定义函数查找素数、
获取素数
log2
多重性
按预期工作。第一个查找给定区间内的素数,第二个返回数组中的素数,第三个计算

log_2(x) = log(x)/log(2) 
最后一个通过检查第二个数除以第一个数的频率,直到除法的剩余部分不再为零,来计算多重性(我想这就是它的名字)。以下是源代码:

对数:

real function log2(x)
implicit none
real, intent(in) :: x

log2 = log(x) / log(2.)
end function
查找区间中素数的个数:

integer function find_number_of_primes(limit) result(number_primes)
implicit none
INTEGER, INTENT(IN) :: limit
INTEGER :: i, j
LOGICAL :: is_prime

number_primes = 0

DO i = 3,(limit-1)
    is_prime = .TRUE.
    DO j = 2, (i-1)
        IF (MODULO(i, j) == 0) THEN
            is_prime = .FALSE.
            EXIT
        END IF
    END DO
    IF (is_prime .EQV. .TRUE.) THEN
    number_primes = number_primes + 1
    END IF
END DO
end function find_number_of_primes
获取实际质数:

SUBROUTINE get_primes(number_primes, primes)
IMPLICIT NONE
INTEGER, INTENT(IN) :: number_primes
INTEGER :: i, found_primes, j
LOGICAL:: is_prime
INTEGER, INTENT(OUT) :: primes(number_primes)
i = 3
found_primes = 0
DO
is_prime = .TRUE.
DO j = 2, (i-1)
    IF (MODULO(i,j) == 0) THEN
        is_prime = .FALSE.
    END IF
END DO
IF (is_prime .EQV. .TRUE.) THEN
    found_primes = found_primes + 1
    primes(found_primes) = i
    IF (found_primes == number_primes) EXIT
END IF
i = i + 1
END DO


end SUBROUTINE get_primes

integer function multiplicity(a, b)
implicit none
INTEGER, INTENT(IN) :: a, b

multiplicity = 0
DO
    multiplicity = multiplicity + 1
    IF (MOD(b, (a**(multiplicity+1))) /= 0) THEN
        EXIT
    END IF
END DO
end function multiplicity
整个文件的Pastebin:

现在在我连接的问题中,在计算内环中的b时,分母中有a^{v(n,k)},但在问题的答案中,分母中的项是a^{v(a,k)}。此外,问题中的内部循环从1到N,而答案中的循环从1到2N

最后的结果是
NaN
,这里是
digit=2
eps=1
的一些控制台输出:

************ i =           1 ***************************
 v_max =   2.00000000
 m =   9.00000000
 ------------- j =           1 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   0.00000000
 ------------- j =           2 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   0.00000000
 ------------- j =           3 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   0.00000000
 ------------- j =           4 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   0.00000000
 ------------- j =           5 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   1.00000000
 v > 0 --> s =              NaN
 ------------- j =           6 -------------------------------
 b =   0.00000000
 A =   0.00000000
 v =   1.00000000
 v > 0 --> s =              NaN
一个完整的输出:


有人能帮我找出我做错了什么吗?

您的代码中有一个错误:

v = v - multiplicity(primes(i),j)+multiplicity(primes(i),(2*j-1))
应该是

v = v - multiplicity(primes(i),j)- multiplicity(primes(i),(2*j-1))
        s = MOD(s + j*b*(A**(-1))*a**(v_max-v), m)
而且

应该是

v = v - multiplicity(primes(i),j)- multiplicity(primes(i),(2*j-1))
        s = MOD(s + j*b*(A**(-1))*a**(v_max-v), m)

谢谢你的帮助!我的重数函数有一个错误,当它应该返回0时,它返回了1。