Для вещественных есть ln. A log для вещественных никогда и не было. Посмотрел в музейной версии 0.3. Нету.
Да уж…((( Это я после работы с Экселем с ума начал сходить, там log(), как и в Бейсике. Перевел задачу с макросами на Паскаль, и логарифмы оставил. А в результате что ни пытаюсь компилировать - везде ошибки лезут с комплексом. Уже полез в справку .NET - а там тоже log в библиотеке Math. Вот и запаниковал. В Паскале ведь Log() для комплексных, LogN() для заданного основания…
Я думаю, что это - моя вина. Ln пришло из Delphi, реализуется оно как Math.Log. В Delphi не было Complex, Complex.Log было просто вынесено в стандартный Log. Так и получилось. Предложение - либо переименовать комплексный Log в Ln либо сделать Log и Ln синонимами для всех типов, которые их реализуют.
Синонимы - это было бы отличное решение. Универсальное и в то же время сахарок. Переименовать комплексный Log по-моему хуже, хоть и проще: все же не все пока что можно получить из Справки и приходится временами “нырять” на сайт Microsoft за разъяснениями по библиотекам .NET. А там LOG.
Сделали Log и Ln для real и Complex.
Заодно там в качестве бонуса
var (a,b) := (1,2);
посмотрите
При нажатии мышкой на внутреннею область квадрата происходит ошибка. Из-за чего она возникает:“Program8.pas(6) : Ошибка времени выполнения: Поток не выполняется; его нельзя приостановить.”?
[details=Summary]uses graphabc; var a: real;
procedure md(x, y, z: integer); begin if (x > 100) and (x < 200) and (y > 100) and (y < 200) then readln(a); end;
begin onmousedown := md; rectangle(100, 100, 200, 200); end.[/details]
Даже не пытайтесь внутри обработчика использовать readln. Этого делать нельзя. Компилятор проверить это не может
Там - это где, в новой версии? Это вместо (var a, var b):=(1,2)?
begin
var (x,y,z):=(3+5,1/3,-12); // вот оно, счастье!
Println(x,y,z);
Println(log(2)-ln(2.0),log(cplx(3,5.1)),ln(cplx(3,5.1)));
end.
А вот и несчастье, обнаруженное случайно из-за опечатки: компилятор “падает” из-за вызова неизвестной функции в Print:
begin
Print(f(1)) // вместо f можно писать любое неизвестное компилятору имя.
end.
Ох ты, ошибка, просуществовавшая 5 часов. Спасибо что заметили - это из-за недавнего достаточно большого рефакторинга. Перевыложили
Заметил случайно, когда менял log на ln: не удалил символ и получил вызов lng
Вот за это спасибо! Щас заценим… А то надоело уже var перед каждой переменной писать.
@admin Хорошая идея с кортежным вводом, но хотелось бы, чтобы и тут работал prompt:
var (x, y, z) := ReadlnInteger3('Введите X Y Z = ');
Кстати, как насчет добавить сразу и универсальный вариант ReadlnIntegerN()
? И поправьте, пож., лишние пробелы при автоформатировании: var ( x , y , z )
.
- у кортежей максимум 7 элементов(не оч удобно, но ибо нефиг кортежи для серьёзных проектов юзать)
- ReadlnIntegerN не будет работать потому что (integer,integer) и (integer,integer,integer) это разные типы и общи материский тип - System.Tuple, но и к нему преобразовать не получится
Program1.pas(5) : Невозможно явно преобразовать тип Tuple<integer,integer> к типу System.Tuple
лучше используйте массивы
function ReadlnInteger(N: cardinal): array of integer;
begin
Result := new integer[N];
if N <> 0 then
for i: cardinal := 0 to N - 1 do
Result[i] := ReadlnInteger;
end;
да и писать под каждое количество от 2 до 7 элементов(ReadlnInteger3) бесполезно, только займёт место в PABCSystem, нпмного проще так:
var (x,y,z) := (ReadlnInteger('Введите X Y Z = '),ReadlnInteger,ReadlnInteger)
Почему не написать просто var a:=ReadArrInteger(ReadInteger(‘n=’)); для создания и заполнения массива?
Ну, конечно, это куда проще и нагляднее, чем было бы так:
var (x, y, z) := ReadlnInteger3('Введите X Y Z = ')
Не торопитесь с выводами, коллега Вот, например, вполне себе рабочий код, хоть и не идеальный вариант, как хотелось бы:
function ReadlnIntegerN(n: integer): (integer, integer, integer, integer, integer, integer, integer);
begin
assert((n >= 0) and (n <= 7));
var a := new integer[7];
ReadArrInteger(n).CopyTo(a, 0);
Result := (a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
end;
function ReadlnIntegerN(const prompt: string; n: integer): (integer, integer, integer, integer, integer, integer, integer);
begin
write(Format(prompt, n));
Result := ReadlnIntegerN(n)
end;
begin
var (a, b) := ReadlnIntegerN('Введите {0} целых числа: ', 2);
println(a, b);
var (x, y, z) := ReadlnIntegerN('Введите X, Y, Z как целые: ', 3);
println(x, y, z);
var (mon, tue, wed, thu, fri, sat) := ReadlnIntegerN('Введите кол-во занятий по дням недели (Пн-Сб): ', 6);
println(mon, tue, wed, thu, fri, sat);
//ReadlnIntegerN(8); //::assert error
end.
Наверное, потому что не всем и не всегда нужен массив в итоге? В некоторых случаях удобнее и нагляднее работать с мнемоническими переменными, а не абстрактными индексами.
Я всё-таки ограничусь ReadInteger2 и ReadInteger3. Приглашение к вводу сделаю.
ReadlnIntegerN - какой-то совсем неправильный. На этапе выполнения невозможно задать тип (integer,integer) или (integer,integer,integer) в зависимости от n
А также ReadReal2 и ReadReal3? Очень полезно для ввода размеров двух- и трехмерных массивов, пар и троек координат точек, габаритных размеров, а также тройки параметров в циклах “от a до b с шагом h”.
Но все равно, очень жаль, что это не решит проблемы виртовского ограничения на шаг 1 (-1) в цикле, из-за которого приходится городить вот такие несуразицы для простейшей табуляции:
begin
var (a,h,n):=(ReadReal,ReadReal,ReadInteger);
foreach var x in n.Times.Select(i->a+i*h) do Writeln(x:7:3,x*x+0.2:9:3)
end.
Лучше так
function f(x: real) := x*x+0.2;
begin
var (a,b) := ReadReal2;
var N := ReadInteger;
foreach var x in Partition(a,b,N) do
Writeln(x:7:2,f(x):9:3)
end.
Partition как раз для этих целей
Partition - это не совсем то. Есть масса задач, когда надо протабулировать функцию от некоторого a c шагом h и до тех пор, пока очередная итерация аргумента не превысит b. А partition в общем случае изменит точки табуляции, потому что он не шаг держит, а разбивает весь интервал на равные отрезки. Например, попробуйте выполнить табуляцию для a от 0.3 с шагом 0.031 до 0.5, соблюдая именно шаг - в этой ситуации partition “ни о чем”.
В общем, это всего лишь аналог достаточно распространенного оператора цикла for x:=a to b step h (в нотации BASIC) или for x:=a step h until b еще в АЛГОЛ-60.
Хочется как-то “свернуть” цикл вида
var x:=a;
while x<=b do begin
...
x+=h
end;
Тот, на который нас обрёк Н.Вирт, кастрировав Алгол-60.
P.S. Не так давно переводил с Алгол-60 (там прекрасная библиотека исходников) процедуру обращения матрицы методом Гаусса-Жордана и когда встретился фрагмент вслух сказал очень непристойное слово, имея в виду как раз Н.Вирта…