Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> "неточная" работа программы, неточное извлечение корней 
V
    Опции темы
kelario
Дата 19.9.2008, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



Доброе время суток.Хочу обратится к вам за помощью.Я только начинаю изучать программирование и всякие мелочи представляются мне крупными проблемами.
В общем есть программа:   Вводим 2 числа (к примеру 1 и 100).Программа должна показать те числа,которые находятся в интервале между 2 введенными ранее числами и кубические корни которых равны целому числу.(тоесть в данном примере это будет 1,8,27,64).Программу я в принципе написал,но преподаватель сказал,что таким образом лучше это не реализовывать,так как С++ теоретически может извлечь даже из подходящего числа корень таким образом,что число будет иметь дробную часть,или наоборот из "неправильного числа " вывести целое.В общем,как написать программу правильнее?и еще,можно ли это как то сделать без доп. библиотеки мат.х,тоесть без функции pow?
Помогите пожалуйста мудрые гуру!
Код


int main ()
{
char burts;
do
{

int skait1,skait2;
float kubs;


    cout << "vvedite pozaluista 2 chisla" << endl;
    cin >> skait1 >> skait2;

do

{

  kubs=pow(skait1,1/3.0); 
  if (kubs==floor(kubs)) cout << skait1 << endl;//здесь изначально вместо округления куба я пробовал if skait1==(kubs*kubs*kubs) но это наверное проблему не решает
  { if (skait1>skait2) skait1=skait1-1;else skait1=skait1+1;}
}
while(skait1!=skait2);
kubs=pow(skait1,1/3.0);
  if (kubs==floor(kubs)) cout << skait1 << endl;
             cout << "hotite vvesti drugie 4isla?(y/n)" << endl;
             cin >> burts;
}
while(burts=='y');

    system ("pause");
    return 0;
}

п.с: если можно,представляйте плз как можно более простые решения.Я только только начинаю учится и поэтому мне будет сложно разобраться в продвинутом коде.(был бы очень признателен за краткие пояснения в сложных местах).


Это сообщение отредактировал(а) kelario - 19.9.2008, 20:10
PM MAIL   Вверх
ama_kid
Дата 19.9.2008, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: нет
Всего: 95



Вполне возможно, что твой преподаватель имел ввиду следующее: представление дробных чисел в памяти имеет особенность - у них в 99% случаев есть дробный "хвост" не равный нулю. Например, число 2.0 может храниться в виде 2.00000004532 или 2.0000000000533 Поэтому сравнивать вещественные числа лучше на диапазоне. Т.е. ты пишешь, к примеру:
Код
kubs==floor(kubs)
а надо:
Код
fabs(kubs-floor(kubs))<eps
где eps - число типа float со значением 0.0001 (для примера)... Таким образом, ты отбрасываешь незначащие цифры дробной части до требуемой точности...

P.S. Кстати, выражение
Код
if (skait1>skait2) skait1=skait1-1;else skait1=skait1+1;
можно заменить на тернарный оператор:
Код
(skait1>skait2)?(skait1--):(skait1++);



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
J0ker
Дата 19.9.2008, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 9
Всего: 14



гораздо проще алгоритм:
берем куб корень из левой границы
округляем до меньшего
далее возводим все целые числа начиная с этого в куб (это число надо проверить персонально на равенство куба левой ганице) пока куб не будет больше правой границы

для отрицательных надо проверять на больше или равно левой границе и меньше или равно правой

Это сообщение отредактировал(а) J0ker - 19.9.2008, 20:56


--------------------
user posted image
PM MAIL   Вверх
IKM2007
Дата 19.9.2008, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



kelario, можно по-проще.
Код

#include <iostream>
#include <cmath>
using std::cout;
using std::cin;
using std::endl;
void main() 
{ 
double x1,x2;
cin>>x1>>x2;
x1=pow(x1,1/3.0);
x2=pow(x2,1/3.0);
int y1=(int)x1,y2=(int)x2,i;
if(y1<x1)
y1++;
for(i=y1;i<=y2;i++)
cout<<i*i*i<<endl;
}


Это сообщение отредактировал(а) IKM2007 - 19.9.2008, 20:55


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 20.9.2008, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



 Спасибо!Все более или менее понятно,идея ясна.Но! Почему то программа не работает в том случае,если первое число отрицательное а второе положительное.Вот если первое положительное,а второе отрицательное то все ок,а так почему то нет :( В чем может быть проблема?
Код

int main()
{
float a1,a2;
int d,f;
cin >>a1 >>a2;


 if (a1<a2) {
 a1=pow(a1,1/3.0);

 d=(int)a1;
do {
  f=d*d*d;
  if (f<a2) cout <<f << endl;
  d=d++ ;  } while(f<a2)   ; }
 if (a1>a2)  {
 a1=pow(a1,1/3.0);

 d=(int)a1;
do{
  f=d*d*d;
  if (f>a2) cout <<f <<endl;
  d=d-- ;} while(f>a2); }


system("pause");



  return 0;
}

(знаю что d  можно обьявить в начале и не делать мартышкин труд,но это так,проба пераsmile )

Это сообщение отредактировал(а) kelario - 20.9.2008, 14:45
PM MAIL   Вверх
IKM2007
Дата 20.9.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



Цитата

double pow(double x,double y);
Возводит x в степень y.Если x имеет отрицательное значение, а y не является целым числом, то происходит ошибка выхода за пределы области определения (EDOM).Если значение x равно нулю, а значение y равно нулю или меньше нуля, происходит ошибка выхода за пределы определения (EDOM).Возможно также появление ошибки выхода за пределы диапазона допустимых значении (ERANGE).


Цитата(kelario @  20.9.2008,  14:33 Найти цитируемый пост)
 Почему то программа не работает в том случае,если первое число отрицательное а второе положительное.Вот если первое положительное,а второе отрицательное то все ок,а так почему то нет :( В чем может быть проблема?

Потому-что в первом случае передаешь в pow отрицательное число, а во втором случае положительное.
Код

a1=pow(a1,1/3.0);//для первого числа используешь pow
-----------
f=d*d*d;
-----------
if (f>a2)//для второго числа не используешь pow


Это сообщение отредактировал(а) IKM2007 - 20.9.2008, 17:13


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 20.9.2008, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



АА,понятно ок.Спасибо еще раз.А как этого можно избежать? если первое число отрицательное то использовать пов 2-го а если второе отрицательное то пов первого ? а если оба отрицательны то умножить их на -1 и потом приписать минус к результату?(или может все проще?)
PM MAIL   Вверх
IKM2007
Дата 20.9.2008, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



kelario, просто вместо 
Код

 a1=pow(a1,1/3.0);

в строке 9 напиши 
Код

(a1>0)?a1=pow(a1,1/3.0):a1=-pow(-a1,1/3.0);



--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 20.9.2008, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



Ой,еще раз выручил smile3 раз спасибо. Остался только случай с 2 отрицательными.Но сперва хочу уточнить насчет 9 строчки.Двоеточие,это значит "в противном случае?" .я заменил на Иф-Элсе,всё работает так-же.И как понимать -pow ?
А с 2 отрицательными прога перескакивает порог 2 числа?тоесть показывает числа,выходящие за пределы отрезка между 2 введенными числами. smile  Как так ? 
Извиняюсь за назойливость. smile 

Это сообщение отредактировал(а) kelario - 20.9.2008, 20:52
PM MAIL   Вверх
IKM2007
Дата 20.9.2008, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



kelario, твой код отредактировать лень было, написал другой код.Работает для ВСЕХ случаев, НО иногда не показывает введенные 2 числа, если их кубические корни равны целому числу. Например если вводить -64 и 8, то выводит -27,-8,-1,0,1,8.Только что заметил... smile 
Код

#include <iostream>
#include <cmath>
using std::cout;
using std::cin;
using std::endl;
void main() 
{ 
double a1,a2,j;
int y1,y2,i;
cin>>a1>>a2;
(a1>0)?(a1=pow(a1,1/3.0)):(a1=-pow(-a1,1/3.0));
(a2>0)?(a2=pow(a2,1/3.0)):(a2=-pow(-a2,1/3.0));
if(a1>a2)
{
j=a1;
a1=a2;
a2=j;
}

a1<0?y1=(int)a1:y1=(int)a1+1;
a2<0?y2=(int)a2-1:y2=(int)a2;

if(y1<a1)
y1++;
for(i=y1;i<=y2;i++)
cout<<i*i*i<<endl;
}


Добавлено через 2 минуты и 37 секунд
Цитата(kelario @  20.9.2008,  20:42 Найти цитируемый пост)
Но сперва хочу уточнить насчет 9 строчки.Двоеточие,это значит "в противном случае?"

Да.

Цитата(kelario @  20.9.2008,  20:42 Найти цитируемый пост)
И как понимать -pow ?

Что как понимать?
Код

(a1>0)?a1=pow(a1,1/3.0):a1=-pow(-a1,1/3.0);

то же самое, что
Код

if(a1>0)
a1=pow(a1,1/3.0);
else
a1=-pow(-a1,1/3.0);



--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 21.9.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



Цитата

a1<0?y1=(int)a1:y1=(int)a1+1;
a2<0?y2=(int)a2-1:y2=(int)a2;


А это зачем?В смысле для чего в 2 случаях добавляется и отнимается единица?Потому что округляем и при неудачных обстоятельствах можем потерять одно число ?
PM MAIL   Вверх
IKM2007
Дата 21.9.2008, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



kelario, как видишь в строках 13-18
Код

 if(a1>a2)
{
j=a1;
a1=a2;
a2=j;
}

я присваиваю а1=min{a1,a2} и a2=max{a1,a2}.
Теперь, если а1=-32.87, то y1 должен быть -32, то есть y1=(int)a1, а если а1>0, то y1=33, то есть y1=(int)a1+1. Анологично в 
Код

a2<0?y2=(int)a2-1:y2=(int)a2;
 для a2.


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 21.9.2008, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



Не,я понимаю что происходит,просто зачем А при значение больше 0 увеличивать на 1 единицу ?почему у1 не может быть равен 32? Зачем ему быть 33 ? 
PM MAIL   Вверх
IKM2007
Дата 21.9.2008, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



kelario, если у тебя есть интервал (a1,a2)=(-32.87,32.87), то в этом интервале целые числа 
{-32,-31,-30,,,,,30,31,32}, следовательно y1=-2 и y2=32, а если дан интервал (32.87,64.87), то в этом интервале целые числа {33,34,35,,,,,62,63,64}, следовательно y1=33=(int)a1+1;.


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
kelario
Дата 21.9.2008, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 19.9.2008

Репутация: нет
Всего: нет



Блин,точно.Сорри за тупость :(


Это сообщение отредактировал(а) kelario - 21.9.2008, 14:37
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0698 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.