Функция pow() в c выдает ошибку усечения (или округления)?
Привет всем: я использую функцию pow() для вычисления степеней простых чисел. Но некоторые результаты не отображаются, как ожидалось. Например, когда я передаю 200 в качестве входных данных, я хочу распечатать все простые числа и их полномочия, которые не превышают 200. Большинство чисел в порядке, но я замечаю, что некоторые отличаются от правильного числа на 1 (24 должно быть 25 120 должно быть 121,124 должно быть 125,168 должно быть 169). Я что-то здесь упустил? Моя платформа на win7 работает Coding::Blocks GNUGCC compiler. Любой совет? Спасибо большое...
60
2 3 4 5 7 8 9 11 13 16 17 19 23 24 27 29 31 32 37 41 43 47 49 53 59 61 64 67 71 73 79 81 83 89 97 101 103 107 109 113 120 124 127 128 131 137 139 149 151 157 163 167 168 173 179 181 191 193 197 199
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
bool is_primes[1000]= {true};
int primes[200]= {0};
int answer[1000]= {0};
void sieve_of_Eratosthenes (bool ary[],int);
void swap(int*,int*);
void quick_sort(int array[], int, int);
int main(int argc,char* argv[]) {
int n =0,i = 0,j = 0,cnt = 0,temp = 1;
memset(is_primes,true,sizeof(is_primes));
memset(primes,0,sizeof(primes));
memset(answer,0,sizeof(answer));
sieve_of_Eratosthenes(is_primes,1000);
//build primes table
for(i=0; i<1000; ++i) {
if(is_primes[i]) {
primes[j++] = i;
}
}
while(scanf("%d",&n)==1) {
i = 0,j = 0,cnt = 0,temp = 1;
//primes
for(j=0,cnt=0;primes[j]!=0; ++j) {
if(primes[j]<=n) {
answer[cnt] = primes[j];
++cnt;
}
}
//and power of primes
for(j=0; primes[j]!=0; ++j) {
for(temp=2;pow(primes[j],temp)<=n;) {
answer[cnt] = pow(primes[j],temp);
++temp;
++cnt;
}
}
//sort ascending
quick_sort(answer,0,cnt-1);
printf("%d\n",cnt);
for(j=0; j<cnt; ++j) {
printf("%d ",answer[j]);
}
printf("\n");
}
return 0;
}
void sieve_of_Eratosthenes (bool ary[],int n) {
int i = 0,j = 0;
is_primes[0] = is_primes[1] = false;
for(i=2; i*i<=n; ++i) {
if(is_primes[i]) {
for(j=i*i; j<=n; j+=i) {
is_primes[j] = false;
}
}
}
}
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// sort interval [left, right]
void quick_sort(int array[], int left, int right) {
if (left < right) {
// divide (partition)
int pivot = array[(left+right)/2];
int i = left - 1, j = right + 1;
while (i < j) {
do ++i;
while (array[i] < pivot);
do --j;
while (array[j] > pivot);
if (i < j) swap(&array[i], &array[j]);
}
// then conquer
quick_sort(array, left, i-1);
quick_sort(array, j+1, right);
// no need to combine sub-solutions
}
}
1 ответ
Если вы не знали о pow
Вы могли бы написать этот цикл по-другому:
for(temp = primes[j]*primes[j];
temp <= n;
temp *= primes[j]) {
answer[cnt++] = temp;
}
Это не только позволит избежать проблемы округления; это также будет немного быстрее. (Можно было бы придумать лучшее имя переменной, чем temp
.)