long n = (long) Math.sqrt(num);
与long n = (long) Math.floor(Math.sqrt(num));
这两行代码的目的都是计算 num
的平方根,并将结果转换为 long
类型的整数。然而,它们在处理方式上有一些微小的差别。
long n = (long) Math.sqrt(num);
long n = (long) Math.floor(Math.sqrt(num));
区别分析
-
第一种写法:
(long) Math.sqrt(num);
Math.sqrt(num)
返回num
的平方根,结果是一个double
类型的浮点数。(long) Math.sqrt(num)
直接将这个double
类型的平方根结果转换为long
,这会截断小数部分,但不进行四舍五入。换句话说,它只保留整数部分,不管小数部分是多少。- 例如,如果
Math.sqrt(num)
的结果是5.9
,那么(long) Math.sqrt(num)
的结果就是5
。
-
第二种写法:
(long) Math.floor(Math.sqrt(num));
Math.sqrt(num)
同样计算num
的平方根,返回一个double
。Math.floor(Math.sqrt(num))
会将平方根结果向下取整,即使小数部分非常接近下一个整数,也会返回不大于该值的最大整数。- 然后
(long)
将这个向下取整的结果转换为long
类型。 - 在大多数情况下,与第一种写法的结果相同,但理论上更加明确,确保向下取整。
区别举例
假设 num = 36
:
Math.sqrt(36)
的结果是6.0
,两种写法都将n
设为6
。
假设 num = 35
:
Math.sqrt(35)
的结果是大约5.916
.(long) Math.sqrt(35)
会直接截断成5
。(long) Math.floor(Math.sqrt(35))
也会返回5
,因为Math.floor
将5.916
向下取整。
总结
虽然在大多数情况下两种写法的结果相同,但 Math.floor
确保了向下取整的意图更加明确,所以第二种写法通常更为严谨。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long num = sc.nextLong();
sc.close();
long n = (long) Math.floor(Math.sqrt(num));
String res = "-1 -1";
for (long i = 2; i < n; ++ i) {
if (num % i == 0) {
long j = num / i;
if (isPrime(i) && isPrime(j)) {
if (i < j) {
res = i + " " + j;
} else {
res = j + " " + i;
}
break;
}
}
}
System.out.println(res);
}
private static boolean isPrime(long n) {
// TODO
if (n < 2) {
return false;
}
long sqrtN = (long) Math.floor(Math.sqrt(n));
for (int i = 2; i < sqrtN; ++ i) {
if (n % i == 0) {
return false;
}
}
return true;
}
}