Поиск:

Ответ в темуСоздание новой темы Создание опроса
> не могу запустить программу! 
:(
    Опции темы
molodzo
Дата 8.3.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ребят! Есть программа:
Код

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

double factorial(double val)
{
    if (val > 1)
        return factorial(val - 1) * val;
    return 1;
}

int main(int argc, char *argv[])
{    
    double x = -1. / 4;    
    double k = 1;
    double left = 0, right = left;        
    double step = pow(1. / 10, 15);

    do
    {    
        left = factorial(4 * k + 1) / pow(static_cast<double>(factorial(2 * k)), 2) * pow(static_cast<double>(x), 2 * k);    
        right = 1. / 2 * pow(static_cast<double>(1 - 4 * x), -3. / 2) + pow(static_cast<double>(1 + 4 * x), -3. / 2);        
        x += step;
        
        if (x >= 1. / 4)
            x = -1. / 4, k += step;
    }
    while (abs(right - left) >= pow(static_cast<double>(10), -15));

    printf("%f\n", k);

    return 0;
}


Не могу вывести  рез-т на экран... пробовал добавить в код: Form1->Edit1->Text=k;   но он ее не распознает k! А если сделать K глобальной переменной, то выводит 1... как  быть? 

PM MAIL   Вверх
nworm
Дата 9.3.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Если это под консоль планируется, то надо в начало добавлять
Код

#include <conio.h>

Код

а в конец getch();


А если, формочки, то вместо main будет Button1Click... 
PM MAIL WWW   Вверх
molodzo
Дата 9.3.2009, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Код исправил:

Код

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

double factorial(double val)
{
    if (val > 1)
        return factorial(val - 1) * val;
    return 1;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    double x = -1. / 4;
    double k = 1;
    double left = 0, right = left;
    double step = pow(1. / 10, 15);

    do
    {
        left = factorial(4 * k + 1) / pow(static_cast<double>(factorial(2 * k)), 2) * pow(static_cast<double>(x), 2 * k);
        right = 1. / 2 * pow(static_cast<double>(1 - 4 * x), -3. / 2) + pow(static_cast<double>(1 + 4 * x), -3. / 2);
        x += step;

        if (x >= 1. / 4)
            x = -1. / 4, k += step;
    }
    while (abs(right - left) >= pow(static_cast<double>(10), -15));

    Form1->Edit1->Text=k;




Только теперь возьникает ошибка: invalid floating point operation.
По инету вроде полазил, однако не получается исправить! 
Help!
PM MAIL   Вверх
Michrutka
Дата 9.3.2009, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



а в какой строчке возникает ошибка?
к слову
Код

abs(right - left)

функция abs возвращает целое число
по скольку что left, что right у тебя double нужно испоьзовать функцию fabs()

Код

fabs(right - left)

PM MAIL   Вверх
molodzo
Дата 9.3.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ошибка в этой строчке:
while (abs(right - left) >= pow(static_cast<double>(10), -15));

Спасибо за fabs!)

PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  20:18 Найти цитируемый пост)
Ошибка в этой строчке:
while (abs(right - left) >= pow(static_cast<double>(10), -15));


Вовсе нет. У меня ошибка в этой строчке:
Код

right = 1. / 2 * pow(static_cast<double>(1 - 4 * x), -3. / 2) + pow(static_cast<double>(1 + 4 * x), -3. / 2);


right получает значение +INF.

Не вдаваясь в преобразования констант (вполне достаточно десятичной точки), я не лезу в математику - в виду того, что уже давно все забыл напрочь и я не помню что там с отрицательными дробными степенями. Просто констатитурю: ошибка тута.

PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вроде исправил эту строчку:
Код

right = 0.5 * pow( static_cast<double>(1/(1 - 4 * x)), 1.5) + pow( static_cast<double>(1/(1 + 4 * x)), 1.5);


Тока за ошибкой следует ошибка... теперь: floating point division by zero.
Видимо, это из-за слишком больших чисел... тока во что с ними делать?
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  21:55 Найти цитируемый пост)
 floating point division by zero

Цитата(molodzo @  9.3.2009,  21:55 Найти цитируемый пост)
1/(1 - 4 * x)

А что вы хотите еще тут получить? Вы же сами присваиваете х значение 1/4. Затем умножате на 4 - получаем 1...

Может лучше приведите формулы, по которым надо считать, посмотрим что к чему?


PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот сама задача:

k изменяется от 0 до бесконечности ((4k+1)! / [(2k)!]^2) * x^2k = =1/2*[(1-4x)^(-3/2) + (1+4x)^(-3/2)]

X принадлежит интервалу [-1/4 ; 1/4)

Найти мин. k, которое будет удовлетворять условию: 
abs(правая часть - левая часть) < 10^(-15)
PM MAIL   Вверх
Dmi3ev
Дата 9.3.2009, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Код

double factorial(double val)
{
    if (val > 1)
        return factorial(val - 1) * val;
    return 1;
}

интересное исполнение факториала + к этому почему тип double у функции факториала??? а почему передается дробное? факториал у дробного числа? Надо бы саму логику и математику продумать, а потом писать... 


--------------------

PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(Dmi3ev @  9.3.2009,  22:20 Найти цитируемый пост)
интересное исполнение факториала + к этому почему тип double у функции факториала??? а почему передается дробное? факториал у дробного числа? Надо бы саму логику и математику продумать, а потом писать..

Мне кажется, что методом перебора такие задачи вообще не решаются

Цитата(molodzo @  9.3.2009,  16:18 Найти цитируемый пост)

double step = pow(1. / 10, 15);
...
x += step;

В программе перебирается х, а в задаче сказано 
Цитата(molodzo @  9.3.2009,  22:10 Найти цитируемый пост)
Найти мин. k, которое будет удовлетворять условию: 
abs(правая часть - левая часть) < 10^(-15) 

Тогда, получается, что надо перебирать k? До бесконечности?

Задача решается другим методом, не перебором.



PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



В задаче вроде перебирается и x (в заданном интервале) и k (до завершения условия)! А как по-другому можно сделать?
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  22:34 Найти цитируемый пост)
В задаче вроде перебирается и x (в заданном интервале) и k (до завершения условия)! А как по-другому можно сделать? 


Просто перебор х я увидел, а перебор к нет - вот и фантазирую.

А с каким шагом надо перебирать х?


PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Т.к. надо сравнивать  с 10^(-15), то и к X я прибавляю 10^(-15)...

Это сообщение отредактировал(а) molodzo - 9.3.2009, 22:52
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  22:52 Найти цитируемый пост)
Т.к. надо сравнивать  с 10^(-15), то и к X я прибавляю 10^(-15)...

Интересная логика.

А в условиях задачи что прописано?
PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ничего. Это все условие... Но так наш препод пишет по памяти число "П" с огромным количеством знаков! А также говорит о погрешностях, возникающих из-за этих длинных чисел, то я думаю это логично...
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  23:05 Найти цитируемый пост)
Но так наш препод пишет по памяти число "П" с огромным количеством знаков! А также говорит о погрешностях, возникающих из-за этих длинных чисел, то я думаю это логично... 

Хорошо, я рад за препода и изменю свой вопрос:
В каком виде должен быть ответ?
При к таком-то и х- таком-то? либо в виде таблицы? Если последнее то ответ может превратиться в книжку.
PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



При k таком-то, x - таком-то. Ну и еще right и left.
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  23:24 Найти цитируемый пост)
Ну и еще right и left. 

А это зачем? Для контроля? Что х задан правильно?

Не в даваясь в математику - можно и перебором сделать - раз х задан, перебираем тоько к, думаю там не особо много будет. А у вас в программе перебирается х. Зачем его перебирать, если он задан фиксировано? Надо перебирать к. Надеюсь, что до бесконечности дело не дойдет

Добавлено через 57 секунд
Цитата(molodzo @  9.3.2009,  23:24 Найти цитируемый пост)
При k таком-то

 Минутку, если и к задан, то что искать-то? Или я туплю?
PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Как это k задан??? smile  Да и x надо тож перебирать в этом интервале для каждого k (вроде так)!

А может задача уже решена  smile  smile 

Это сообщение отредактировал(а) molodzo - 9.3.2009, 23:37
PM MAIL   Вверх
Anikmar
Дата 9.3.2009, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  23:36 Найти цитируемый пост)
Как это k задан???   Да и x надо тож перебирать в этом интервале для каждого k (вроде так)!


Цитата(molodzo @  9.3.2009,  23:24 Найти цитируемый пост)
При k таком-то, x - таком-то. Ну и еще right и left.


Опять вернулись к интервалу. Если ответ выдавать для х от [-0.25 до 0.25) с шагом 10^(-15) то получится таблица с триллионами значений. Вот я и интересуюсь, может все-таки у х шаг какой-то более адекватный должен быть?


Цитата(molodzo @  9.3.2009,  23:36 Найти цитируемый пост)
А может задача уже решена     

 smile 
PM MAIL ICQ   Вверх
molodzo
Дата 9.3.2009, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну хорошо... я завтра постараюсь уточнить!  smile 
Даже если брать с другим шагом, то как исправить ошибки?
PM MAIL   Вверх
Dmi3ev
Дата 9.3.2009, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



http://www.wikiznanie.ru/ru-wz/index.php/%...%81%D0%BB%D0%B0
вот факториал дробного числа... может у Вас в задаче к - целое?


--------------------

PM MAIL   Вверх
molodzo
Дата 10.3.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да... я это упустил! K, видимо, целое. Ну даже не в этом сейчас суть... Пусть пока K- целое, x- изменяется с любым шагом... даже при таких условиях появляются ошибки...
PM MAIL   Вверх
Anikmar
Дата 10.3.2009, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(molodzo @  9.3.2009,  22:10 Найти цитируемый пост)
k изменяется от 0 до бесконечности ((4k+1)! / [(2k)!]^2) * x^2k = =1/2*[(1-4x)^(-3/2) + (1+4x)^(-3/2)]

X принадлежит интервалу [-1/4 ; 1/4)


Берем начальный х:
-1/4

Берем указанную формулу (вернее часть)
(1+4x)^(-3/2)
1+4*(-1/4) = 0
0 в отрицательной степени вообще существует?
PM MAIL ICQ   Вверх
Dmi3ev
Дата 10.3.2009, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

0 в отрицательной степени вообще существует? 

будет давать бесконечность...


--------------------

PM MAIL   Вверх
Anikmar
Дата 10.3.2009, 00:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(Dmi3ev @  10.3.2009,  00:10 Найти цитируемый пост)
Цитата

0 в отрицательной степени вообще существует? 

будет давать бесконечность... 

Значит левая граница изначально бессмыслена?
PM MAIL ICQ   Вверх
molodzo
Дата 10.3.2009, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну вы меня окончательно запутали!  smile
Все... завтра попробую уточнить!

Спасибо.

Это сообщение отредактировал(а) molodzo - 10.3.2009, 00:29
PM MAIL   Вверх
Dmi3ev
Дата 10.3.2009, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

Все... завтра попробую уточнить! 

совет, у тебя много расчетов, поэтому постарайся помочь себе
1) вот твое выражение
((4k+1)! / [(2k)!]^2) * x^2k
х постоянно меняется с шагом 10^(-15) поэтому выражение x^2k считать надо каждый раз, а вот выражение (4k+1)! / [(2k)!]^2) относительно постоянное, те на его изменение влияет к, а к меняется только когда х пройдет от -0.25 до 0.25 с шагом  10^(-15), представь насколько будет быстрее твоя программа, если вот этот расчет (4k+1)! / [(2k)!]^2) ты будешь делать не каждый раз... а один раз для к=1, потом будешь пересчитывать только когда к будет 2... гораздо рациональнее просто ты порядка 2*10^15 раз лишних вот это выражение, а это немало...

Добавлено через 4 минуты и 50 секунд
Цитата

//...
while (...pow(static_cast<double>(10), -15))

а вот тут зачем считать каждый раз, если это значение переменной step, которую ты уже посчитал...

Добавлено через 8 минут и 32 секунды
Код

#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int fact(int val)
{
    if (val==0)
        return 1;
    else
        return (val*fact(val-1));
}
int _tmain()
{
    double x = -0.25;    
    int k = 1;
    double left = 0, right = left;        
    double step = pow(0.1, 5);
    cout<<"Step="<<step<<endl;
    do
    { 
        cout<<"x="<<x<<endl;
        left = (fact(4 * k + 1) / pow((float)fact(2 * k), 2)) * pow(x, 2 * k);    
        right = 0.5 * ( pow(1 - 4 * x, -1.5) + pow( (1 + 4 * x), -1.5) );        
        x += step;
        
        if (x >=0.25)
        {
            x = -0.25;
            k ++;
        }
    }
    while (fabs(right - left) >= step);
    cout<<k<<endl;
    system("pause");
    return 0;
}

шаг поменьше взял, вроде работает...
при этом еще учти то что говорит Anikmar про нули в отрицательной степени и посмотри, когда такое может получиться... 


--------------------

PM MAIL   Вверх
molodzo
Дата 10.3.2009, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Уточнил:
1) препод изменил условия: x изменяется от (-1/4; 1/4). Следует 0 в знаменателе не будет!
2) x можно ввести самому в пределах интервала

Dmi3ev, а чем ты компилируешь, а то у меня возникает ошибка(в C++ Builder 2007): Floating point overflow...

Это сообщение отредактировал(а) molodzo - 10.3.2009, 18:08
PM MAIL   Вверх
Dmi3ev
Дата 10.3.2009, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

Dmi3ev, а чем ты компилируешь, а то у меня возникает ошибка(в C++ Builder 2007): Floating point overflow...

ms vs 2008
в какой строке ошибка?
Цитата

Floating point overflow...

сделай так, чтобы нули не получались и все будет ок... скорее всего поэтому ошибка...

Это сообщение отредактировал(а) Dmi3ev - 10.3.2009, 18:40


--------------------

PM MAIL   Вверх
molodzo
Дата 10.3.2009, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пробую откомпилировать в Visual Studio 2005. Создал progect(по умолчанию), код вставил в name.h... А вот что нужно выбрать при: executable for debug session?
PM MAIL   Вверх
molodzo
Дата 10.3.2009, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ура! Удалось запустить! Только вот странность: при любом значении step, программа выдает одно и тоже значение (k = 17)... Кто-нибудь знает в чем ошибка?
PM MAIL   Вверх
molodzo
Дата 10.3.2009, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Исправил все значения на double... прога стала выдавать значения k = 43 при любом x!
Если вместо float поставить long double, то k уже будет равняться 50!
Также не получается нормально вывести left(пишет left = 1.#IND), а вот у right нормальное число!
Кто-нибудь знает почему такое происходит и как это исправить?

Код

#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std;

double fact(double val)
{
    if (val==0)
        return 1;
    else
        return (val*fact(val-1));
}
int _tmain()
{
   double x;    
   double k = 0;
   double left = 0;
   double right = 0;
   double step = pow(0.1, 15);
    do
    {
    cout << "Vvedite x: ";
    cin >> x;
    }
    while ((x>=0.25) || (x<=-0.25));
    do
    { 
        k++;
        left = (fact(4 * k + 1) / pow((long double)fact(2 * k), 2)) * pow(x, 2 * k);    
        right = 0.5 *  (pow((1/(1 - 4 * x)), 1.5)) + pow((1/(1 + 4 * x)), 1.5) ;        
    }
    while (fabs(right - left) >= step);
    cout << "k = " << k << endl;
    cout << "right = " << right << endl;
    cout << "left = " << left << endl;
    system("pause");
    return 0;
}

PM MAIL   Вверх
Dmi3ev
Дата 10.3.2009, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

Кто-нибудь знает в чем ошибка? 

короче, molodzo, программа у тебя правильно работает, осталось только предусмотреть те случае, когда могут быть 0 (в отрицалтельной степени) и еще немного въехать в то, что компьютер некоторые числа воспринимает одинаково, хотя они не равны...

Добавлено через 12 минут и 23 секунды
molodzo, я понял, где косяк, завтра выложу полное решение...


--------------------

PM MAIL   Вверх
Anikmar
Дата 11.3.2009, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



molodzo, А вы уверены, что уравнение сходится при любом х?

Мне лень было кодить и я загнал вашу формулу банально в excel, и напоролся на х (простите, не помню какой), который в принципе не сходился. Может быть добавить проверку, что при таком-то х, к просто не существует?
PM MAIL ICQ   Вверх
Dmi3ev
Дата 13.3.2009, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Проблема в том, что мы  считаем (ты говоришь, что к-бывает 43):
((2*43)!)^2=(86!)^2=(1*2*3*...*86)*(1*2*3*...*86)
(4*43+1)!=173! - это число точно не почитает, отсюда и ошибки... нужно пользоваться чем-то другим для хранения таких больших чисел... попробуй просто написать прогу:
Код

for(int i=0; i<1000; i++)
  cout<<fact(i)<<endl;

не пробовал! но на вскидку, дальше 100 точно не должен уйти...


--------------------

PM MAIL   Вверх
Anikmar
Дата 13.3.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Выражение надо упростить и обойтись без факториала. Использовать несколько другой метод.
Посмотрим на формулу повнимательнее и раскроем ее
При к=1
Дробь получится 5!/(2!*2!)
В развернутом виде (1*2*3*4*5)/(1*2*1*2)

При к=2
9!/(4!*4!)
В развернутом виде (1*2*3*4*5*6*7*8*9)/(1*2*3*4*1*2*3*4)

При к=3
13!/(6!*6!)
В развернутом виде (1*2*3*4*5*6*7*8*9*10*11*12*13)/(1*2*3*4*5*6*1*2*3*4*5*6)
Т.е. сразу видно какую часть можно сократить, а подсчет уже производить не втупую вычислением числителя и знаменателя, а последовательным умножением 7 * 8/2 * 9/3 * 10/4 * 11/5 * 12/6 * 13
Никакого переполнения у нас не будет.

И т.д. для любого к
PM MAIL ICQ   Вверх
Dmi3ev
Дата 13.3.2009, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Anikmar, сильно не вдумывался, но тут, конечно, надо что-то преобразовывать и считать не в лоб, потому как в лоб не выходит стандартными средствами... или нужно уже брать длинные числа и шпарить...


--------------------

PM MAIL   Вверх
Dmi3ev
Дата 14.3.2009, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



что вроде...
только я брал порядок 10^(-5), думаю, ты легко это поправишь...
Код

#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <iostream>
using namespace std;

double myright(double x)
{
    return( 0.5 * ( pow(1 - 4 * x, 1.5) + pow( (1 + 4 * x), 1.5) ) );
}

double myleft(double x, int k)
{
    int u1=2*k;//граница 1
    int u2=4*k;//граница 2
    double res=1;//результат
    for (int i=1, j=u1+1; i<=u1, j<=u2; i++, j++)
        res*=(float)j/i;
    res*=4*k+1;
    res*=pow(x, 2 * k);
    return res;
}

int _tmain()
{
    double xb=-0.25;//начало диапазона х
    double xe=0.25;//конец диапазона х, т.е. х из (-0,25; 0,25) 
    
    int k=1;//к, которое и нужно найти...
    double min=1;//текущий минимум разницы левой и правой части, для проверки
    double step = pow(0.1, 5);//шаг
    double eps=pow(0.1, 5);//погрешность
    for (;;)
    {
        double i=xb+step;//текущий х
        while (i<xe)
        {
            cout<<"x="<<i<<endl;
            double l=myleft(i, k);//левая часть
            cout<<"left="<<l<<endl;
            double r=myright(i);//правая часть
            cout<<"right="<<r<<endl;
            double res=fabs(l-r);//разница по модулю
            cout<<"res="<<res<<endl;
            if (res<min)
                min=res;
            cout<<"min="<<min<<endl;
            if ( res<=eps)
            {
                cout<<k<<endl;
                system("pause");
                return 0;
            }
            i+=step;

        }
        k++;
    }
    cout<<k<<endl;
    system("pause");
    return 0;
}


Это сообщение отредактировал(а) Dmi3ev - 14.3.2009, 12:03


--------------------

PM MAIL   Вверх
molodzo
Дата 15.3.2009, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм... странная программа... А она у тебя работает? Какие числа выдает?
У меня она считает как будто до бесконечности! А если вручную ввести i, то тоже непонятно когда остановится... Я поставил if k >1500 break; и прога у меня посчитала до этого значения за 3 сек!!! странно... 
P.S. Спасибо за участие!

PM MAIL   Вверх
Dmi3ev
Дата 15.3.2009, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



у меня она выдает последние такие:

Добавлено через 11 секунд
ща досчитает... smile

Добавлено через 3 минуты и 46 секунд
x=-0.21262
left=1.28753
right=1.28753
res=4.8107e-006
min=4.8107e-006
2
собственно 2  и есть ответ...

Добавлено через 9 минут и 50 секунд
а ты паузу сделай и посмотри min уменьшается?
в смысле в консоли (я нажимаю правую кнопу мыши или pause и смотрю)


--------------------

PM MAIL   Вверх
molodzo
Дата 15.3.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да! У меня тоже наконец посчитала  smile ! 
А вот почему, если я ввожу x сам(допустим x = 0.21), у меня прога выдает другие значения! И left при этом равняется 1.#IND ?
PM MAIL   Вверх
Dmi3ev
Дата 15.3.2009, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

А вот почему, если я ввожу x сам(допустим x = 0.21),

как ты ввод организуешь? я же не вижу, что ты там творишь?


--------------------

PM MAIL   Вверх
molodzo
Дата 15.3.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот так:

Код

int _tmain()
{
    double xb=-0.25;//начало диапазона х
    double xe=0.25;//конец диапазона х, т.е. х из (-0,25; 0,25) 
    
    int k=1;//к, которое и нужно найти...
    double min=1;//текущий минимум разницы левой и правой части, для проверки
    double eps=pow(0.1, 5);//погрешность

    double i;
    cout << "Vvedite X: ";  
    cin >> i;
    
    for (;;)
    {
            double l=myleft(i, k);//левая часть
            cout<<"left="<<l<<endl;
            double r=myright(i);//правая часть
            cout<<"right="<<r<<endl;
            double res=fabs(l-r);//разница по модулю
            cout<<"res="<<res<<endl;
            if (res<min)
                min=res;
            cout<<"min="<<min<<endl;
            if ( res<=eps)
            {
                cout<<k<<endl;
                system("pause");
                return 0;
            }
        k++;
    }
    cout<<k<<endl;
    system("pause");
    return 0;
}

PM MAIL   Вверх
Dmi3ev
Дата 16.3.2009, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

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



Цитата

А вот почему, если я ввожу x сам(допустим x = 0.21), у меня прога выдает другие значения!

представь себе, что при х=0,21 если и есть решение (а его нет), то оно очень далеко, в смысле при большом К.... так вот, поэтому К просто тупо увеличивается и достигает такого значения, что myleft=1.#IND...
чтобы что-ваще видеть, надо так хотя бы писать...
Код

int _tmain()

    int k=1;//к, которое и нужно найти...
    double eps=pow(0.1, 5);//погрешность
    double i;
    cout << "Vvedite X: ";  
    cin >> i;
    double r=myright(i);
    for (;;)
    {
            double l=myleft(i, k);//левая часть
            cout<<"k="<<k<<endl;
            cout<<"left="<<l<<endl;
            cout<<"right="<<r<<endl;
            double res=fabs(l-r);//разница по модулю
            cout<<"res="<<res<<endl;
 
            if ( res<=eps)
            {
                cout<<k<<endl;
                system("pause");
                return 0;
            }
        k++;
    }
    cout<<k<<endl;
    system("pause");
    return 0;
}

при этом коде К достигается 238 при этом myleft=2.31692e-35, после чего myleft сначала равно 0 некоторое время, а потом уходит в - бесконечность... что логично...
пора переставать задавать глупые вопросы и включать...


--------------------

PM MAIL   Вверх
molodzo
Дата 16.3.2009, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ладно, не буду больше приставать) smile  Хотя вопросов много!
Всем спасибо! Особенно, Anikmar и Dmi3ev! Удачи!

Это сообщение отредактировал(а) molodzo - 16.3.2009, 15:33
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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