Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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
C++ c中埃拉托斯烯的筛分_C++_C_Algorithm_Math_Sieve Of Eratosthenes - Fatal编程技术网

C++ c中埃拉托斯烯的筛分

C++ c中埃拉托斯烯的筛分,c++,c,algorithm,math,sieve-of-eratosthenes,C++,C,Algorithm,Math,Sieve Of Eratosthenes,这是我在C语言中对埃拉托斯烯进行筛选的代码。 它给了我以下输出 二, 3. 5. 7. 11 13 17 19 23 25 31 35 37 41 43 47 我的输出也包括25和35,它们不是素数,也不包括29 谁能告诉我哪里错了 #include<stdio.h> #include<math.h> int main() { int i,a[50],b[50],j,n=0,s; for(i=0;i<50;i++) a[i] = 1;

这是我在C语言中对埃拉托斯烯进行筛选的代码。 它给了我以下输出

二, 3. 5. 7. 11 13 17 19 23 25 31 35 37 41 43 47

我的输出也包括25和35,它们不是素数,也不包括29

谁能告诉我哪里错了

#include<stdio.h>
#include<math.h>
int main()
{
    int i,a[50],b[50],j,n=0,s;
    for(i=0;i<50;i++)
        a[i] = 1;
    a[0]=a[1] = 0;

    for(i=2;i<50;i++)
        if(a[i])
            for(j=pow(i,2);j<50;j+=i)
                a[j] = 0;

    for(i=0;i<50;i++)
        if(a[i])
        {
            b[n] = i;
            n++;
        }

    for(j=0;j<n;j++)
        printf("%d\n",b[j]);
    return 0;
}
#包括
#包括
int main()
{
int i,a[50],b[50],j,n=0,s;

对于使用gcc版本4.4.7(Ubuntu/Linaro 4.4.7-2ubuntu1)编译的(i=0;i),您的代码返回正确的结果。问题可能与编译器和
pow()实现有关

可能您有一个简单的
pow
实现,它将
pow(x,y)
计算为
exp(y*log(x))
。这是浮点运算,它存在常见的浮点问题。这意味着
pow(x,y)
转换为整数的结果将被截断,因为双算术
log(x)*y
和将返回略小于整数x*y的双倍值的幂运算

将代码更改为

for( j = i * i; j < 50; j += i)
    a[j] = 0;
(j=i*i;j<50;j+=i)的

a[j]=0;
此外,我们只能迭代到sqrt(n),因为第二个循环只有在那时才会执行:

for( i = 2; i < sqrt(50); i++)
    if( a[i]) // if not marked
        /* mark starting from i*i because i*j for j<i
         * has been already marked when i was j */
        for( j = i * i; j < 50; j += i)
            a[j] = 0; 
for(i=2;i/*标记从i*i开始,因为i*j代表j我试图重现您的输出,但我不能

操作系统信息:

$uname-Linux 3.13.0-29-generic#53 Ubuntu SMP Wed Jun 4 21:00:20 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

编译器信息:

$gcc——gcc版本(Ubuntu 4.8.2-19ubuntu1)4.8.2

汇编:

$gcc-埃拉托斯坦筛余物。c-lm-o-埃拉托斯坦筛余物

发布:

美元/筛除埃拉托斯坦

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47


正如其他人所观察到的,错误出现在
pow
函数中。我无法用您显示的代码重现您的错误,但当我滚动自己的
ppow
函数时:

double ppow(double a, double x)
{
    return exp(log(a) * x);
}
我的列表与您的列表相匹配。我认为
pow
的标准一致性实现应该将整数指数视为一种特殊情况,可以采用负基数,因此您的
pow
似乎不一致


使用
i*i
而不是
pow(i,2)
。这应该更快,而且您也不必链接到数学库。

pow
函数使用处理器上的浮点单元时,可能会产生异常

当此函数执行期间发生此类异常时,它可能返回不正确的值

当调用
pow(i,2)
i
等于
5
时,系统上可能就是这种情况

作为支持这一猜想的间接证据,请注意,每个数(在[0-49]的指定范围内)都会出现在素数列表中,这些数是5的倍数,且素数大于5


下面是一段代码,用于检索可能因FP操作而发生的异常:

#include <fenv.h>
#include <stdio.h>

void print_fe_exceptions()
{
    printf("Exceptions raised:");
    if (fetestexcept(FE_DIVBYZERO)) printf(" FE_DIVBYZERO");
    if (fetestexcept(FE_INEXACT  )) printf(" FE_INEXACT  ");
    if (fetestexcept(FE_INVALID  )) printf(" FE_INVALID  ");
    if (fetestexcept(FE_OVERFLOW )) printf(" FE_OVERFLOW ");
    if (fetestexcept(FE_UNDERFLOW)) printf(" FE_UNDERFLOW");
    feclearexcept(FE_ALL_EXCEPT);
    printf("\n");
}

我无法重现该错误。可能您有不同的
pow()
实现。请尝试
I*I
。我也一样。请指定编译器版本和更多环境详细信息。编译时不使用优化标志(如果是gcc)请指定不相关的编译器,但我建议使用更多的描述性变量名,而不是作为注释的
a
b
。我的费率不允许我留下注释。
2*I
I
2
时已被标记为非素数。
3*I
4*I
的情况类似,等等。从
i*i
@bits\u international开始就足够了,但这仍然不是问题的答案。事实上,我们正在处理算法以外的其他问题。是的,代码块的pow实现是问题所在。感谢链接。我随时为您服务,我的好先生谢谢您,使用i*i代替pow(i,2)解决了我的问题,但我仍然无法理解为什么pow(I,2)给了我错误的答案。
pow
适用于浮点数。它们不精确,当它们是上面
ppow
实现中的计算结果时更是如此。对于
ppow(20,2)
我得到了399.9999999999,例如,转换为int后将变成399。您可能不需要舍入:
ppow(I,2)+0.5
,但我建议对整数幂使用简单乘法,特别是对于像平方这样的简单幂。ppow()和pow()之间的区别是什么.
pow
是您的数学库的幂函数。
ppow
是我上面使用的
pow
的实现。它不是符合标准的实现,但我假设您使用的数学库以这种方式实现了
pow
。我使用
ppow
表示编译器的
pow
可能是破碎的
FE_DIVBYZERO // Pole error occurred in an earlier floating-point operation
FE_INEXACT   // Inexact result: rounding was necessary to store the result of an earlier floating-point operation
FE_INVALID   // Domain error occurred in an earlier floating-point operation
FE_OVERFLOW  // The result of an earlier floating-point operation was too large to be representable
FE_UNDERFLOW // The result of an earlier floating-point operation was subnormal with a loss of precision