Мировой стандарт - хранить углы в радианах а не градусах. Синусы в паскале .Net -овские, поэтому они тоже по этому стандарту работают. Как и всё остальное из System.Math..
было бы круто упомянуть об этом в документации, ибо я таких стандартов не знаю и вот так с ходу про радианы даже не подумал. И да, откройте любой школьный учебник, там все в упор в градусах.
На сколько я знаю - школьных учебников по PascalABC.Net нету. Все для более старых паскалей. А документация есть, и на msdn, и, вроде, даже в основной справке паскаля.
В моём учебнике по алгебре всё с радианами. Не знаю где вы градусы нашли. Только если вы из 9-ого/8-ого/7-ого и ниже класса такое может быть. Там ещё про радианы не рассказывают. Привыкайте к радианам.
Гхм. Вот интересно - а где граница между “надо делать справку для метода, он наш”, и “не надо делать справку, он же из .NET”? Люди, которые тут появляются, просят то справку на Windows Forms, то на System.Threading.Task, то на System.Math… Серьезно, я бы на месте разрабов справку, за пределами внесенных в “стандартный” паскаль модификаций вроде ReadlnInteger, выкинул целиком и полностью, оставив ссылку на русский (переведенный) MSDN.
Не стоит. Они не разрабатывают язык на основе крупной внешней платформы с огромной функциональностью и количеством написанного кода. Им справку написать (самую полную, какая есть) - неделя работы максимум.
и тут мы возвращаемся к вопросу – для кого PascalABC? На кого он позиционируется? На крупных софтверных разработчиков? Сомневаюсь что такие им пользуются. Или на школьников и студентотв? Много школьников полезут на МСДН, а если полезут поймут что там написано? Хотя если данная версия паскаля сделана чисто по приколу то тогда да вы правы и все нормально.
В программировании, как и математике, углы всегда задаются в радианной мере. В градусах - это только в школьной математике, да и то не всегда. В любом языке программирования мера для углов всегда радианная. Даже в Экселе, где готовые функции для ячеек. Поэтому всегда можно вывести “на чистую воду” кривую реализацию арифметики, если 4*arctan(1) не совпадает с принятым значением числа “пи”.
{Если X — вещественное число,
то синусом X в математическом анализе называется синус угла,
радианная* мера которого равна X.
Определение тригонометрических функций через ряды Тейлора:
∞
sin X = X - X^3/3! + x^5/5! - x^7/7! + X^9/9! . . . = Σ [(-1)ᶰ]*X^(2N+1)] / (2N + 1)!
n=0
или CORDIC.
xPI=355/113;
}
begin
var X := 0.2345;
var e := 0.00001;
var N := 1;
var S := X;
var H := X;
while (ABS(H) > e) do begin//repeat
H := H * (-1) * X ** 2 / (N + 1) / (N + 2);
S += H;
N += 2;
end;//until not (ABS(H) > e);
writeln(S);
var SS:=SIN(x);
writeln(SS);
writeln(SS-S:0:15);
SS:=355/113;
Writeln(SS:2:15);
Writeln(Pi);
Writeln(SS-Pi:0:15);
end.
Вопрос: автоматическое присваивание выбирает оптимальный тип или первый подходящий по вместимости? Как можно улучшить работу с дробными в данном случае?
Это называется operator implicit и работает не только на присвоение.
Всегда выбирается оптимальное преобразование. Если одинаково хороших вариантов несколько - компилятор даст ошибку.
Вы правы, но современные процессоры аппаратно обрабатывают данные с плавающей точкой, как 64-битные по стандарту IEEE- 754, обеспечивая точность в 15—17 десятичных цифр и масштабы в диапазоне 1e−308 … 1e+308, так что использование single связано с аппаратной эмуляцией и существенно замедляет программу.
// запускать по Shift+F9, отключив в настройках генерацию отладочной информации
begin
var lc := 1000000;
var glc := 10000;
var sw_sa := new System.Diagnostics.Stopwatch;
var sw_ss := new System.Diagnostics.Stopwatch;
var sw_sm := new System.Diagnostics.Stopwatch;
var sw_sd := new System.Diagnostics.Stopwatch;
var sw_da := new System.Diagnostics.Stopwatch;
var sw_ds := new System.Diagnostics.Stopwatch;
var sw_dm := new System.Diagnostics.Stopwatch;
var sw_dd := new System.Diagnostics.Stopwatch;
var s1,s2,s3: single;
var d1,d2,d3: real;
(d1, d2) := Random2;
(s1, s2) := (d1, d2);
for var i := 1 to glc do
begin
sw_sa.Start;
loop lc do s3 := s1+s2;
sw_sa.Stop;
sw_ss.Start;
loop lc do s3 := s1-s2;
sw_ss.Stop;
sw_sm.Start;
loop lc do s3 := s1*s2;
sw_sm.Stop;
sw_sd.Start;
loop lc do s3 := s1/s2;
sw_sd.Stop;
sw_da.Start;
loop lc do d3 := d1+d2;
sw_da.Stop;
sw_ds.Start;
loop lc do d3 := d1-d2;
sw_ds.Stop;
sw_dm.Start;
loop lc do d3 := d1*d2;
sw_dm.Stop;
sw_dd.Start;
loop lc do d3 := d1/d2;
sw_dd.Stop;
System.Console.Title := $'{i/glc:P} done';
end;
writeln('single:');
writeln($' + : {sw_sa.Elapsed}');
writeln($' - : {sw_ss.Elapsed}');
writeln($' * : {sw_sm.Elapsed}');
writeln($' / : {sw_sd.Elapsed}');
writeln;
writeln('real:');
writeln($' + : {sw_da.Elapsed}');
writeln($' - : {sw_ds.Elapsed}');
writeln($' * : {sw_dm.Elapsed}');
writeln($' / : {sw_dd.Elapsed}');
readln
end.
У меня 64-битная система и разницы между real и single нет:
А Вы смотрели, во что компилируется real и single на уровне процессора? Возможно, в .NET разница и отсутствует, но я точно знаю, что под DOS она была. И как раз ее объясняли аппаратной реализацией.