2015-03-26 3 views
1

Итак, я пытаюсь заставить этот C-код работать. Он компилирует, но производит неправильные выходы. Он должен перечислить все квадратные числа pefect между 1 и выбранным значением. Он делает что-то неправильно, и после многих проб и ошибок я думаю, что проблема связана с работой модуля ... как его усечение рано или что-то другое странное.C Код Для цикла с вложенными If; модулем и sqrt проблемой

// C Code 


/*This program will identify all square numbers between one and a chosen integer*/ 

#include <stdio.h> 
#include <math.h> 

int main(){ 

int i, upper, square_int; 
float square; 
printf("This program will identify all square numbers between one and a chosen integer"); 

printf("Please enter the upper limit integer:"); 
scanf("%d", &upper); 

upper = 13; /*scanf is the primary integer input method; this is here just to test it on codepad*/ 

for (i = 1; i<= upper; ++i) /*i want to run through all integers between 1 and the value of upper*/ 
{ 
    square = sqrt(i); /* calc square root for each value of i */ 
    square_int = square; /* change the root from float to int type*/ 

    if (i % (int)square_int == 0) /*check if i divided by root leaves no remainder*/ 
     printf("%d\n", i); /*print 'em*/ 
} 
printf("This completes the list of perfect squares between 1 and %d",upper); 

return 0; /*End program*/ 
} 

Выход на codepad является:

This program will identify all square numbers between one and a chosen integerPlease enter the upper limit integer:1 
2 
3 
4 
6 
8 
9 
12 
This completes the list of perfect squares between 1 and 13 

Который, конечно, неправильно. Я ожидаю получить 1, 2, 4 и 9 назад. Может ли кто-нибудь указать на мою фигню?

+0

«Я ожидаю, чтобы получить 1, 2, 4 и 9 обратно» -> 2 не является квадратом. –

+0

Квадратное преобразование square_int = испортит вашу концепцию алгоритма. Я думаю, вы знаете, что это изворотливо, потому что вы снова бросаете square_int как int снова. – Jon

+0

право, предназначено только для написания 1, 4 и 9. Спасибо. – Miloki

ответ

1

Вот более простой алгоритм

int i = 1; 
while (i*i < upper) 
{ 
    printf("%d\n", i*i); 
    ++i; 
} 

Другой метод, вычисляющий квадратный корень, преобразовать его в целое, и сравнить числа.

for (i = 1; i <= upper; ++i) 
{ 
    square = sqrt(i); 
    square_int = square; 
    if (square == (float)square_int) 
     printf("%d\n", i); 
} 
+0

Я не совсем понимаю, зачем использовать переменную float между ними. почему бы не сделать просто 'int sqroot = sqrt (i);' as ** sqrt (3) ** возвращает 'double', он будет преобразован в' int' для хранения в переменной 'sqroot'. –

+0

@luis, потому что в этом alorithm я сравниваю float (или double) с int. Мы могли бы также построить квадрат int и посмотреть, соответствует ли он i. Это был бы еще один алгоритм. – chmike

1

Неправильное использование модуля. В случае i = 6square_int станет 2 и таким образом i % (int)square_int равен 6 % 2, что приводит к 0.

Вы можете проверить вместо этого square_int * square_int == i.

+0

Спасибо всем. Проверял и внедрял код из chmike и не замечал дополнительных сообщений. Он работает сейчас, заставлял его выплевывать именно то, что я хотел. – Miloki

+0

BTW, я не знаю, где чертовски я шел с модулем ... сделал некоторые заметки с каракулями на утренней встрече и сразу начал работать над кодом. Это происходит, когда вы пропускаете фазу тестирования данных ... спасибо, что собрали меня с пола сегодня, ребята. – Miloki

1

Вы говорите, что вы ожидаете получить 1, 2, 4, 9, который означает, что вы не ожидаете получить 3.

Давайте посмотрим, с i == 3:

sqrt(3) == 1.732051

(int) 1.732051 == 1

3 % 1 == 0.

Это означает, что он фактически выполняет то, что ожидается, но не проверяет, является ли число квадратом.

Простой алгоритм для проверки, если число является квадратом, чтобы сделать:

sqrt_int = sqrt(i) + 0.5; 

if (square_int * square_int == i) 
    printf("%d\n", i);