c - C中的素数
问题描述
我遇到了这个有效的程序,用于打印给定数字的所有质因数:
# include <stdio.h>
# include <math.h>
// A function to print all prime factors of a given number n
void primeFactors(int n)
{
// Print the number of 2s that divide n
while (n%2 == 0)
{
printf("%d ", 2);
n = n/2;
}
// n must be odd at this point. So we can skip
// one element (Note i = i +2)
for (int i = 3; i <= sqrt(n); i = i+2)
{
// While i divides n, print i and divide n
while (n%i == 0)
{
printf("%d ", i);
n = n/i;
}
}
// This condition is to handle the case when n
// is a prime number greater than 2
if (n > 2&&n%2!=0)
printf ("%d ", n);
}
/* Driver program to test above function */
int main()
{
int n = 315;
primeFactors(n);
return 0;
}
输出是 3 3 5 7。这是完美的。
但是我对这个算法感到困惑。sqrt()
返回一个浮点值。如果在 中以整数格式显示printf
,则返回一些随机的大数。如果是这种情况,for 循环中的条件应该失败,因为sqrt()
作为整数返回一个随机数。有人可以解释一下吗?
另外,有人可以验证吗?该算法在 geeksforgeeks 网站上被错误地写为 if(n>2) 而不是我添加的 if(n>2&&n!=0)。有人请验证此算法。提前致谢。
解决方案
如果您尝试将 的值打印sqrt(n)
为整数:
printf("sqrt(n) = %d\n", sqrt(n)); // Don't do this
那么你有未定义的行为。sqrt()
返回类型的结果double
。编译器不知道(或不需要知道)参数的预期类型。传递正确类型的参数由您决定。上述调用printf
具有未定义的行为。
在其他上下文中,表达式的类型和预期类型是明确的,该语言需要隐式转换。特别是,在表达式i <= sqrt(n)
wherei
和n
are 的类型int
中,参数n
被转换int
为double
(参数类型sqrt()
), and the value of
i is also converted from
int to
double`。结果很可能是您所期望的。
顺便说一句,这个:
for (int i = 3; i <= sqrt(n); i = i+2) ...
很可能是低效的。该sqrt
函数相对昂贵,并且将在循环的每次迭代中调用。(sqrt(n)
在某些情况下,预计算是一个很好的解决方案,但这里的值n
可以在循环内改变。)
另一种选择是:
for (int i = 3; i*i <= n; i += 2) ...
这避免了浮点运算的复杂性(但考虑是否i*i
会溢出)。
(如果 C 在标准库中有一个整数平方根函数会很好,但它没有。)
推荐阅读
- azure - Power BI 中字符串变量的实时流式处理
- amazon-web-services - 具有动态策略的 AWS STS Tem 凭证
- sql - 使用多个 CASE 子句对最后一个语法排序空值
- botframework - 如何捕获从 FormFlow 对话框中抛出的异常?
- java - 回退函数中的 Hystrix executionException 和 failedExecutionException
- java - 了解 G1 垃圾收集器在特定 GC 阶段长时间停顿的原因
- junit - 在所有其他测试之前运行一次特定的 JUnit 测试
- actions-on-google - 如何在谷歌助手中访问用户位置
- c++ - 当我们在 C++ 中创建类的对象时,为成员函数分配的内存在哪里?
- vue.js - VueJS 验证在运行时更改语言环境