В порядке написания лабораторных работ за знакомую познакомилась с GNUтым Fortran'ом. Это - жесть. Кровельная. Луженая. Вот у кого стоит, если не сложно, проверьте на явные ошибки вывода (NaN, ******** и тому подобное):
Код
!! Компилировать с ключом -cpp, пожалуйста.
Program Uno !! Essential ?
!!{ -Preprocessing-
#define ArrowTip() Trim(Span(IChar('-'), 4))
#define DelimOut() Out(Trim(Span(IChar('='), 61)))
#define Equals(ValName, Value) ValName // " = " // FStr(Value)
#define Fn17(X) Testfn(Real(X), m, NotSoJ, k)
#define FStr(Value) Trim(StrF(Value))
#define IntStr(Value) Trim(Str(Value))
#define RequestVar(VarName, LB, HB) AskNumber("Укажите " // VarName // ": ", Real(LB), Real(HB))
#define Out(Text) Call TypeOut(Text // New_Line('A'))
!!}
!!{ -Structurization-
Type :: PointF
Real :: X, Y
End Type PointF
Parameter (JStart = 1) !! Исходное значение итератора.
Character*(*),Parameter :: PosPrefix = ", достигнуто на узле #"
!!}
!!{ -Variables & Array-
Real :: h=.0, hReal=.0, Accum=.0, Umax=.0, Umin=.0, Aver=.0, AverSqr=.0, PShare=.0, NShare=.0, Bias=.0, m=.0, NotSoJ= .0, k = .0
Integer :: A=0, B=0, N=0, J=0, Jmin=0, Jmax=0, Total=0
Type(PointF), Allocatable :: Graph(:)
!!}
!!{ Main code
!! -Initialization-
Out(ArrowTip()//"> Задание #1, вариант 17 <"//ArrowTip()// New_Line('A')) !! Заголовочная строка.
m = RequestVar("коэфф-т m", 1, 4) !! Ввод коэффициента m.
NotSoJ = RequestVar("коэфф-т j", 1, 4) !! Ввод коэффициента j.
k = RequestVar("коэфф-т k", 1, 4) !! Ввод коэффициента k.
A = 0; B = 1; N = RequestVar("количество исследуемых узлов на отрезке", 50, 1000) !! Первичные данные рассчетов.
h = 0.0 + (b - a) / (N - 1.0) !! Коэффициент шага.
Allocate (Graph(1:N)) !! Массив данных функции.
hReal = Real(b - a) / N !! Коэффициент для рассчета удельных долей и среднеквадратичного.
J = JStart; Jmax = J; Jmin = J; Total = N - JStart + 1 !! Итератор и производные.
Accum = Fn17(a); Umax = Accum; Umin = Accum !! Выходные данные.
!! -Data refactoring-
Do J = JStart, N
Graph(J)%X = A + (J - 1) * h !! Значение псевдоабсциссы.
Graph(J)%Y = Fn17(Graph(J)%X) !! Значение ординаты.
Aver = Aver + Graph(J)%Y !! Заранее считаем среднюю для оптимизации.
End Do; Aver = Aver / Total !! Досчитываем среднюю.
!! -Result calulation-
Do J = JStart, N; Accum = Graph(J)%Y !! Считываем значение функции на указанной точке.
If (Accum > Umax) Then; Umax = Accum; Jmax = J !! Проверяем максимальное значение.
Else If (Accum < Umin) Then; Umin = Accum; Jmin = J !! ...и минимальное, да.
End If; AverSqr = AverSqr + Accum * Accum !! Считаем сумму на средний квадрат
Bias = Bias + (Accum - Aver) ** 2 !! Считаем квадратичное отклонение от среднего значения.
If (Accum > 0) Then; PShare = PShare + hReal !! Считаем положительные значния.
Else If (Accum < 0) Then; NShare = NShare + hReal !! Считаем отрицательные значения.
End If; End Do; AverSqr = AverSqr / Total !! Досчитываем средний квадрат.
!! -Final Output-
DelimOut()
Out(Equals("Максимальное значение фи-и",Umax) // PosPrefix // IntStr(JMax))
Out(Equals("Минимальное значение фи-и", Umin) // PosPrefix // IntStr(JMin))
Out(Equals("Среднее значение функции", Aver))
Out(Equals("Средний квадрат ф-ии", AverSqr))
Out(Equals("Среднеквадратичное значение", Sqrt(AverSqr)))
Out(Equals("Доли положит. и отрицат. значений", PShare) // " / " // FStr(NShare))
Out(Equals("Среднеквадратичное отклонение от среднего", Sqrt(hReal * Bias)))
!!}
contains !! Почему здесь ? Да потому, что GNU - это лучшее, что было создано человечеством.
!!{ -functionality-
Real Function AskNumber(Request, LowBound, HiBound) !! Формализованный запрос числа.
Character*(*) Request; Real LowBound, HiBound !! Подготавливаем запрос.
Do; call TypeOut(Request); Read*,AskNumber !! Ожидаем ввод и после преоверяем результаты:
If (AskNumber < LowBound .OR. AskNumber > HiBound) Then !! Проверяем границы ввода и если вдруг - рапортуем ошибку.
Out("ERROR: предпол. значение между " // FStr(Lowbound) // " и " // FStr(HiBound) // " !") !! Error goes there.
Else; Return; End If; End Do !! ...Иначе - мирно заканчиваем и выходим.
End Function
Real Function TestFn(X, m, j, k) !! Исследуемая функция.
Real X, m, j, k; TestFN = ASin(X ** m) - (1 - X ** J) ** k
End Function TestFn
Subroutine TypeOut(Text) !! Абстрактизированный вывод текста.
Character*(*) Text; Write(*,"(A)", advance="no")Text
End Subroutine
Character(255) Function Span(Char, Length) !! Компиляция последовательности из указанных символов.
Integer Char, Length, I; Span = "";Do I=1, Length; Span(I:I+1) = AChar(Char); End Do
End Function
Character(15) Function StrF(Val) !! Фортран - это сила, друзья мои. Вы не знали ?
Real, intent(in) :: Val; StrF = ""; write (StrF,"(F10.4)") Val; StrF = adjustl(StrF)
End Function
Character(15) Function Str(Val) !! ...Сила, вот как есть - сила.
Integer, intent(in) :: Val; Str = ""; write (Str, *) Val; Str = adjustl(Str)
End Function
!!}
End Program Uno