Skip to main content

dec_number_sys/
dec_quad.rs

1//! Safe bindings for 128-bit decimal.
2
3use crate::dec_context::DecContext;
4use crate::dec_quad_c::*;
5use crate::{DEC_FLOAT_SIGN, DEC_QUAD_PMAX};
6use libc::{c_char, c_int, c_uint};
7use std::ffi::{CStr, CString};
8use std::fmt::Debug;
9
10/// Length in bytes of the [DecQuad] union.
11pub const DEC_QUAD_BYTES: usize = 16;
12
13/// Maximum length of the [DecQuad] string.
14pub const DEC_QUAD_STRING: usize = 43;
15
16/// [DecQuad] string buffer.
17pub const DEC_QUAD_STRING_BUFFER: [c_char; DEC_QUAD_STRING] = [0; DEC_QUAD_STRING];
18
19/// [DecQuad] value `0` (zero).
20
21pub const DEC_QUAD_ZERO: DecQuad = {
22  #[cfg(target_endian = "little")]
23  {
24    DecQuad {
25      bytes: [
26        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
27      ],
28    }
29  }
30  #[cfg(target_endian = "big")]
31  {
32    DecQuad {
33      bytes: [
34        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35      ],
36    }
37  }
38};
39
40/// [DecQuad] value `1` (one).
41
42pub const DEC_QUAD_ONE: DecQuad = {
43  #[cfg(target_endian = "little")]
44  {
45    DecQuad {
46      bytes: [
47        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
48      ],
49    }
50  }
51  #[cfg(target_endian = "big")]
52  {
53    DecQuad {
54      bytes: [
55        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
56      ],
57    }
58  }
59};
60
61/// [DecQuad] value `2` (two).
62
63pub const DEC_QUAD_TWO: DecQuad = {
64  #[cfg(target_endian = "little")]
65  {
66    DecQuad {
67      bytes: [
68        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
69      ],
70    }
71  }
72  #[cfg(target_endian = "big")]
73  {
74    DecQuad {
75      bytes: [
76        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
77      ],
78    }
79  }
80};
81
82/// [DecQuad] value `10` (ten).
83
84pub const DEC_QUAD_TEN: DecQuad = {
85  #[cfg(target_endian = "little")]
86  {
87    DecQuad {
88      bytes: [
89        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
90      ],
91    }
92  }
93  #[cfg(target_endian = "big")]
94  {
95    DecQuad {
96      bytes: [
97        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
98      ],
99    }
100  }
101};
102
103/// [DecQuad] value `100` (hundred).
104
105pub const DEC_QUAD_HUNDRED: DecQuad = {
106  #[cfg(target_endian = "little")]
107  {
108    DecQuad {
109      bytes: [
110        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
111      ],
112    }
113  }
114  #[cfg(target_endian = "big")]
115  {
116    DecQuad {
117      bytes: [
118        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
119      ],
120    }
121  }
122};
123
124/// [DecQuad] value `1000` (thousand).
125
126pub const DEC_QUAD_THOUSAND: DecQuad = {
127  #[cfg(target_endian = "little")]
128  {
129    DecQuad {
130      bytes: [
131        0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
132      ],
133    }
134  }
135  #[cfg(target_endian = "big")]
136  {
137    DecQuad {
138      bytes: [
139        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
140      ],
141    }
142  }
143};
144
145/// [DecQuad] value `1000000` (million).
146
147pub const DEC_QUAD_MILLION: DecQuad = {
148  #[cfg(target_endian = "little")]
149  {
150    DecQuad {
151      bytes: [
152        0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
153      ],
154    }
155  }
156  #[cfg(target_endian = "big")]
157  {
158    DecQuad {
159      bytes: [
160        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
161      ],
162    }
163  }
164};
165
166/// [DecQuad] value `1000000000` (billion).
167
168pub const DEC_QUAD_BILLION: DecQuad = {
169  #[cfg(target_endian = "little")]
170  {
171    DecQuad {
172      bytes: [
173        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
174      ],
175    }
176  }
177  #[cfg(target_endian = "big")]
178  {
179    DecQuad {
180      bytes: [
181        0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
182      ],
183    }
184  }
185};
186
187/// 128-bit decimal number.
188#[repr(C)]
189#[derive(Copy, Clone)]
190pub union DecQuad {
191  pub bytes: [u8; DEC_QUAD_BYTES],
192  pub shorts: [u16; DEC_QUAD_BYTES / 2],
193  pub words: [u32; DEC_QUAD_BYTES / 4],
194  pub longs: [u64; DEC_QUAD_BYTES / 8],
195}
196
197impl Default for DecQuad {
198  /// The default value for [DecQuad] is positive zero.
199  fn default() -> Self {
200    DEC_QUAD_ZERO
201  }
202}
203
204impl Debug for DecQuad {
205  /// Converts [DecQuad] to a string in the form of hexadecimal bytes separated with spaces.
206  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207    write!(
208      f,
209      "[{}]",
210      (0..DEC_QUAD_BYTES)
211        .rev()
212        .fold("".to_string(), |s, i| format!("{} {:02X}", s, unsafe { self.bytes[i] }))
213        .trim_start()
214    )
215  }
216}
217
218/// Safe binding to *decQuadAbs* function.
219pub fn dec_quad_abs(dq1: &DecQuad, dc: &mut DecContext) -> DecQuad {
220  let mut dq = DEC_QUAD_ZERO;
221  unsafe {
222    decQuadAbs(&mut dq, dq1, dc);
223  }
224  dq
225}
226
227/// Safe binding to *decQuadAdd* function.
228pub fn dec_quad_add(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
229  let mut dq = DEC_QUAD_ZERO;
230  unsafe {
231    decQuadAdd(&mut dq, dq1, dq2, dc);
232  }
233  dq
234}
235
236/// Safe binding to *decQuadAnd* function.
237pub fn dec_quad_and(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
238  let mut dq = DEC_QUAD_ZERO;
239  unsafe {
240    decQuadAnd(&mut dq, dq1, dq2, dc);
241  }
242  dq
243}
244
245/// Safe binding to *decQuadCanonical* function.
246pub fn dec_quad_canonical(dq1: &DecQuad) -> DecQuad {
247  let mut dq = DEC_QUAD_ZERO;
248  unsafe {
249    decQuadCanonical(&mut dq, dq1);
250  }
251  dq
252}
253
254/// Safe binding to *decQuadCompare* function.
255pub fn dec_quad_compare(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
256  let mut dq = DEC_QUAD_ZERO;
257  unsafe {
258    decQuadCompare(&mut dq, dq1, dq2, dc);
259  }
260  dq
261}
262
263/// Safe binding to *decQuadCompareSignal* function.
264pub fn dec_quad_compare_signal(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
265  let mut dq = DEC_QUAD_ZERO;
266  unsafe {
267    decQuadCompareSignal(&mut dq, dq1, dq2, dc);
268  }
269  dq
270}
271
272/// Safe binding to *decQuadCompareTotal* function.
273pub fn dec_quad_compare_total(dq1: &DecQuad, dq2: &DecQuad) -> DecQuad {
274  let mut dq = DEC_QUAD_ZERO;
275  unsafe {
276    decQuadCompareTotal(&mut dq, dq1, dq2);
277  }
278  dq
279}
280
281/// Safe binding to *decQuadCompareTotalMag* function.
282pub fn dec_quad_compare_total_mag(dq1: &DecQuad, dq2: &DecQuad) -> DecQuad {
283  let mut dq = DEC_QUAD_ZERO;
284  unsafe {
285    decQuadCompareTotalMag(&mut dq, dq1, dq2);
286  }
287  dq
288}
289
290/// Safe binding to *decQuadCopy* function.
291pub fn dec_quad_copy(dq1: &DecQuad) -> DecQuad {
292  let mut dq = DEC_QUAD_ZERO;
293  unsafe {
294    decQuadCopy(&mut dq, dq1);
295  }
296  dq
297}
298
299/// Safe binding to *decQuadCopyAbs* function.
300pub fn dec_quad_copy_abs(dq1: &DecQuad) -> DecQuad {
301  let mut dq = DEC_QUAD_ZERO;
302  unsafe {
303    decQuadCopyAbs(&mut dq, dq1);
304  }
305  dq
306}
307
308/// Safe binding to *decQuadCopyNegate* function.
309pub fn dec_quad_copy_negate(dq1: &DecQuad) -> DecQuad {
310  let mut dq = DEC_QUAD_ZERO;
311  unsafe {
312    decQuadCopyNegate(&mut dq, dq1);
313  }
314  dq
315}
316
317/// Safe binding to *decQuadCopySign* function.
318pub fn dec_quad_copy_sign(dq1: &DecQuad, dq2: &DecQuad) -> DecQuad {
319  let mut dq = DEC_QUAD_ZERO;
320  unsafe {
321    decQuadCopySign(&mut dq, dq1, dq2);
322  }
323  dq
324}
325
326/// Safe binding to *decQuadDigits* function.
327pub fn dec_quad_digits(dq1: &DecQuad) -> c_uint {
328  let dq;
329  unsafe {
330    dq = decQuadDigits(dq1);
331  }
332  dq
333}
334
335/// Safe binding to *decQuadDivide* function.
336pub fn dec_quad_divide(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
337  let mut dq = DEC_QUAD_ZERO;
338  unsafe {
339    decQuadDivide(&mut dq, dq1, dq2, dc);
340  }
341  dq
342}
343
344/// Safe binding to *decQuadDivideInteger* function.
345pub fn dec_quad_divide_integer(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
346  let mut dq = DEC_QUAD_ZERO;
347  unsafe {
348    decQuadDivideInteger(&mut dq, dq1, dq2, dc);
349  }
350  dq
351}
352
353/// Safe binding to *decQuadFMA* function.
354pub fn dec_quad_fma(dq1: &DecQuad, dq2: &DecQuad, dq3: &DecQuad, dc: &mut DecContext) -> DecQuad {
355  let mut dq = DEC_QUAD_ZERO;
356  unsafe {
357    decQuadFMA(&mut dq, dq1, dq2, dq3, dc);
358  }
359  dq
360}
361
362/// Safe binding to *decQuadFromBCD* function.
363pub fn dec_quad_from_bcd(bcd: &[u8; DEC_QUAD_PMAX], exp: i32, sign: bool) -> DecQuad {
364  let mut dq = DEC_QUAD_ZERO;
365  unsafe {
366    decQuadFromBCD(&mut dq, exp, bcd.as_ptr(), if sign { DEC_FLOAT_SIGN } else { 0 });
367  }
368  dq
369}
370
371/// Safe binding to *decQuadFromInt32* function.
372pub fn dec_quad_from_i32(n: i32) -> DecQuad {
373  let mut dq = DEC_QUAD_ZERO;
374  unsafe {
375    decQuadFromInt32(&mut dq, n);
376  }
377  dq
378}
379
380// /// Safe binding to *decQuadFromNumber* function.
381// pub fn dec_quad_from_number(dn: &DecNumber, dc: &mut DecContext) -> DecQuad {
382//   let mut dq = DEC_QUAD_ZERO;
383//   unsafe {
384//     decQuadFromNumber(&mut dq, dn, dc);
385//   }
386//   dq
387// }
388
389// /// Safe binding to *decQuadFromPacked* function.
390// pub fn dec_quad_from_packed(exp: i32, pack: &[u8; DEC_QUAD_PMAX]) -> DecQuad {
391//   let mut dq = DEC_QUAD_ZERO;
392//   unsafe {
393//     decQuadFromPacked(&mut dq, exp, pack.as_ptr());
394//   }
395//   dq
396// }
397
398/// Safe binding to *decQuadFromString* function.
399pub fn dec_quad_from_string(s: &str, dc: &mut DecContext) -> DecQuad {
400  let c_s = CString::new(s).unwrap();
401  let mut dq = DEC_QUAD_ZERO;
402  unsafe {
403    decQuadFromString(&mut dq, c_s.as_ptr(), dc);
404  }
405  dq
406}
407
408/// Safe binding to *decQuadFromUInt32* function.
409pub fn dec_quad_from_u32(n: u32) -> DecQuad {
410  let mut dq = DEC_QUAD_ZERO;
411  unsafe {
412    decQuadFromUInt32(&mut dq, n);
413  }
414  dq
415}
416
417/// Safe binding to *decQuadFromWider* function.
418pub fn dec_quad_from_wider(dq1: &DecQuad, dc: &mut DecContext) -> DecQuad {
419  let mut dq = DEC_QUAD_ZERO;
420  unsafe {
421    decQuadFromWider(&mut dq, dq1, dc);
422  }
423  dq
424}
425
426/// Safe binding to *decQuadGetCoefficient* function.
427pub fn dec_quad_get_coefficient(x: &DecQuad, bcd: &mut [u8; DEC_QUAD_PMAX]) -> c_int {
428  unsafe { decQuadGetCoefficient(x, bcd.as_mut_ptr()) }
429}
430
431/// Safe binding to *decQuadGetExponent* function.
432pub fn dec_quad_get_exponent(x: &DecQuad) -> DecQuad {
433  unsafe { decQuadGetExponent(x) }
434}
435
436/// Safe binding to *decQuadInvert* function.
437pub fn dec_quad_invert(dq1: &DecQuad, dc: &mut DecContext) -> DecQuad {
438  let mut dq = DEC_QUAD_ZERO;
439  unsafe {
440    decQuadInvert(&mut dq, dq1, dc);
441  }
442  dq
443}
444
445/// Safe binding to *decQuadIsCanonical* function.
446pub fn dec_quad_is_canonical(dn: &DecQuad) -> bool {
447  unsafe { decQuadIsCanonical(dn) == 1 }
448}
449
450/// Safe binding to *decQuadIsFinite* function.
451pub fn dec_quad_is_finite(dn: &DecQuad) -> bool {
452  unsafe { decQuadIsFinite(dn) == 1 }
453}
454
455/// Safe binding to *decQuadIsInfinite* function.
456pub fn dec_quad_is_infinite(dn: &DecQuad) -> bool {
457  unsafe { decQuadIsInfinite(dn) == 1 }
458}
459
460/// Safe binding to *decQuadIsInteger* function.
461pub fn dec_quad_is_integer(dn: &DecQuad) -> bool {
462  unsafe { decQuadIsInteger(dn) == 1 }
463}
464
465/// Safe binding to *decQuadIsLogical* function.
466pub fn dec_quad_is_logical(dn: &DecQuad) -> bool {
467  unsafe { decQuadIsLogical(dn) == 1 }
468}
469
470/// Safe binding to *decQuadIsNaN* function.
471pub fn dec_quad_is_nan(dn: &DecQuad) -> bool {
472  unsafe { decQuadIsNaN(dn) == 1 }
473}
474
475/// Safe binding to *decQuadIsNormal* function.
476pub fn dec_quad_is_normal(dn: &DecQuad) -> bool {
477  unsafe { decQuadIsNormal(dn) == 1 }
478}
479
480/// Safe binding to *decQuadIsNegative* function.
481pub fn dec_quad_is_negative(dn: &DecQuad) -> bool {
482  unsafe { decQuadIsNegative(dn) == 1 }
483}
484
485/// Safe binding to *decQuadIsPositive* function.
486pub fn dec_quad_is_positive(dn: &DecQuad) -> bool {
487  unsafe { decQuadIsPositive(dn) == 1 }
488}
489
490/// Safe binding to *decQuadIsSignaling* function.
491pub fn dec_quad_is_signaling(dn: &DecQuad) -> bool {
492  unsafe { decQuadIsSignaling(dn) == 1 }
493}
494
495/// Safe binding to *decQuadIsSignalling* function.
496pub fn dec_quad_is_signalling(dn: &DecQuad) -> bool {
497  unsafe { decQuadIsSignalling(dn) == 1 }
498}
499
500/// Safe binding to *decQuadIsZero* function.
501pub fn dec_quad_is_zero(dn: &DecQuad) -> bool {
502  unsafe { decQuadIsZero(dn) == 1 }
503}
504
505/// Safe binding to *decQuadMinus* function.
506pub fn dec_quad_minus(dn: &DecQuad, dc: &mut DecContext) -> DecQuad {
507  let mut dq = DEC_QUAD_ZERO;
508  unsafe {
509    decQuadMinus(&mut dq, dn, dc);
510  }
511  dq
512}
513
514/// Safe binding to *decQuadMultiply* function.
515pub fn dec_quad_multiply(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
516  let mut dq = DEC_QUAD_ZERO;
517  unsafe {
518    decQuadMultiply(&mut dq, dq1, dq2, dc);
519  }
520  dq
521}
522
523/// Safe binding to *decQuadPlus* function.
524pub fn dec_quad_plus(dq1: &DecQuad, dc: &mut DecContext) -> DecQuad {
525  let mut dq = DEC_QUAD_ZERO;
526  unsafe {
527    decQuadPlus(&mut dq, dq1, dc);
528  }
529  dq
530}
531
532/// Safe binding to *decQuadQuantize* function.
533pub fn dec_quad_quantize(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
534  let mut dq = DEC_QUAD_ZERO;
535  unsafe {
536    decQuadQuantize(&mut dq, dq1, dq2, dc);
537  }
538  dq
539}
540
541/// Safe binding to *decQuadReduce* function.
542pub fn dec_quad_reduce(dq1: &DecQuad, dc: &mut DecContext) -> DecQuad {
543  let mut dq = DEC_QUAD_ZERO;
544  unsafe {
545    decQuadReduce(&mut dq, dq1, dc);
546  }
547  dq
548}
549
550/// Safe binding to *decQuadRemainder* function.
551pub fn dec_quad_remainder(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
552  let mut dq = DEC_QUAD_ZERO;
553  unsafe {
554    decQuadRemainder(&mut dq, dq1, dq2, dc);
555  }
556  dq
557}
558
559/// Safe binding to *decQuadScaleB* function.
560pub fn dec_quad_scale_b(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
561  let mut dq = DEC_QUAD_ZERO;
562  unsafe {
563    decQuadScaleB(&mut dq, dq1, dq2, dc);
564  }
565  dq
566}
567
568/// Safe binding to *decQuadSubtract* function.
569pub fn dec_quad_subtract(dq1: &DecQuad, dq2: &DecQuad, dc: &mut DecContext) -> DecQuad {
570  let mut dq = DEC_QUAD_ZERO;
571  unsafe {
572    decQuadSubtract(&mut dq, dq1, dq2, dc);
573  }
574  dq
575}
576
577/// Safe binding to *decQuadToInt32* function.
578pub fn dec_quad_to_int32(dq: &DecQuad, dc: &mut DecContext, rounding: u32) -> i32 {
579  unsafe { decQuadToInt32(dq, dc, rounding) }
580}
581
582/// Safe binding to *decQuadToIntegralValue* function.
583pub fn dec_quad_to_integral_value(dq1: &DecQuad, dc: &mut DecContext, rounding: u32) -> DecQuad {
584  let mut dq = DEC_QUAD_ZERO;
585  unsafe {
586    decQuadToIntegralValue(&mut dq, dq1, dc, rounding);
587  }
588  dq
589}
590
591/// Safe binding to *decQuadToString* function.
592pub fn dec_quad_to_string(dq1: &DecQuad) -> String {
593  unsafe {
594    let mut buf = DEC_QUAD_STRING_BUFFER;
595    decQuadToString(dq1, buf.as_mut_ptr() as *mut c_char);
596    CStr::from_ptr(buf.as_ptr() as *const c_char)
597      .to_string_lossy()
598      .into_owned()
599  }
600}
601
602/// Safe binding to *decQuadToUInt32* function.
603pub fn dec_quad_to_uint32(dq: &DecQuad, dc: &mut DecContext, rounding: u32) -> u32 {
604  unsafe { decQuadToUInt32(dq, dc, rounding) }
605}
606
607/// Safe binding to *decQuadZero* function.
608pub fn dec_quad_zero(dq1: &mut DecQuad) {
609  unsafe {
610    decQuadZero(dq1);
611  }
612}