wunderwaffe: тупят другие (karliki)
[personal profile] wunderwaffe
http://freepascal.ru/article/freepascal/20190506080000/#p3000
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
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

wunderwaffe: рабочее (Default)
доктор Вандершпигель

April 2022

S M T W T F S
     12
34567 89
1011 12 1314 1516
17181920212223
24252627282930

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 18th, 2025 09:40 am
Powered by Dreamwidth Studios