Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Возведение числа в отрицательную дробную степень


Автор: alex_asker 30.11.2008, 15:51
     Добрые люди, подскажите, пожалуйста, как прописать возведение значения Эйлера "е" в отрицательную дробную степень, например    -0.0002.

Я делал следующим образом:

Код

double stepen(double x, double y)
{
double rez=1;
        for (double i=0;i<y;i++)
            rez*=x;
        if (y==0) rez=1;
return rez;
};


И далее:

Код

r=stepen(e,(-0.0002));

       Это возведение используется в довольно внушительной величины формуле. В данном случае выполняемое приложение зависает и считать формулу совсем не хочет. А вот если просто убрать знак "-" в степени, то все замечательно работает.
Помогите, пожалуйста, кто знает!

Автор: jonie 30.11.2008, 16:31
z^(-n) = 1/z^n , для всех z>0

Автор: jonie 30.11.2008, 17:19
http://forum.vingrad.ru/forum/topic-238272/kw-возведение-числа-отрицательную-дробную-степень.html
тема дубль

Автор: J0ker 30.11.2008, 21:21
Цитата(jonie @ 30.11.2008,  16:31)
z^(-n) = 1/z^n , для всех z>0

да при чем тут это
ты на формулу посмотри

Добавлено через 3 минуты и 34 секунды
Цитата(alex_asker @  30.11.2008,  15:51 Найти цитируемый пост)
Я делал следующим образом:

это не правильно
так можно делать только для положительных целых степеней

Автор: Sannis 30.11.2008, 21:58
Имхо, если человек не знает, что такое возведение числа в степень, то программировать ему ещё рано. И вопросы стоит сразу публиковать в Центр помощи, чтобы не утруждать модераторов переносом.


alex_asker, приглядитесь внимательно к вашему циклу. Если у вас y < 0, то уже в первом шаге цикла будет неверно, что i < y. А значит цикл не будет выполняться ни разу и функция вернёт 1. приведите весь код программы, тогда можно будет сказать, почему она виснет. А пока лучше вспомнить определение возведения в степень. Не знаю что хочет от вас преподаватель или чего хотите вы, но если нельзя пользоваться функцией pow(x,y) или вы не хотите её использовать, то можете попробовать записать эту функцию через экспонирование логарифмов.

Автор: SABROG 30.11.2008, 22:39
Вообще да, ноль больше отрицательного значения. Цикл не должен выполняться. Не понятно почему он у вас виснет.

Автор: alex_asker 1.12.2008, 17:35
        Sannis, я действительно новичок в программировании, но все, что здесь было предложено (pow или экспонирование логарифмов) я пробовал на своем коде, результат тот же. Я уверен, что какая-то самая малая ошибка мешает мне сделать правильный код, не могу ее найти, поэтому и обратился к вам.
       Вот мой код (я его не переделывал - это я про   i=0;i<y;):

Код

#include <vcl.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
double stepen(double x, double y);
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
double stepen(double x, double y)
{
double rez=1;
        for (double i=0;i<y;i++)
            rez*=x;
        if (y==0) rez=1;
return rez;
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int p;
double r1,r2,n,T0,Tk,a,b,T,r,Kg,c,step,e;
AnsiString s1,s2;
s1=Edit1->Text;
s2=Edit2->Text;
p=1;
n=60;
r1=StrToFloat(s1)/n;
r2=StrToFloat(s2)/n;
T0=500;
Tk=0.1;
T=0.1;
step=0.1;
e=2.718281828459045;
r=stepen(e,(-T/T0));
a=0.1;
b=0.1;

m: Kg=T0*((1-r)/(T+(Tk/n)+r*a*(r1+(Tk/n))+(1-r)*(1-b)*(r2+(Tk/n))+(1-r)*b*(T+(Tk/n)+r2)+(Tk/n)));
c=-1;
if (Kg>c)
{c=Kg;
 T=T+step;
 goto m;}
else
RichEdit1->Lines->Add(" " +IntToStr(p)+ ".  T0= " +        FloatToStr(T0)+ ";    Tk= " 

+FloatToStr(Tk)+ ";    a= " +FloatToStr(a)+ ";    b= " +FloatToStr(b));
RichEdit1->Lines->Add("                                            T= " +FloatToStr(T)+ ";      Kg= 

" +FloatToStr(Kg));
b=b/10;
p=p+1;
if (b<0.00001)
{a=a/10;
 b=0.1;}
else goto m;
if (a<0.00001)
{Tk=Tk+step;
 a=0.1;
 b=0.1;}
else goto m;
if (Tk>1)
{T0=T0+500;
 Tk=0.1;
 a=0.1;
 b=0.1;}
else goto m;
if (T0>10000)
{RichEdit1->Lines->Add("");
 RichEdit1->Lines->Add("                                                            Окончание 

расчетов");}
 else goto m;

}

 
       В общем, что не так пишите (если конечно есть соображения как исправить), буду премного благодарен!!! smile 

Автор: xvr 2.12.2008, 12:12
Ужас  smile Очень смахивает на код на Фортране - сплошные невразумительные формулы и переходы, разобраться как это работает - невозможно.
По поводу того, что оно виснет - у вас в формуле Kg=T0*((1-r)/(T+(Tk/n)+r*a*(r1+(Tk/n))+(1-r)*(1-b)*(r2+(Tk/n))+(1-r)*b*(T+(Tk/n)+r2)+(Tk/n))); есть такая часть 1-r на которую умножается T0. Если r равно 1 (как у вас и получается в вашем stepen), то Kg всегда равна 0. После чего у вас все зацикливается на первом же goto.
Вообще для таких вещей есть дебагер, по шагам не пробовали ваши спагетти проходить?

Автор: Lycifer 2.12.2008, 13:00
x в -2  это не 1/x во 2?(Может математику забыл, пожалуйста без сооказма)

Автор: jonie 2.12.2008, 13:16
Lycifer сообщение номер 2 прочти.

Автор: alex_asker 2.12.2008, 23:11
     Ну, во-первых, уважаемый xvr, Т0 умножается не на (1-r), а на все выражание целиком! Во-вторых, не надо округлять, на первом шаге r=0.998001998667, поэтому и нуля не будет! А вот правильно ли я возвел в отрицательную дробную степень - это вопрос! Да это же собственно название темы!!! Я не просто так обратил ваше внимание именно на это! 
          хотя ошибка всегда может оказаться где угодно.........

Автор: mes 2.12.2008, 23:22
Цитата(alex_asker @  2.12.2008,  23:11 Найти цитируемый пост)
А вот правильно ли я возвел в отрицательную дробную степень - это вопрос! Д

неправильно и о чем сказано уже не раз. Шаг в цикле for равен 1, т.е при дробном значение степени, в цикле исполнится шаг для i=0, и вернется (res=) 1*x


условие  if (y==0) rez=1; некоректно, так числа с плавающей запятой не сравнивают.
if (y<epsilon && y>-epsilon) .. где epsilon выбираете сами как (условно) бесконечно малое число. 

Автор: xvr 3.12.2008, 00:41
Цитата(alex_asker @ 2.12.2008,  23:11)
Ну, во-первых, уважаемый xvr, Т0 умножается не на (1-r), а на все выражание целиком! 

1-r входит во все части всего выражения, так что будет 0
Нет, вру, есть еще слагаемое Tk/n, так что будет T0*Tk/n, что является константой относительно T, которое меняется в первом цикле, так что разницы всеравно нет. Хотя там еще с меняется, в общем, ищи цикл, в котором все это зацикливается
Цитата

Во-вторых, не надо округлять, на первом шаге r=0.998001998667,
Я не округляю, при твоей реализации 'возведения в степень' r будет равно РОВНО 1, смотри тест своего цикла до полного просветления
Цитата

поэтому и нуля не будет! 
Будет, будет.
Цитата

А вот правильно ли я возвел в отрицательную дробную степень - это вопрос! 
Не вопрос - абсолютно неправильно, уже не раз говорили
Цитата

          хотя ошибка всегда может оказаться где угодно.........
В ДНК, ну не пишут так программы  smile Если вы в своем коде из 100 строк не можете найти ошибку, то что будет, когда этих строк станет, не приведи господь, 1000 ?  smile Общественность этого не переживет.

Автор: alex_asker 6.12.2008, 12:24
Всем Большое спасибо!!! Вопрос решен. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)