http://freepascal.ru/article/freepascal/20190506080000/#p3000
http://freepascal.ru/article/freepascal/20190411080000/
Неработающие примеры во второй статье -
для операций с длинными числами с помощью процедур - "В, так сказать, низкоуровневом (сишном) виде. Эти типы применяются в языке Си. При этом арифметические операции с числами можно проводить только с помощью специальных функций. Однако в FreePascal, в отличие от Си, для этих типов можно сомостоятельно переопределить арифметические операции" (с)
1) первый пример
Если всё это оформить в функцию -
То при аргументе функции mpf_set_default_prec например 128 возникает SIGSEGV
2) второй пример -
2.1) В вызове ф-ии mpf_get_str не хватает параметра, т.к. определена она вот так -
2.2) Insert всегда был процедурой, а не функцией
2.3) Даже если все это исправить -
получаем SIGFPE (для (2), см. ниже) и ничего для (1).
Было проверено для gmp.dll отсюда и отсюда -
1) https://cs.nyu.edu/exact/core/gmp/gmp-dynamic-vc-4.1.2.zip
2) https://sourceforge.net/projects/mingw/files/MinGW/Base/gmp/gmp-6.1.2/
PS переприсвоение
на всякий случай сделано оттого, что - "Однако в документации [3, с. 88, 89] написано, что когда мы работаем с классами или интерфейсами, то передавать в функции вычисляемые параметры с их участием ни в коем случае нельзя." - хуй его знает, может они там по ссылке передаются, лень даже смотреть, впрочем без него поведение аналогично.
"Так где же можно использовать эту библиотеку?" Где, где. "Подарить ему барана - он изящно пошутил" (с)
PSS "Чтобы быть уверенным в точности вычислений, входные данных лучше всего брать в текстовом виде или в виде целых чисел стандартных типов. В самом крайнем случае можно брать из типа "Double", но здесь уже гарантии в точности исходных данных не будет. На использование типов "Extended" или "Single" - полный запрет. " - автор в начале статьи и здесь - http://freepascal.ru/article/freepascal/20181215220000/ доказывает, что double лучше "подозрительного" extended.
https://yadi.sk/d/9mJ7A66ffmh82g
http://freepascal.ru/article/freepascal/20190411080000/
Неработающие примеры во второй статье -
для операций с длинными числами с помощью процедур - "В, так сказать, низкоуровневом (сишном) виде. Эти типы применяются в языке Си. При этом арифметические операции с числами можно проводить только с помощью специальных функций. Однако в FreePascal, в отличие от Си, для этих типов можно сомостоятельно переопределить арифметические операции" (с)
1) первый пример
Var
f: mpf_t;
n1, n2: longword;
pc: PChar;
Begin
mpf_set_default_prec(256);
mpf_init_set_str(f, '3.141592653589793238462643383279502884197169399375105820974944', 10);
n1 := Floor(mpf_get_prec(f) * LOG_10_2);
n2 := n1 - 2;
GetMem(pc, n1);
mp_sprintf(pc, PChar('%'+IntToStr(n1)+'.'+IntToStr(n2)+'Ff'), @f);
WriteLn(pc);
End;Если всё это оформить в функцию -
function mpftostr(x:mpf_t):string;
var n1,n2:longword;
pc:PChar;
s:string;
xxx:mpf_t;
begin
mpf_set_default_prec(256);
mpf_init(xxx);
mpf_set(xxx,x);
n1:=Floor(mpf_get_prec(xxx)*LOG_10_2);
n2:=n1-2;
GetMem(pc,n1);
mp_sprintf(pc,PChar('%'+IntToStr(n1)+'.'+IntToStr(n2)+'Ff'),@xxx);
s:=pc;
result:=s;
end;То при аргументе функции mpf_set_default_prec например 128 возникает SIGSEGV
2) второй пример -
Var
f: mpf_t;
n: longword;
pc: PChar;
s: AnsiString;
Begin
mpf_set_default_prec(256);
mpf_init_set_str(f, '3.141592653589793238462643383279502884197169399375105820974944', 10);
pc := mpf_get_str(NIL, n, 0, f);
s := pc;
s := Insert('.', s, n+1);
WriteLn(s);
End;2.1) В вызове ф-ии mpf_get_str не хватает параметра, т.к. определена она вот так -
{ Convert op to a string of digits in base base }
function mpf_get_str(str: pchar;
out exp: mp_exp_t;
base: longint;
ndigits: sizeuint;
var op: mpf_t): pchar; cdecl; external LIB name '__gmpf_get_str';2.2) Insert всегда был процедурой, а не функцией
2.3) Даже если все это исправить -
function mpftostr(x:mpf_t):string;
var
n:longint; pc:PChar;
s:AnsiString;
exp:mp_exp_t;
xxx:mpf_t;
begin
exp:=0;
mpf_init(xxx);
mpf_set(xxx,x);
pc:=mpf_get_str(nil,exp,n,0,xxx);
s:=pc;
insert('.',s,n+1);
result:=s;
end;получаем SIGFPE (для (2), см. ниже) и ничего для (1).
Было проверено для gmp.dll отсюда и отсюда -
1) https://cs.nyu.edu/exact/core/gmp/gmp-dynamic-vc-4.1.2.zip
2) https://sourceforge.net/projects/mingw/files/MinGW/Base/gmp/gmp-6.1.2/
PS переприсвоение
mpf_init(xxx); mpf_set(xxx,x);
на всякий случай сделано оттого, что - "Однако в документации [3, с. 88, 89] написано, что когда мы работаем с классами или интерфейсами, то передавать в функции вычисляемые параметры с их участием ни в коем случае нельзя." - хуй его знает, может они там по ссылке передаются, лень даже смотреть, впрочем без него поведение аналогично.
"Так где же можно использовать эту библиотеку?" Где, где. "Подарить ему барана - он изящно пошутил" (с)
PSS "Чтобы быть уверенным в точности вычислений, входные данных лучше всего брать в текстовом виде или в виде целых чисел стандартных типов. В самом крайнем случае можно брать из типа "Double", но здесь уже гарантии в точности исходных данных не будет. На использование типов "Extended" или "Single" - полный запрет. " - автор в начале статьи и здесь - http://freepascal.ru/article/freepascal/20181215220000/ доказывает, что double лучше "подозрительного" extended.
https://yadi.sk/d/9mJ7A66ffmh82g