![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
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