Kotlin中的相同程序与Python中的程序产生不同的结果

时间:2018-06-11 02:42:43

标签: python kotlin

我根据测试由项目欧拉问题7概述给出的数字的素数的算法,用不同语言编写了两个函数。我没有发现这两个函数有任何区别,但它们给了我不同的结果。为什么呢?

Kotlin的第一个:

import kotlin.math.floor
import kotlin.math.sqrt

fun isPrime(n: Int): Boolean {
    if (n == 1) return false
    else if (n < 4) return true
    else if (n % 2 == 0) return false
    else if (n < 9) return true
    else if (n % 3 == 0) return false
    else {
        val r = floor(sqrt(n.toDouble())).toInt()
        var f = 5
        while (f <= r) {
            if (n % f == 0) return false
            else if (n % (f + 2) == 0) return false
            f += 6
        }
        return true
    }
}

fun main(args: Array<String>) {
    var sum = 5
    var n = 5
    while (n <= 2000000) {
        if (isPrime(n)) sum += n
        n += 2
        if (n <= 2000000 && isPrime(n)) sum += n
        n += 4
    }

    println(sum)
}

输出为1179908154

然后是Python中的那个:

import math

def isPrime(n):
    if n==1 :
        return False
    elif n<4 :
        return True
    elif n%2==0:
        return False
    elif n<9:
        return True
    elif n%3==0:
        return False
    else:
        r=math.floor(math.sqrt(n))
        f=5
        while(f<=r):
            if n%f==0:
                return False
            elif n%(f+2)==0:
                return False
            f+=6
    return True

sum =5
n =5
while n<=2000000:
    if isPrime(n):
        sum+=n
    n+=2
    if n<=2000000 and isPrime(n):
        sum+=n
    n+=4
print(sum)

输出为142913828922

这两个程序是一样的,但为什么他们给了我不同的答案? 和.... 第一次用英语问一个问题。对不起该语言。

2 个答案:

答案 0 :(得分:2)

这是整数限制跳跃的情况(溢出)。

python的输出是正确的。如果你看到实际值142913828922,那么它高于32比特的kotlin int,即2 ^ 37。我不知道kotlin代码,但您可以使用等效的long来实现此目的。

答案 1 :(得分:2)

看起来像Kotlin的溢出。 Kotlin仍然仅限于JVM,您可能会处理 Int来说太大的值。

如果您将Kotlin中的所有内容转换为Long,则会获得与Python中相同的数字。注意:Python会隐式地将大数字转换为类似long的类型,因此您不必自己执行此操作,但这是两种语言之间的显着差异。

fun isPrime(n: Long): Boolean {
    if (n == 1L) return false
    else if (n < 4) return true
    else if (n % 2 == 0L) return false
    else if (n < 9) return true
    else if (n % 3 == 0L) return false
    else {
        val r = floor(sqrt(n.toDouble())).toInt()
        val r1 = floor(sqrt(n.toDouble()))
        var f = 5
        while (f <= r) {
            if (n % f == 0L) return false
            else if (n % (f + 2L) == 0L) return false
            f += 6
        }
        return true
    }
}