Технический форум

Технический форум (http://www.tehnari.ru/)
-   Delphi, Kylix and Pascal (http://www.tehnari.ru/f43/)
-   -   Проверьте пожалуйста "калькулятор степеней" (http://www.tehnari.ru/f43/t58996/)

Бродяга 26.10.2011 20:21

Проверьте пожалуйста "калькулятор степеней"
 
Здравствуйте. Решил вспомнить всё, что знал о паскале (после олимпиады). И для пробы своих знаний сваял СИЕ:
Код:

var a, i, b, f:Integer;
begin
Writeln('Введите число');
Readln(b);
Writeln('Введите степень');
Readln(a);
f:=b;
if (b=0) and (a=1) then
  b:=1
else
if a=0 then
  b:=1
else
if a=2 then
  b:= sqr(b)
else
if a=3 then
  b:= sqr(b)*b;
if a>3 then
begin
  for i:=1 to a-1 do
  f:=f*b;
end;
Writeln(f);
end.

Идея проста: Число в степень..... Но степень выбирается рандомно.... Хотя может и нет: 5 прекрастно дощитывается до 13 степени, и дальше обвал... А 4 "едет" до 15 степени
Так вот, что здесь неверно? Ошибок нет, но и подсчёт неверен...

Daniellos 26.10.2011 20:25

Цитата:

Сообщение от Бродяга (Сообщение 607408)
var a, i, b, f:Integer;


Мне кажется здесь ошибка, результаты вычислений должны быть типа LongInt

Бродяга 26.10.2011 20:32

Код:

var a, i :Integer;
f, b:LongInt;

Думаю степень и счётчик можно не переносить....
Никаких изменений, всё те же промашки...

Бродяга 26.10.2011 20:39

Позвонил другу... Спросил у него... Предложил так:
Код:

var stepen, i :Integer;
b: Real;
begin
Writeln('Введите число');
Readln(b);
Writeln('Введите степень');
Readln(stepen);
if (b=0) and (stepen=1) then b:=1 else
if stepen=0 then b:=1 else
if stepen=2 then b:= sqr(b) else
if stepen=3 then b:= sqr(b)*b else
if stepen>3 then b:=Exp(stepen*Ln(Abs(b)));
Writeln(b);
end.

Более-менее работает :) Извините за беспокойство :)

Vladimir_S 26.10.2011 20:46

Цитата:

Сообщение от Бродяга (Сообщение 607408)
Так вот, что здесь неверно? Ошибок нет, но и подсчёт неверен...

Еще бы! Бедный Паскаль делает всё, что в его силах, чтобы самостоятельно (по собственной инициативе!) исправить допущенную Вами грубейшую ошибку, но и его возможности не безграничны. Давайте разбираться.
Вот вы задали все параметры в формате Integer, а о том забыли, что диапазон значений в этом формате всего-то от -32768 до +32767. Какие уж тут большие степени! Ладно. Видя такое дело, Паскаль сам(!!!) поменял формат величины f на LongInt. Тут повеселее: максимальное значение в этом формате +2147483647. Отсюда и ограничения. Ведь 4 в 15 степени это 1073741824, а 5 в 13 - 1220703125. Всё - упор.
Но, кстати, и помимо этого Вы ляпов в программу насажали. У Вас там какая-то дикая путаница параметров b и f - сам черт ногу сломит, так и не поняв, зачем это. Ну объявите вначале f:=b и уж больше b не трогайте - вычисляйте f, тем более, что именно f вы и выводите, как результат!
В качестве иллюстрации покажу написанную мною лет 15 назад функцию возведения числа в целую степень, которой я пользуюсь до сих пор:
Код:

function X2np(X:Extended; n:WORD):Extended;
Var i:WORD;
    Y:Extended;
BEGIN
  IF n=0 THEN X2np:=1 ELSE
  IF n=1 THEN X2np:=X ELSE
  BEGIN
    Y:=X;
    FOR i:=2 TO n DO Y:=Y*X;
    X2np:=Y;
  END;
END;


Бродяга 26.10.2011 20:55

Цитата:

Сообщение от Vladimir_S (Сообщение 607432)
Еще бы!...

Каюсь - я кривой :) Хотя бы оправдание есть - я уже долго не вспоминал Паскаль вообще :)
Функцию я, если Вы не против, возьму для пользования :)
Спасибо за помощь и разъяснение :)

Vladimir_S 27.10.2011 10:16

Цитата:

Сообщение от Бродяга (Сообщение 607438)
Функцию я, если Вы не против, возьму для пользования Спасибо за помощь и разъяснение

Да не за что.
Могу еще подарить несколько своих библиотечных функций:

Тангенс:
Код:

function Tan(X:Extended):Extended;
BEGIN
  Tan:=Sin(X)/Cos(X);
END;

Арксинус:
Код:

function ArcSin(X:Extended):Extended;
BEGIN
    IF ROUND(X*10000000)=10000000 THEN ArcSin:=Pi/2 ELSE
    IF ROUND(X*10000000)=-10000000 THEN ArcSin:=-Pi/2 ELSE
    ArcSin:=ArcTan(X/SQRT(1-X*X));
END;

Арккосинус:
Код:

function ArcCos(X:Extended):Extended;
BEGIN
    IF ROUND(X*10000000)=10000000 THEN ArcCos:=0 ELSE
    IF ROUND(X*10000000)=-10000000 THEN ArcCos:=Pi ELSE
    ArcCos:=(Pi/2)-ArcTan(X/SQRT(1-X*X));
END;

Гиперболические функции:
Код:

function Ch(X:Extended):Extended;
BEGIN
    Ch:=(Exp(X)+Exp(-X))/2;
END;

function Sh(X:Extended):Extended;
BEGIN
    Sh:=(Exp(X)-Exp(-X))/2;
END;

function Th(X:Extended):Extended;
BEGIN
    Th:=(Exp(X)-Exp(-X))/(Exp(X)+Exp(-X));
END;

Обратные гиперболические функции:
Код:

function ArCh(X:Extended):Extended;
BEGIN
    ArCh:=Ln(X+SQRT(X*X-1));
END;

function ArSh(X:Extended):Extended;
BEGIN
    ArSh:=Ln(X+SQRT(X*X+1));
END;

function ArTh(X:Extended):Extended;
BEGIN
    ArTh:=(1/2)*Ln((X+1)/(1-X));
END;

Факториал, двойной факториал:
Код:

function Nfact(n:LongInt):Extended;
VAR
  i:LongInt;
  fact:Extended;
BEGIN
  IF n=0 THEN fact:=1 ELSE
    BEGIN
      fact:=1;
      FOR i:=1 TO n DO
        fact:=fact*i;
    END;
  Nfact:=fact;
END;

function NfactDBL(n:LongInt):Extended;
VAR
  i:LongInt;
  fact:Extended;
BEGIN
  fact:=1;
  i:=n;
  REPEAT
    fact:=fact*i;
    DEC(i, 2);
  UNTIL i<=1;
  NfactDBL:=fact;
END;

Пользуйтесь на здоровье!

Бродяга 27.10.2011 18:59

Огромное спасибо :)


Часовой пояс GMT +4, время: 11:11.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.