Замечания и предложения

Как мне поступить, если я хочу позволить пользователю задать значение переменной, регулирующей количество знаков после запятой (здесь (System.Math.Round(x, digits, System.MidpointRounding.AwayFromZero)) — digits). Но, как вы знаете, значение > 15 выдаст ошибку. Т. е. я нашёл только, как обрезать значение переменной в write (x:0:5), но подойдёт ли этот способ при вычислениях внутри программы (без write)?

Вычисления процессор всегда проводит с максимально возможной для него точностью. Для типа real/double погрешность расчетов зависит исключительно от алгоритма. Ограничить точность указанным числом знаков (разрядностью) можно только программно, но ни один распространенный язык программирования этим “не страдает”, поскольку такие действия могут только существенно замедлить вычисления.

P.S. Я вот написал, а думать продолжаю: когда такое в принципе может понадобиться? И ответа не нахожу.

Вот округление до 2 знаков после точки

begin
  Round(2.3456,2).Print
end.

Так это одноразовое округление. Если нужно именно оно, то вопрос был задан некорректно. Я его понял, как желание зафиксировать разрядность в дробной части при выполнении операций. Такое я видел только в системах, где разрядность произвольная и на плавающей точке, например, в пакетах компьютерной математики типа Maple,

В чём отличие между System.Math.Round и x:0:5? Куда можно задавать подобные вопросы (не хочу засорять тему “Замечания и предложения”)? Нашёл баг сайта: в Google Chrome идёт пересечение горячих клавиш, поэтому при нажатии Ctrl + Shift + C вместо открытия инструментов разработчика вставляется шаблон неотформатированного текста (Текст "как есть" (без применения форматирования)).

1 лайк

Последняя запись работающая в Write - вообще устарела.
В наше время лучше так:

begin
  var x := 1.2345;
  Writeln(x.ToString('N2').PadLeft(5),  '|');
  Writeln(x.ToString('N2').PadRight(5), '|');
end.

Или, когда нужна краткость кода - внутри форматной строки:

begin
  var x := 1.2345;
  Writeln($'{x,5:N2}|');
  Writeln($'{x,-5:N2}|');
end.

По делу - Round возвращает число. В то время как :: во Write, .ToString и $'' - это всё операции над строками.

Кхм, в опере тоже. Ну, я б не назвал это багом. Если курсор не стоит на окне написания ответа, или использовать кнопку под ПКМ - работает нормально. Да и инструменты разработчика только для разработчиков сайта.

1 лайк

Read(x) работает, а, например, ReadInteger(x) — нет. Прошу добавить возможность читать так для всех возможных типов.

А вы прочитали как его использовать, перед тем как говорить что не работает?

Не понял Ваш вопрос. Если что, я имел ввиду, что Read можно записать как в виде x:=Read, так и Read(x), а ReadInteger можно записать только как x:=ReadInteger, поэтому я и прошу добавить возможность записать ReadInteger(x).

И какой, по вашему, тип у x?

Это получение адреса подпрограммы. И вообще не должно работать, потому что у Read много перегрузок, а переменной можно присвоить только адрес одной перегрузки. Ну и ещё потому что Read это волшебная подпрограмма, то есть компилятор может немного подменять код с ней.

Ну, ближе к теме - зачем вам ReadInteger(x)? Где такое может пригодиться?

Думал, будет удобнее. В принципе, незачем.

Возвращать и получать значение всегда удобнее результатом, а не var-параметром. Для этого и кортежи существуют.

Есть ли возможность выкидывать из .exe неиспользуемые методы?

То есть для такого кода:

type
  t1 = class
    static procedure p1 := exit;
    static procedure p2 := exit;
    static procedure p3 := exit;
  end;
  
begin
  t1.p2;
end.

Сделать так, чтоб в .exe попал метод t1.p2, но не t1.p1 и не t1.p3?

А то меня слегка напрягает размер .exe файлов, когда подключён модуль OpenGL.

После того как я добавил (исправил) возможность передавать nil в параметры типа массива - размер практически пустого .exe вырос до 6.32MB .

Не уверен, что сюда с вопросом… но… Сейчас копаюсь в коде PABC (свой плагин делаю) и пока не сообразил, как вытянуть индекс первой ячейки массива в режиме Debug? Глянул в лист значений локальных переменных … и там с нуля!!!

Дебаггер показывает, как хранится статический массив у нас в памяти. Он хранится как массив, индексируемый с нуля.

А какой плагин?

Пока добрался до списка локальный переменных: Debugger.ProcessEventArgs.Process.LocalVariables из события Process_DebuggeeStateChanged где Process из WorkbenchServiceFactory.DebuggerManager.DebuggedProcess

Элементы списка экземпляры класса Debugger.Value Примитивные типы вроде как через строку можно получить. Value с массивом получают так:

var value = e.Process.LocalVariables.ToArray();
var array = value[3].GetMembers()[0]

Ну и сами значения через

var elms = array.GetArrayElements().ToArray();

А вот ссылку на экземпляр “статического массива” пока не получил… Не понял пока… Нет экземпляра, нет данных о классе и members…

Есть еще мысль залезть в сам модуль и через рефлексию получить сам экземпляр класса, но надеялся через IDE данные получить.

А какой плагин?

Некий рекорд написания кода и процесса пошаговой отладки, чтобы затем можно было визуализировать в другой программе. С изменением текста и перемещением курсора быстро разобрался. А вот с отладкой немного запутался. Позицию текущей выполняемой строки получил. Имена и значения локальных переменных из этого списка легко получить. А вот с массивом завис. Собственно, мне только простые вещи нужны, для учебных видео, для школьников. В основном в объеме ЕГЭ. Поэтому перечисления, ООП и прочие сложности не нужны.

Сейчас неиспользуемые методы выкидываются из exe если они находятся в pcu. А поскольку у вас модули, то непонятно, почему размер файлов такой большой

Обязательно надо разобраться, почему у Вас 6 Мб выходит exe

Статический массив у нас называется NullBasedArray. Найдите все вхождения этого слова в проекте - может, это наведёт на мысль. И да - рефлексией!

13 сообщений перенесены в новую тему: OpenGL стандартный модуль