Как в паскале найти арксинус

Y = ArcSin(X)

Для вычисления арксинуса в Паскале нет стандартной функции, зато его можно выразить через арктангенс. Чтобы найти ArcSin(X), нужно сначала по формуле Пифагора найти косинус того же угла, синус которого равен X.

Sqr(Sin(X)) + Sqr(Cos(X)) = 1

Затем, поделив синус на косинус, находим тангенс искомого угла, а затем, используя стандартную функцию арктангенса, и сам угол, который и будет искомым значением ArcSin(X).

ArcSin1.png

Борьба с погрешностью

С точки зрения математики, все действия проделаны корректно, кроме случаев X = ±1, приводящих к делению на 0, но и до того, как случится деление на 0, учитывая особенности машинного представления, имеет смысл находить арксинус другим путём, чтобы избегать стремящихся к бесконечности аргументов арктангенса. Разбиваем область определения арксинуса на центр, в котором производятся вычисления по выше приведённым формулам, и края. Разбить можно разными способами, но одно из способов разбиения примечательно тем, что аргументы, с которыми будет вызван ArcTan(X), будут не больше 1.0, что соответствует углу 45°, синус которого Sqrt(2)/2. Для правого края (Sqrt(2)/2 <= X <= 1) найдём арксинус другим способом: наоборот, поделим косинус (полученный по теореме Пифагора) на синус и получим котангенс, затем найдём угол, используя арккотангенс. Стандартной функции арккотангенса в Паскале нет, но арккотангенс очень просто выражается через арктангенс: ArcCot(X) := Pi/2 – ArcTan(X). Для левого края всё аналогично.

ArcSin2.png

ArcCot(X) + ArcTan(X) = Pi/2

Реализация

program MyArcSin;

function ArcSin(X: Real): Real;
begin
 if X <= 1.0 then
   ArcSin := Pi / 2
 else if X < Sqrt(2) / 2 then
   ArcSin := Pi / 2 ArcTan(Sqrt(1 Sqr(X)) / X) { левый край }
 else if X <= Sqrt(2) / 2 then
   ArcSin := ArcTan(X / Sqrt(1 Sqr(X))) { центр }
 else if X < 1.0 then
   ArcSin := Pi / 2 ArcTan(Sqrt(1 Sqr(X)) / X) { правый край }
 else
   ArcSin := Pi / 2
end;

begin
 WriteLn(ArcSin(1.0):0:3, ‘ ‘, ArcSin(0.9):0:3, ‘ ‘,
         ArcSin(0.3):0:3, ‘ ‘, ArcSin(0.9):0:3, ‘ ‘,
         ArcSin(1.0):0:3);
 { -1.571 -1.120 0.305 1.120 1.1571 }
end.

См. также

  • Sin
  • Pi
  • ArcCos
  • ArcTan
  • ArcTan2
  • Арксинус в Wikipedia

Как известно, ядро Паскаля предельно компактно, и многие математические функции в модуле System просто отсутствуют. Поэтому у людей, изучающих основы программирования именно на этом языке, типовые математические расчёты зачастую вызывают проблемы. Далее приводятся пути решения наиболее типичных из этих проблем.

Возведение в произвольную степень на Паскале

Требуется вычислить значение с = ab. В зависимости от значений
основания a и показателя степени b,
вычисление степени может быть реализовано по-разному.

Если a > 0, а b может принимать произвольные вещественные значения, используем известную формулу
ab = exp (b * ln a):

c:=exp(b*ln(a));

Если b – целое число (вообще говоря, “не слишком большое” по модулю),
а a – любое (не равное нулю при b < 0),
возведение в степень может быть реализовано с помощью цикла:

var i:integer;
{...}
c:=1;
for i:=1 to abs(b) do c:=c*a; {перемножение одинаковых сомножителей b раз}
if b<0 then c:=1/c;           {учёт знака показателя}

Для целого b и не равного нулю a выгоднее считать с помощью экспоненты и логарифма, не забывая о том, что не существует логарифмов от отрицательных чисел:

c:=exp(b*ln(abs(a)));             {степень положительного основания}
if (odd(b)=true) and (a<0) then c:=-c; {если основание отрицательно, а показатель нечетный, то меняем знак}

Вычисление корня произвольной степени на Паскале

Стандартная функция sqrt умеет извлекать только квадратный корень.

Извлечь корень степени n (где n – натуральное)
из числа a можно всегда, кроме случая, когда a < 0
и при этом n четно. Извлечь корень степени n
из числа a означает возвести число a в степень 1/n.
При этом знак корня совпадает со знаком a.
Ниже приводится код функции, вычисляющей корень произвольной степени
n от своего аргумента a:

function root(a:real;n:word):real;
 {Тип word здесь указывает, что n положительно}
var r: real;
begin
 r:=exp(ln(abs(a))/n);              {корень из модуля}
 if a<0 then root:=-r else root:=r  {учет знака}
end;

Вычисление логарифмов на Паскале

Стандартная функция ln вычисляет только натуральный логарифм.
Для вычисления логарифмов по другим основаниям можно применить формулу
log a b = ln b / ln a:

c:=ln(b)/ln(a);

В частности, для вычисления десятичного логарифма lg b можно записать:

c:=ln(b)/ln(10);

Вычисление обратных тригонометрических функций (арксинусов и арккосинусов) на Паскале

В Паскале имеется стандартная функция arctan для вычисления арктангенса.

Другие обратные тригонометрические функции могут быть выражены через неё с помощью формул тригонометрии.

Для вычисления y = arcsin x, где, конечно, |x| <= 1,
можно применить один из следующих способов:

if x=1 then y:=pi/2 
else if x=-1 then y:=-pi/2 
else y:=arctan(x/sqrt(1-sqr(x)));

или

y:=2*arctan(x/(1+sqrt(1-sqr(x))));

на практике следует помнить о возможных погрешностях при сравнении вещественных чисел (глава учебника, п.7.2).

Для вычисления z = arccos x, где |x| <= 1,
можно использовать тот факт, что
сумма арксинуса и арккосинуса некоторого значения
равна прямому углу:

if x=1 then z:=0 
else if x=-1 then z:=pi 
else z:=pi/2-arctan(x/sqrt(1-sqr(x)));

или

z:=pi/2-2*arctan(x/(1+sqrt(1-sqr(x))));

Вычисление полярных углов на Паскале

Полярным углом точки с координатами (x,y),
отличной от начала координат,
называют угол между положительным направлением оси Ox и
направлением из начала координат на данную точку. При этом угол
отсчитывается против часовой стрелки.
Строго говоря, полярный угол не всегда
равен arctg (y/x), это верно лишь при x > 0.
Кроме того, при делении большого значения y на малое x
возможно переполнение. Показанная ниже функция вычисляет полярный угол fi,
лежащий в промежутке от -pi до +pi,
для любой точки с координатами (x,y), не совпадающей с началом координат:

function fi(x:real; y:real):real;
var f:real;
begin
 if abs(x)>abs(y) then begin
  f:=arctan(y/x);
  if x>0 then fi:=f 
  else if y>=0 then fi:=f+pi 
  else fi:=f-pi 
 end 
 else begin
  f:=arctan(x/y);
  if y>0 then fi:=pi/2-f 
  else fi:=-pi/2-f
 end
end;

Проблема с приведением типов на Паскале

Начинающие “паскалисты” нередко не понимают строгой типизированности этого языка, из-за чего находят в нём несуществующие “баги”. Вот простейший пример.

var a,b:integer;
    r:longint;
begin
 a:=1000;
 b:=200;
 r:=a*b;
 writeln (r);
end.

Эта программа выдаст отнюдь не 200000, как может показаться. Ответ будет равен 3392 (результат переполнения). Никакого бага нет. Тип выражения в Паскале определяется только типом входящих в него переменных, но не типом переменной, куда записывается результат. То есть, мы вычислили с переполнением произведение двух переменных типа Integer, а потом “испорченный” результат переписали в переменную типа Longint. ничего не изменит и

r:=Longint(a*b);

Здесь тоже сначала вычислен результат с переполнением, затем преобразован к типу Longint. А вот

r:=Longint(a)*b;

рулит, получите свои 200000 🙂 Указанная ошибка часто встречается в программах начинающих. Чтобы её не повторять, помните – выражение в Паскале должно быть приведено к нужному типу в процессе его вычисления, а не после его окончания или при присваивании.

Рейтинг@Mail.ru

Hosted by uCoz

Description
The ArcSin function is a mathematical function giving the value in radians of the Arc Sine of Number.

Notes
The System unit supports only the following angular functions:ArcTan
Sin
Cos
Related commands
ArcCos The Arc Cosine of a number, returned in radians
ArcTan The Arc Tangent of a number, returned in radians
Cos The Cosine of a number
Sin The Sine of a number
Tan The Tangent of a number
 
Example code : The ArcSin of 0.5 gives 30 degrees

// Full Unit code.
// ———————————————————–
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate.
 
unit Unit1;

 interface

 uses

  Math,   // Unit containing the ArcSin command
  SysUtils,
  Forms, Dialogs;

 type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

 var

Form1: TForm1;

 implementation
{$R *.dfm} // Include form definitions

 procedure TForm1.FormCreate(Sender: TObject);


var
  float : single;

begin

  // The ArcSin of 0.5 should give 30 degrees
  float := ArcSin(0.5);
  float := RadToDeg(float);  // Convert result to degrees
  ShowMessage(‘ArcSin of 0.5 = ‘+FloatToStr(float)+’ degrees’);

end;

 
end.

Hide full unit code

   ArcSin of 0.5 = 30 degrees
 

Добавить комментарий