1use 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
10pub const DEC_QUAD_BYTES: usize = 16;
12
13pub const DEC_QUAD_STRING: usize = 43;
15
16pub const DEC_QUAD_STRING_BUFFER: [c_char; DEC_QUAD_STRING] = [0; DEC_QUAD_STRING];
18
19pub 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
40pub 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
61pub 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
82pub 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
103pub 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
124pub 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
145pub 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
166pub 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#[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 fn default() -> Self {
200 DEC_QUAD_ZERO
201 }
202}
203
204impl Debug for DecQuad {
205 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
218pub 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
227pub 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
236pub 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
245pub 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
254pub 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
263pub 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
272pub 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
281pub 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
290pub 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
299pub 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
308pub 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
317pub 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
326pub fn dec_quad_digits(dq1: &DecQuad) -> c_uint {
328 let dq;
329 unsafe {
330 dq = decQuadDigits(dq1);
331 }
332 dq
333}
334
335pub 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
344pub 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
353pub 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
362pub 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
371pub 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
380pub 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
408pub 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
417pub 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
426pub 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
431pub fn dec_quad_get_exponent(x: &DecQuad) -> DecQuad {
433 unsafe { decQuadGetExponent(x) }
434}
435
436pub 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
445pub fn dec_quad_is_canonical(dn: &DecQuad) -> bool {
447 unsafe { decQuadIsCanonical(dn) == 1 }
448}
449
450pub fn dec_quad_is_finite(dn: &DecQuad) -> bool {
452 unsafe { decQuadIsFinite(dn) == 1 }
453}
454
455pub fn dec_quad_is_infinite(dn: &DecQuad) -> bool {
457 unsafe { decQuadIsInfinite(dn) == 1 }
458}
459
460pub fn dec_quad_is_integer(dn: &DecQuad) -> bool {
462 unsafe { decQuadIsInteger(dn) == 1 }
463}
464
465pub fn dec_quad_is_logical(dn: &DecQuad) -> bool {
467 unsafe { decQuadIsLogical(dn) == 1 }
468}
469
470pub fn dec_quad_is_nan(dn: &DecQuad) -> bool {
472 unsafe { decQuadIsNaN(dn) == 1 }
473}
474
475pub fn dec_quad_is_normal(dn: &DecQuad) -> bool {
477 unsafe { decQuadIsNormal(dn) == 1 }
478}
479
480pub fn dec_quad_is_negative(dn: &DecQuad) -> bool {
482 unsafe { decQuadIsNegative(dn) == 1 }
483}
484
485pub fn dec_quad_is_positive(dn: &DecQuad) -> bool {
487 unsafe { decQuadIsPositive(dn) == 1 }
488}
489
490pub fn dec_quad_is_signaling(dn: &DecQuad) -> bool {
492 unsafe { decQuadIsSignaling(dn) == 1 }
493}
494
495pub fn dec_quad_is_signalling(dn: &DecQuad) -> bool {
497 unsafe { decQuadIsSignalling(dn) == 1 }
498}
499
500pub fn dec_quad_is_zero(dn: &DecQuad) -> bool {
502 unsafe { decQuadIsZero(dn) == 1 }
503}
504
505pub 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
514pub 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
523pub 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
532pub 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
541pub 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
550pub 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
559pub 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
568pub 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
577pub fn dec_quad_to_int32(dq: &DecQuad, dc: &mut DecContext, rounding: u32) -> i32 {
579 unsafe { decQuadToInt32(dq, dc, rounding) }
580}
581
582pub 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
591pub 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
602pub fn dec_quad_to_uint32(dq: &DecQuad, dc: &mut DecContext, rounding: u32) -> u32 {
604 unsafe { decQuadToUInt32(dq, dc, rounding) }
605}
606
607pub fn dec_quad_zero(dq1: &mut DecQuad) {
609 unsafe {
610 decQuadZero(dq1);
611 }
612}