annotate gcc/ada/libgnat/a-nbnbin__gmp.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 ------------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 -- GNAT RUN-TIME COMPONENTS --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 -- ADA.NUMERICS.BIG_NUMBERS.BIG_INTEGERS --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 -- B o d y --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 -- Copyright (C) 2019, Free Software Foundation, Inc. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 -- --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 ------------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 -- This is the GMP version of this package
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 with Ada.Unchecked_Conversion;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 with Ada.Unchecked_Deallocation;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 with Interfaces.C; use Interfaces.C;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 with Interfaces.C.Strings; use Interfaces.C.Strings;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 with Ada.Characters.Conversions; use Ada.Characters.Conversions;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 with Ada.Characters.Handling; use Ada.Characters.Handling;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 package body Ada.Numerics.Big_Numbers.Big_Integers is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 use System;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 pragma Linker_Options ("-lgmp");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 type mpz_t is record
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 mp_alloc : Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 mp_size : Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 mp_d : System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 end record;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 pragma Convention (C, mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 type mpz_t_ptr is access all mpz_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 function To_Mpz is new Ada.Unchecked_Conversion (System.Address, mpz_t_ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 function To_Address is new
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 Ada.Unchecked_Conversion (mpz_t_ptr, System.Address);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 function Get_Mpz (Arg : Optional_Big_Integer) return mpz_t_ptr is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 (To_Mpz (Arg.Value.C));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 -- Return the mpz_t value stored in Arg
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 procedure Set_Mpz (Arg : in out Optional_Big_Integer; Value : mpz_t_ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 with Inline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 -- Set the mpz_t value stored in Arg to Value
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 procedure Allocate (This : in out Optional_Big_Integer) with Inline;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 -- Allocate an Optional_Big_Integer, including the underlying mpz
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 procedure mpz_init_set (ROP : access mpz_t; OP : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 pragma Import (C, mpz_init_set, "__gmpz_init_set");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 procedure mpz_set (ROP : access mpz_t; OP : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 pragma Import (C, mpz_set, "__gmpz_set");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 function mpz_cmp (OP1, OP2 : access constant mpz_t) return Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 pragma Import (C, mpz_cmp, "__gmpz_cmp");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 function mpz_cmp_ui
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 (OP1 : access constant mpz_t; OP2 : unsigned_long) return Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 pragma Import (C, mpz_cmp_ui, "__gmpz_cmp_ui");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 procedure mpz_set_si (ROP : access mpz_t; OP : long);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 pragma Import (C, mpz_set_si, "__gmpz_set_si");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 procedure mpz_set_ui (ROP : access mpz_t; OP : unsigned_long);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 pragma Import (C, mpz_set_ui, "__gmpz_set_ui");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 function mpz_get_si (OP : access constant mpz_t) return long;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 pragma Import (C, mpz_get_si, "__gmpz_get_si");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 function mpz_get_ui (OP : access constant mpz_t) return unsigned_long;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 pragma Import (C, mpz_get_ui, "__gmpz_get_ui");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 procedure mpz_neg (ROP : access mpz_t; OP : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 pragma Import (C, mpz_neg, "__gmpz_neg");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 procedure mpz_sub (ROP : access mpz_t; OP1, OP2 : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 pragma Import (C, mpz_sub, "__gmpz_sub");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 -------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 -- Set_Mpz --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 -------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 procedure Set_Mpz (Arg : in out Optional_Big_Integer; Value : mpz_t_ptr) is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 Arg.Value.C := To_Address (Value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 end Set_Mpz;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 -- Is_Valid --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 function Is_Valid (Arg : Optional_Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 (Arg.Value.C /= System.Null_Address);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 --------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 -- Invalid_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 --------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 function Invalid_Big_Integer return Optional_Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 (Value => (Ada.Finalization.Controlled with C => System.Null_Address));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 -- "=" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 function "=" (L, R : Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 return mpz_cmp (Get_Mpz (L), Get_Mpz (R)) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 end "=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 -- "<" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 function "<" (L, R : Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 return mpz_cmp (Get_Mpz (L), Get_Mpz (R)) < 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 end "<";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 -- "<=" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 function "<=" (L, R : Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 return mpz_cmp (Get_Mpz (L), Get_Mpz (R)) <= 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 end "<=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 -- ">" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 function ">" (L, R : Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 return mpz_cmp (Get_Mpz (L), Get_Mpz (R)) > 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 end ">";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 -- ">=" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 function ">=" (L, R : Big_Integer) return Boolean is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 return mpz_cmp (Get_Mpz (L), Get_Mpz (R)) >= 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 end ">=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 -- To_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 function To_Big_Integer (Arg : Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 mpz_set_si (Get_Mpz (Result), long (Arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 end To_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 ----------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 -- To_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 ----------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 function To_Integer (Arg : Big_Integer) return Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 return Integer (mpz_get_si (Get_Mpz (Arg)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 end To_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 ------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 -- Signed_Conversions --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 ------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 package body Signed_Conversions is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 -- To_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 function To_Big_Integer (Arg : Int) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 mpz_set_si (Get_Mpz (Result), long (Arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 end To_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 -- From_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 function From_Big_Integer (Arg : Big_Integer) return Int is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 return Int (mpz_get_si (Get_Mpz (Arg)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 end From_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 end Signed_Conversions;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 --------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 -- Unsigned_Conversions --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 --------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 package body Unsigned_Conversions is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 -- To_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 function To_Big_Integer (Arg : Int) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 mpz_set_ui (Get_Mpz (Result), unsigned_long (Arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 end To_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 -- From_Big_Integer --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 function From_Big_Integer (Arg : Big_Integer) return Int is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 return Int (mpz_get_ui (Get_Mpz (Arg)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 end From_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 end Unsigned_Conversions;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 ---------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 -- To_String --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 ---------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 function To_String
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 (Arg : Big_Integer; Width : Field := 0; Base : Number_Base := 10)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 return String
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 function mpz_get_str
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 (STR : System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 BASE : Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 OP : access constant mpz_t) return chars_ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 pragma Import (C, mpz_get_str, "__gmpz_get_str");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 function mpz_sizeinbase
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 (this : access constant mpz_t; base : Integer) return size_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 pragma Import (C, mpz_sizeinbase, "__gmpz_sizeinbase");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 function Add_Base (S : String) return String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 -- Add base information if Base /= 10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 function Leading_Padding
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 (Str : String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 Min_Length : Field;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 Char : Character := ' ') return String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 -- Return padding of Char concatenated with Str so that the resulting
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 -- string is at least Min_Length long.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 function Image (N : Natural) return String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 -- Return image of N, with no leading space.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 -- Add_Base --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 function Add_Base (S : String) return String is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 if Base = 10 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 return S;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 return Image (Base) & "#" & To_Upper (S) & "#";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 end Add_Base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 -- Image --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 function Image (N : Natural) return String is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 S : constant String := Natural'Image (N);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 return S (2 .. S'Last);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 end Image;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 ---------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 -- Leading_Padding --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 ---------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 function Leading_Padding
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 (Str : String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 Min_Length : Field;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 Char : Character := ' ') return String is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 return (1 .. Integer'Max (Integer (Min_Length) - Str'Length, 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 => Char) & Str;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 end Leading_Padding;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 Number_Digits : constant Integer :=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 Integer (mpz_sizeinbase (Get_Mpz (Arg), Integer (abs Base)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 Buffer : aliased String (1 .. Number_Digits + 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 -- The correct number to allocate is 2 more than Number_Digits in order
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 -- to handle a possible minus sign and the null-terminator.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 Result : constant chars_ptr :=
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 mpz_get_str (Buffer'Address, Integer (Base), Get_Mpz (Arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 S : constant String := Value (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 if S (1) = '-' then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 return Leading_Padding ("-" & Add_Base (S (2 .. S'Last)), Width);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 return Leading_Padding (" " & Add_Base (S), Width);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 end To_String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 -----------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 -- From_String --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 -----------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 function From_String (Arg : String) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 function mpz_set_str
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 (this : access mpz_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 str : System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 base : Integer := 10) return Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 pragma Import (C, mpz_set_str, "__gmpz_set_str");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 First : Natural;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 Last : Natural;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 Base : Natural;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 if Arg (Arg'Last) /= '#' then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 -- Base 10 number
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 First := Arg'First;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 Last := Arg'Last;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 Base := 10;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 -- Compute the xx base in a xx#yyyyy# number
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 if Arg'Length < 4 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 First := 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 Last := Arg'Last - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 for J in Arg'First + 1 .. Last loop
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 if Arg (J) = '#' then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 First := J;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 exit;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 end loop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 if First = 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 Base := Natural'Value (Arg (Arg'First .. First - 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 First := First + 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 declare
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 Str : aliased String (1 .. Last - First + 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 Index : Natural := 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 -- Strip underscores
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 for J in First .. Last loop
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 if Arg (J) /= '_' then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 Index := Index + 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 Str (Index) := Arg (J);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 end loop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 Index := Index + 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 Str (Index) := ASCII.NUL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 if mpz_set_str (Get_Mpz (Result), Str'Address, Base) /= 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 end From_String;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 ---------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 -- Put_Image --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 ---------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 procedure Put_Image
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 Arg : Big_Integer) is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 Wide_Wide_String'Write (Stream, To_Wide_Wide_String (To_String (Arg)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 end Put_Image;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 -- "+" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 function "+" (L : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 Set_Mpz (Result, new mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 mpz_init_set (Get_Mpz (Result), Get_Mpz (L));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 end "+";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 -- "-" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 function "-" (L : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 mpz_neg (Get_Mpz (Result), Get_Mpz (L));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 end "-";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 -- "abs" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 function "abs" (L : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 procedure mpz_abs (ROP : access mpz_t; OP : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 pragma Import (C, mpz_abs, "__gmpz_abs");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 mpz_abs (Get_Mpz (Result), Get_Mpz (L));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 end "abs";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 -- "+" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 function "+" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 procedure mpz_add
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 (ROP : access mpz_t; OP1, OP2 : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 pragma Import (C, mpz_add, "__gmpz_add");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 mpz_add (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 end "+";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 -- "-" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 function "-" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 mpz_sub (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 end "-";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 -- "*" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 function "*" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 procedure mpz_mul
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 (ROP : access mpz_t; OP1, OP2 : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 pragma Import (C, mpz_mul, "__gmpz_mul");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 mpz_mul (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 end "*";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 -- "/" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 function "/" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 procedure mpz_tdiv_q (Q : access mpz_t; N, D : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 pragma Import (C, mpz_tdiv_q, "__gmpz_tdiv_q");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 if mpz_cmp_ui (Get_Mpz (R), 0) = 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 declare
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 mpz_tdiv_q (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 end "/";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 -- "mod" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 function "mod" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 procedure mpz_mod (R : access mpz_t; N, D : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 pragma Import (C, mpz_mod, "__gmpz_mod");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 -- result is always non-negative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 L_Negative, R_Negative : Boolean;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 if mpz_cmp_ui (Get_Mpz (R), 0) = 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 declare
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 L_Negative := mpz_cmp_ui (Get_Mpz (L), 0) < 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 R_Negative := mpz_cmp_ui (Get_Mpz (R), 0) < 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 if not (L_Negative or R_Negative) then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 mpz_mod (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 -- The GMP library provides operators defined by C semantics, but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 -- the semantics of Ada's mod operator are not the same as C's
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 -- when negative values are involved. We do the following to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 -- implement the required Ada semantics.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 declare
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 Temp_Left : Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 Temp_Right : Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 Temp_Result : Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 Allocate (Temp_Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 Set_Mpz (Temp_Left, new mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 Set_Mpz (Temp_Right, new mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 mpz_init_set (Get_Mpz (Temp_Left), Get_Mpz (L));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 mpz_init_set (Get_Mpz (Temp_Right), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 if L_Negative then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 mpz_neg (Get_Mpz (Temp_Left), Get_Mpz (Temp_Left));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 if R_Negative then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 mpz_neg (Get_Mpz (Temp_Right), Get_Mpz (Temp_Right));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 -- now both Temp_Left and Temp_Right are nonnegative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 mpz_mod (Get_Mpz (Temp_Result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 Get_Mpz (Temp_Left),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 Get_Mpz (Temp_Right));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 if mpz_cmp_ui (Get_Mpz (Temp_Result), 0) = 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 -- if Temp_Result is zero we are done
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 mpz_set (Get_Mpz (Result), Get_Mpz (Temp_Result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 elsif L_Negative then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 if R_Negative then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 mpz_neg (Get_Mpz (Result), Get_Mpz (Temp_Result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 else -- L is negative but R is not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 mpz_sub (Get_Mpz (Result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 Get_Mpz (Temp_Right),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 Get_Mpz (Temp_Result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 pragma Assert (R_Negative);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 mpz_sub (Get_Mpz (Result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 Get_Mpz (Temp_Result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 Get_Mpz (Temp_Right));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 end "mod";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 -- "rem" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 -----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 function "rem" (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 procedure mpz_tdiv_r (R : access mpz_t; N, D : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 pragma Import (C, mpz_tdiv_r, "__gmpz_tdiv_r");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 -- R will have the same sign as N.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 if mpz_cmp_ui (Get_Mpz (R), 0) = 0 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 raise Constraint_Error;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 declare
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 mpz_tdiv_r (R => Get_Mpz (Result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 N => Get_Mpz (L),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 D => Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 -- the result takes the sign of N, as required by the RM
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 end "rem";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 -- "**" --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 ----------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 function "**" (L : Big_Integer; R : Natural) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 procedure mpz_pow_ui (ROP : access mpz_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 BASE : access constant mpz_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 EXP : unsigned_long);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 pragma Import (C, mpz_pow_ui, "__gmpz_pow_ui");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 mpz_pow_ui (Get_Mpz (Result), Get_Mpz (L), unsigned_long (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 end "**";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 -- Min --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 function Min (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 (if L < R then L else R);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 -- Max --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 ---------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 function Max (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 (if L > R then L else R);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 -----------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 -- Greatest_Common_Divisor --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 -----------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 function Greatest_Common_Divisor (L, R : Big_Integer) return Big_Integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 procedure mpz_gcd
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 (ROP : access mpz_t; Op1, Op2 : access constant mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 pragma Import (C, mpz_gcd, "__gmpz_gcd");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 Result : Optional_Big_Integer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 Allocate (Result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 mpz_gcd (Get_Mpz (Result), Get_Mpz (L), Get_Mpz (R));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 return Result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 end Greatest_Common_Divisor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 -- Allocate --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 procedure Allocate (This : in out Optional_Big_Integer) is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 procedure mpz_init (this : access mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 pragma Import (C, mpz_init, "__gmpz_init");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 Set_Mpz (This, new mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 mpz_init (Get_Mpz (This));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 end Allocate;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 ------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 -- Adjust --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 ------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 procedure Adjust (This : in out Controlled_Bignum) is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 Value : constant mpz_t_ptr := To_Mpz (This.C);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 if Value /= null then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 This.C := To_Address (new mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 mpz_init_set (To_Mpz (This.C), Value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 end Adjust;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 -- Finalize --
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 --------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 procedure Finalize (This : in out Controlled_Bignum) is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 procedure Free is new Ada.Unchecked_Deallocation (mpz_t, mpz_t_ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 procedure mpz_clear (this : access mpz_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 pragma Import (C, mpz_clear, "__gmpz_clear");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 Mpz : mpz_t_ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 begin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 if This.C /= System.Null_Address then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 Mpz := To_Mpz (This.C);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 mpz_clear (Mpz);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 Free (Mpz);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 This.C := System.Null_Address;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 end Finalize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 end Ada.Numerics.Big_Numbers.Big_Integers;