0
# Utility Functions
1
2
gmpy2 provides various utility functions for version information, binary serialization, floating-point system configuration, and performance optimization. These functions support debugging, serialization, and system integration.
3
4
## Capabilities
5
6
### Version Information
7
8
Functions for retrieving version information about gmpy2 and underlying libraries.
9
10
```python { .api }
11
def version():
12
"""
13
Get gmpy2 version string.
14
15
Returns:
16
str: gmpy2 version (e.g., "2.2.1")
17
"""
18
19
def mp_version():
20
"""
21
Get GMP library version string.
22
23
Returns:
24
str: GMP version information
25
"""
26
27
def mpfr_version():
28
"""
29
Get MPFR library version string.
30
31
Returns:
32
str: MPFR version information
33
"""
34
35
def mpc_version():
36
"""
37
Get MPC library version string.
38
39
Returns:
40
str: MPC version information
41
"""
42
43
def mp_limbsize():
44
"""
45
Get GMP limb size in bits.
46
47
Returns:
48
int: Number of bits per GMP limb (typically 32 or 64)
49
50
Note:
51
Limb size affects performance and internal representation
52
"""
53
54
def license():
55
"""
56
Get license information for gmpy2.
57
58
Returns:
59
str: License text and information
60
"""
61
```
62
63
### Binary Serialization
64
65
Functions for converting gmpy2 objects to and from binary format for storage and transmission.
66
67
```python { .api }
68
def to_binary(x):
69
"""
70
Convert gmpy2 object to binary format.
71
72
Args:
73
x: gmpy2 object (mpz, mpq, mpfr, mpc)
74
75
Returns:
76
bytes: Binary representation of the object
77
78
Note:
79
Binary format preserves full precision and is platform-independent
80
"""
81
82
def from_binary(s):
83
"""
84
Create gmpy2 object from binary format.
85
86
Args:
87
s: Binary data (bytes or str)
88
89
Returns:
90
gmpy2 object of appropriate type
91
92
Raises:
93
ValueError: If binary data is invalid or corrupted
94
"""
95
96
def pack(x, precision, emin, emax):
97
"""
98
Pack floating-point number to binary with specified format.
99
100
Args:
101
x: Floating-point value (mpfr)
102
precision: Precision in bits
103
emin: Minimum exponent
104
emax: Maximum exponent
105
106
Returns:
107
bytes: Packed binary representation
108
109
Note:
110
Useful for creating custom floating-point formats
111
"""
112
113
def unpack(s, precision, emin, emax):
114
"""
115
Unpack floating-point number from binary format.
116
117
Args:
118
s: Binary data (bytes)
119
precision: Precise in bits used for packing
120
emin: Minimum exponent used for packing
121
emax: Maximum exponent used for packing
122
123
Returns:
124
mpfr: Unpacked floating-point value
125
126
Raises:
127
ValueError: If binary data doesn't match specified format
128
"""
129
```
130
131
### Legacy Binary Support
132
133
Functions for importing from older gmpy binary formats.
134
135
```python { .api }
136
def mpz_from_old_binary(s):
137
"""
138
Import mpz from old binary format.
139
140
Args:
141
s: Old format binary data
142
143
Returns:
144
mpz: Converted integer
145
"""
146
147
def mpq_from_old_binary(s):
148
"""
149
Import mpq from old binary format.
150
151
Args:
152
s: Old format binary data
153
154
Returns:
155
mpq: Converted rational number
156
"""
157
158
def mpfr_from_old_binary(s):
159
"""
160
Import mpfr from old binary format.
161
162
Args:
163
s: Old format binary data
164
165
Returns:
166
mpfr: Converted floating-point number
167
"""
168
```
169
170
### MPFR System Configuration
171
172
Functions for querying and configuring MPFR system limits and behavior.
173
174
```python { .api }
175
def get_max_precision():
176
"""
177
Get maximum allowed precision for MPFR operations.
178
179
Returns:
180
int: Maximum precision in bits
181
182
Note:
183
System-dependent limit, typically very large
184
"""
185
186
def get_emax_max():
187
"""
188
Get maximum allowed exponent value.
189
190
Returns:
191
int: Maximum exponent for MPFR numbers
192
"""
193
194
def get_emin_min():
195
"""
196
Get minimum allowed exponent value.
197
198
Returns:
199
int: Minimum exponent for MPFR numbers
200
"""
201
202
def free_cache():
203
"""
204
Free internal MPFR caches to release memory.
205
206
Note:
207
Call this to free memory used by MPFR's internal caches
208
Useful for long-running programs to manage memory usage
209
"""
210
```
211
212
### Floating-Point Utilities
213
214
Advanced floating-point manipulation and analysis functions.
215
216
```python { .api }
217
def can_round(x, err, rnd1, rnd2, prec):
218
"""
219
Test if rounding is deterministic given error bounds.
220
221
Args:
222
x: Value to test (mpfr)
223
err: Error bound
224
rnd1: First rounding mode
225
rnd2: Second rounding mode
226
prec: Target precision
227
228
Returns:
229
bool: True if both rounding modes yield same result
230
231
Note:
232
Useful for determining if a computed result can be rounded safely
233
"""
234
235
def check_range(x):
236
"""
237
Check and adjust value to fit in current context range.
238
239
Args:
240
x: Floating-point value (mpfr)
241
242
Returns:
243
mpfr: Value adjusted for current context emin/emax if needed
244
"""
245
246
def next_above(x):
247
"""
248
Get next representable value above x.
249
250
Args:
251
x: Floating-point value (mpfr)
252
253
Returns:
254
mpfr: Smallest representable value > x
255
"""
256
257
def next_below(x):
258
"""
259
Get next representable value below x.
260
261
Args:
262
x: Floating-point value (mpfr)
263
264
Returns:
265
mpfr: Largest representable value < x
266
"""
267
268
def next_toward(x, y):
269
"""
270
Get next representable value toward y.
271
272
Args:
273
x: Starting value (mpfr)
274
y: Direction value (mpfr)
275
276
Returns:
277
mpfr: Next representable value in direction of y
278
"""
279
280
def reldiff(x, y):
281
"""
282
Compute relative difference between two values.
283
284
Args:
285
x, y: Floating-point values (mpfr)
286
287
Returns:
288
mpfr: Relative difference |x-y|/max(|x|,|y|)
289
"""
290
291
def get_exp(x):
292
"""
293
Get exponent of floating-point number.
294
295
Args:
296
x: Floating-point value (mpfr)
297
298
Returns:
299
int: Exponent of x
300
"""
301
302
def set_exp(x, exp):
303
"""
304
Set exponent of floating-point number.
305
306
Args:
307
x: Floating-point value (mpfr)
308
exp: New exponent value
309
310
Returns:
311
mpfr: Value with modified exponent
312
"""
313
314
def set_sign(x, sign):
315
"""
316
Set sign of floating-point number.
317
318
Args:
319
x: Floating-point value (mpfr)
320
sign: Sign (positive/negative indicator)
321
322
Returns:
323
mpfr: Value with specified sign
324
"""
325
```
326
327
### Rational Conversion Utilities
328
329
```python { .api }
330
def f2q(x, max_denominator=None):
331
"""
332
Convert float to rational with optional denominator limit.
333
334
Args:
335
x: Floating-point value
336
max_denominator: Maximum allowed denominator (None for no limit)
337
338
Returns:
339
mpq: Rational approximation of x
340
341
Note:
342
Provides controlled conversion from float to exact rational
343
"""
344
```
345
346
### Advanced Number Theory
347
348
```python { .api }
349
def prev_prime(x):
350
"""
351
Find previous prime number less than x (requires GMP 6.3.0+).
352
353
Args:
354
x: Starting value
355
356
Returns:
357
mpz: Previous prime before x
358
359
Note:
360
Counterpart to next_prime(), available in newer GMP versions
361
"""
362
```
363
364
### Predicates
365
366
```python { .api }
367
def is_lessgreater(x, y):
368
"""
369
Test if x < y or x > y (not equal, not unordered).
370
371
Args:
372
x, y: Numeric values
373
374
Returns:
375
bool: True if x != y and neither is NaN
376
"""
377
378
def is_unordered(x, y):
379
"""
380
Test if comparison is unordered (involves NaN).
381
382
Args:
383
x, y: Numeric values
384
385
Returns:
386
bool: True if either x or y is NaN
387
"""
388
```
389
390
## Usage Examples
391
392
### Version Information
393
394
```python
395
import gmpy2
396
397
# Get version information
398
print(f"gmpy2 version: {gmpy2.version()}")
399
print(f"GMP version: {gmpy2.mp_version()}")
400
print(f"MPFR version: {gmpy2.mpfr_version()}")
401
print(f"MPC version: {gmpy2.mpc_version()}")
402
print(f"GMP limb size: {gmpy2.mp_limbsize()} bits")
403
404
# Display license information
405
print("License:")
406
print(gmpy2.license())
407
```
408
409
### Binary Serialization
410
411
```python
412
import gmpy2
413
414
# Create various gmpy2 objects
415
integer = gmpy2.mpz("123456789012345678901234567890")
416
rational = gmpy2.mpq(22, 7)
417
real = gmpy2.mpfr("3.14159265358979323846264338327950288419716939937510")
418
complex_num = gmpy2.mpc("1.5+2.5j")
419
420
# Convert to binary format
421
print("Binary serialization:")
422
for name, obj in [("Integer", integer), ("Rational", rational),
423
("Real", real), ("Complex", complex_num)]:
424
binary_data = gmpy2.to_binary(obj)
425
print(f"{name}: {len(binary_data)} bytes")
426
427
# Deserialize back
428
restored = gmpy2.from_binary(binary_data)
429
print(f" Original: {obj}")
430
print(f" Restored: {restored}")
431
print(f" Equal: {obj == restored}")
432
```
433
434
### MPFR System Limits
435
436
```python
437
import gmpy2
438
439
# Query system limits
440
print("MPFR system limits:")
441
print(f"Maximum precision: {gmpy2.get_max_precision()} bits")
442
print(f"Maximum exponent: {gmpy2.get_emax_max()}")
443
print(f"Minimum exponent: {gmpy2.get_emin_min()}")
444
445
# Test precision limits
446
try:
447
with gmpy2.local_context(precision=gmpy2.get_max_precision()):
448
x = gmpy2.mpfr("1.5")
449
print(f"Using maximum precision: {x.precision} bits")
450
except:
451
print("Maximum precision too large for this system")
452
453
# Memory management
454
print("Freeing MPFR caches...")
455
gmpy2.free_cache()
456
```
457
458
### Floating-Point Analysis
459
460
```python
461
import gmpy2
462
463
with gmpy2.local_context(precision=100):
464
x = gmpy2.mpfr("1.5")
465
466
# Examine representable values
467
above = gmpy2.next_above(x)
468
below = gmpy2.next_below(x)
469
470
print(f"Value: {x}")
471
print(f"Next above: {above}")
472
print(f"Next below: {below}")
473
print(f"Difference above: {above - x}")
474
print(f"Difference below: {x - below}")
475
476
# Get/set exponent
477
exp = gmpy2.get_exp(x)
478
print(f"Exponent: {exp}")
479
480
# Relative difference
481
y = gmpy2.mpfr("1.50000000000001")
482
rel_diff = gmpy2.reldiff(x, y)
483
print(f"Relative difference: {rel_diff}")
484
```
485
486
### Float to Rational Conversion
487
488
```python
489
import gmpy2
490
491
# Convert floats to rationals with denominator limits
492
test_values = [3.14159, 2.71828, 1.41421]
493
494
print("Float to rational conversion:")
495
for val in test_values:
496
# Unlimited denominator
497
exact = gmpy2.f2q(val)
498
499
# Limited denominator
500
approx_100 = gmpy2.f2q(val, max_denominator=100)
501
approx_1000 = gmpy2.f2q(val, max_denominator=1000)
502
503
print(f"\nFloat: {val}")
504
print(f" Exact: {exact}")
505
print(f" Max denom 100: {approx_100} = {float(approx_100)}")
506
print(f" Max denom 1000: {approx_1000} = {float(approx_1000)}")
507
```
508
509
### Rounding Determinism Test
510
511
```python
512
import gmpy2
513
514
with gmpy2.local_context(precision=50):
515
# Test if rounding is deterministic
516
x = gmpy2.mpfr("1.23456789")
517
error = gmpy2.mpfr("1e-10") # Small error bound
518
target_precision = 30
519
520
# Test different rounding mode pairs
521
rounding_pairs = [
522
(gmpy2.RoundToNearest, gmpy2.RoundUp),
523
(gmpy2.RoundDown, gmpy2.RoundUp),
524
(gmpy2.RoundToZero, gmpy2.RoundToNearest)
525
]
526
527
for rnd1, rnd2 in rounding_pairs:
528
deterministic = gmpy2.can_round(x, error, rnd1, rnd2, target_precision)
529
print(f"Rounding modes {rnd1} vs {rnd2}: {'deterministic' if deterministic else 'not deterministic'}")
530
```
531
532
### NaN and Special Value Handling
533
534
```python
535
import gmpy2
536
537
# Create special values
538
x = gmpy2.mpfr("1.5")
539
y = gmpy2.nan()
540
z = gmpy2.inf()
541
542
# Test predicates
543
print("Special value predicates:")
544
print(f"is_lessgreater(1.5, 2.0): {gmpy2.is_lessgreater(x, gmpy2.mpfr('2.0'))}")
545
print(f"is_lessgreater(1.5, NaN): {gmpy2.is_lessgreater(x, y)}") # False
546
print(f"is_unordered(1.5, NaN): {gmpy2.is_unordered(x, y)}") # True
547
print(f"is_unordered(1.5, inf): {gmpy2.is_unordered(x, z)}") # False
548
```