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;
}
}



















