1#![allow(non_camel_case_types)]
11
12use std::cmp::Ordering;
15use std::fmt::{Debug, Display, Formatter, LowerExp, UpperExp};
16use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign};
17use std::str::FromStr;
18use forward_ref::{forward_ref_binop, forward_ref_op_assign, forward_ref_unop};
19
20use crate::bid128_add::{bid128_add, bid128_sub};
21use crate::bid128_compare::*;
22use crate::bid128_div::bid128_div;
23use crate::bid128_fdim::bid128_fdim;
24use crate::bid128_fma::bid128_fma;
25use crate::bid128_fmod::bid128_fmod;
26use crate::bid128_frexp::bid128_frexp;
27use crate::bid128_ilogb::bid128_ilogb;
28use crate::bid128_ldexp::bid128_ldexp;
29use crate::bid128_llquantexp::bid128_llquantexp;
30use crate::bid128_llrint::bid128_llrint;
31use crate::bid128_llround::bid128_llround;
32use crate::bid128_logb::bid128_logb;
33use crate::bid128_lrint::bid128_lrint;
34use crate::bid128_lround::bid128_lround;
35use crate::bid128_minmax::{bid128_maxnum, bid128_maxnum_mag, bid128_minnum, bid128_minnum_mag};
36use crate::bid128_modf::bid128_modf;
37use crate::bid128_mul::bid128_mul;
38use crate::bid128_nearbyint::bid128_nearbyint;
39use crate::bid128_next::{bid128_nextafter, bid128_nextdown, bid128_nextup};
40use crate::bid128_nexttoward::bid128_nexttoward;
41use crate::bid128_noncomp::*;
42use crate::bid128_quantexp::bid128_quantexp;
43use crate::bid128_quantize::bid128_quantize;
44use crate::bid128_quantum::bid128_quantum;
45use crate::bid128_rem::bid128_rem;
46use crate::bid128_round_integral::*;
47use crate::bid128_scalbln::bid128_scalbln;
48use crate::bid128_scalbn::bid128_scalbn;
49use crate::bid128_sqrt::bid128_sqrt;
50use crate::bid128_string::{bid128_from_string, bid128_to_string};
51use crate::bid128_to_int32::*;
52use crate::bid128_to_int64::*;
53use crate::bid128_to_uint32::*;
54use crate::bid128_to_uint64::*;
55use crate::bid_binarydecimal::{binary32_to_bid128, binary64_to_bid128};
56use crate::bid_dpd::{bid_dpd_to_bid128, bid_to_dpd128};
57use crate::bid_from_int::{bid128_from_int32, bid128_from_int64, bid128_from_uint32, bid128_from_uint64};
58use crate::bid_internal::*;
59
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
62pub enum ClassTypes {
63 SignalingNaN,
65
66 QuietNaN,
68
69 NegativeInfinity,
71
72 NegativeNormal,
74
75 NegativeSubnormal,
77
78 NegativeZero,
80
81 PositiveZero,
83
84 PositiveSubnormal,
86
87 PositiveNormal,
89
90 PositiveInfinity
92}
93
94#[derive(Copy, Clone, Debug, PartialEq)]
96pub enum RoundingMode {
97 NearestEven = 0x00000,
99
100 Downward = 0x00001,
102
103 Upward = 0x00002,
105
106 TowardZero = 0x00003,
108
109 NearestAway = 0x00004
111}
112
113impl From<u32> for RoundingMode {
114 fn from(value: u32) -> Self {
115 match value {
116 0x00000 => RoundingMode::NearestEven,
117 0x00001 => RoundingMode::Downward,
118 0x00002 => RoundingMode::Upward,
119 0x00003 => RoundingMode::TowardZero,
120 0x00004 => RoundingMode::NearestAway,
121 _ => panic!("Unknown rounding mode")
122 }
123 }
124}
125
126pub const DEFAULT_ROUNDING_MODE: RoundingMode = RoundingMode::NearestEven;
127
128pub struct StatusFlags;
130
131pub type _IDEC_flags = u32;
133
134impl StatusFlags {
135 pub const BID_INEXACT_EXCEPTION: _IDEC_flags = DEC_FE_INEXACT;
136 pub const BID_UNDERFLOW_EXCEPTION: _IDEC_flags = DEC_FE_UNDERFLOW;
137 pub const BID_OVERFLOW_EXCEPTION: _IDEC_flags = DEC_FE_OVERFLOW;
138 pub const BID_ZERO_DIVIDE_EXCEPTION: _IDEC_flags = DEC_FE_DIVBYZERO;
139 pub const BID_DENORMAL_EXCEPTION: _IDEC_flags = DEC_FE_UNNORMAL;
140 pub const BID_INVALID_EXCEPTION: _IDEC_flags = DEC_FE_INVALID;
141 pub const BID_UNDERFLOW_INEXACT_EXCEPTION: _IDEC_flags = DEC_FE_UNDERFLOW | DEC_FE_INEXACT;
142 pub const BID_OVERFLOW_INEXACT_EXCEPTION: _IDEC_flags = DEC_FE_OVERFLOW | DEC_FE_INEXACT;
143 pub const BID_EXACT_STATUS:_IDEC_flags = 0x00000000;
144}
145
146#[derive(Copy, Clone)]
148#[repr(align(16))]
149pub struct d128 {
150 pub (crate) w: [BID_UINT64; 2]
151}
152
153pub const RADIX: i32 = 10;
155
156pub const MINUS_ONE: d128 = d128 { w: [0x0000000000000001u64, 0xb040000000000000u64] };
158
159pub const ZERO: d128 = d128 { w: [0x0000000000000000u64, 0x3040000000000000u64] };
161
162pub const ONE: d128 = d128 { w: [0x0000000000000001u64, 0x3040000000000000u64] };
164
165pub const NAN: d128 = d128 { w: [0x0000000000000000u64, 0x7c00000000000000u64] };
167
168pub const NEG_NAN: d128 = d128 { w: [0x0000000000000000u64, 0xFC00000000000000u64] };
170
171pub const SNAN: d128 = d128 { w: [0x0000000000000000u64, 0x7E00000000000000u64] };
173
174pub const NEG_SNAN: d128 = d128 { w: [0x0000000000000000u64, 0xFE00000000000000u64] };
176
177pub const INFINITY: d128 = d128 { w: [0x0000000000000000u64, 0x7800000000000000u64] };
179
180pub const NEGATIVE_INFINITY: d128 = d128 { w: [0x0000000000000000u64, 0xF800000000000000u64] };
182
183pub const MANTISSA_DIGITS: u32 = BID128_MAXDIGITS;
185
186pub const EPSILON: d128 = d128 { w: [0x1u64, 0x2FFE000000000000u64] };
188
189pub const MIN: d128 = d128 { w: [0x1u64, 0x42000000000000u64] };
191
192pub const MAX: d128 = d128 { w: [0x378D8E63FFFFFFFFu64, 0x5FFFED09BEAD87C0u64] };
194
195pub const MIN_EXP: i32 = -6142;
197
198pub const MAX_EXP: i32 = 6145;
200
201#[macro_export]
203macro_rules! dec128 {
204 ($t:tt) => {{
205 use std::str::FromStr;
206 $crate::d128::d128::from_str(stringify!($t)).expect("Invalid decimal number literal")
207 }}
208}
209
210impl Default for d128 {
211 #[must_use]
213 fn default() -> Self {
214 Self::new(0x3040000000000000u64, 0x0)
215 }
216}
217
218impl d128 {
219 #[must_use]
220 pub (crate) fn new(h: u64, l: u64) -> Self {
221 #[cfg(target_endian = "big")]
222 return Self { w: [h, l] };
223
224 Self { w: [l, h] }
225 }
226
227 pub fn encode_decimal(&self) -> Self {
230 bid_to_dpd128(self)
231 }
232
233 pub fn decode_decimal(&self) -> Self {
236 bid_dpd_to_bid128(self)
237 }
238
239 #[must_use]
241 pub fn abs(&self) -> Self {
242 bid128_abs(self)
243 }
244
245 #[must_use]
249 pub fn class(&self) -> ClassTypes {
250 bid128_class(self)
251 }
252
253 #[must_use]
255 pub fn copy(&self) -> Self { bid128_copy(self) }
256
257 #[must_use]
259 pub fn copy_sign(&self, other: &Self) -> Self { bid128_copy_sign(self, other) }
260
261 #[must_use]
263 pub fn is_canonical(&self) -> bool {
264 bid128_is_canonical(self)
265 }
266
267 #[must_use]
269 pub fn is_finite(&self) -> bool {
270 bid128_is_finite(self)
271 }
272
273 #[must_use]
275 pub fn is_infinite(&self) -> bool {
276 bid128_is_inf(self)
277 }
278
279 #[must_use]
281 pub fn is_nan(&self) -> bool {
282 bid128_is_nan(self)
283 }
284
285 #[must_use]
287 pub fn is_normal(&self) -> bool {
288 bid128_is_normal(self)
289 }
290
291 #[must_use]
293 pub fn is_signaling(&self) -> bool {
294 bid128_is_signaling(self)
295 }
296
297 #[must_use]
299 pub fn is_sign_minus(&self) -> bool {
300 bid128_is_signed(self)
301 }
302
303 #[must_use]
305 pub fn is_subnormal(&self) -> bool {
306 bid128_is_subnormal(self)
307 }
308
309 #[must_use]
311 pub fn is_zero(&self) -> bool {
312 bid128_is_zero(self)
313 }
314
315 #[must_use]
318 pub fn negate(x: &Self) -> Self {
319 bid128_negate(x)
320 }
321
322 #[must_use]
327 pub fn same_quantum(x: &Self, y: &Self) -> bool {
328 bid128_same_quantum(x, y)
329 }
330
331 #[must_use]
333 pub fn total_order(x: &Self, y: &Self) -> bool {
334 bid128_total_order(x, y)
335 }
336
337 #[must_use]
339 pub fn total_order_mag(x: &Self, y: &Self) -> bool {
340 bid128_total_order_mag(x, y)
341 }
342
343 #[must_use]
344 pub fn nan(tagp: &str, pfpsf: &mut _IDEC_flags) -> BID_UINT128 {
345 bid128_nan(tagp, pfpsf)
346 }
347
348 #[must_use]
351 pub fn convert_from_decimal_character(value: &str, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
352 bid128_from_string(value, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
353 }
354
355 #[must_use]
358 pub fn convert_from_f32(value: f32, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
359 binary32_to_bid128(value, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
360 }
361
362 #[must_use]
365 pub fn convert_from_f64(value: f64, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
366 binary64_to_bid128(value, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
367 }
368
369 #[must_use]
371 pub fn fdim(&self, rhs: &BID_UINT128, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
372 bid128_fdim(self, rhs, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
373 }
374
375 #[must_use]
377 pub fn fused_multiply_add(x: &Self, y: &Self, z: &Self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
378 bid128_fma(x, y, z, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
379 }
380
381 #[must_use]
383 pub fn fmod(&self, rhs: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> Self {
384 bid128_fmod(self, rhs, pfpsf)
385 }
386
387 #[must_use]
389 pub fn frexp(&self) -> (Self, i32) {
390 bid128_frexp(self)
391 }
392
393 #[must_use]
395 pub fn ldexp(&self, n: i32, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
396 bid128_ldexp(self, n, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
397 }
398
399 #[must_use]
401 pub fn llquantexp(&self, pfpsf: &mut _IDEC_flags) -> i64 {
402 bid128_llquantexp(self, pfpsf)
403 }
404
405 #[must_use]
408 pub fn logb(&self, pfpsf: &mut _IDEC_flags) -> Self {
409 bid128_logb(self, pfpsf)
410 }
411
412 #[must_use]
415 pub fn lrint(&self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> i64 {
416 bid128_lrint(self, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
417 }
418
419 #[must_use]
422 pub fn llrint(&self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> i64 {
423 bid128_llrint(self, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
424 }
425
426 #[must_use]
429 pub fn lround(&self, pfpsf: &mut _IDEC_flags) -> i64 {
430 bid128_lround(self, pfpsf)
431 }
432
433 #[must_use]
436 pub fn llround(&self, pfpsf: &mut _IDEC_flags) -> i64 {
437 bid128_llround(self, pfpsf)
438 }
439
440 #[must_use]
443 pub fn log_b(&self, pfpsf: &mut _IDEC_flags) -> i32 {
444 bid128_ilogb(self, pfpsf)
445 }
446
447 #[must_use]
451 pub fn max_num(x: &Self, y: &Self, pfpsf: &mut _IDEC_flags) -> Self {
452 bid128_maxnum(x, y, pfpsf)
453 }
454
455 #[must_use]
458 pub fn max_num_mag(x: &Self, y: &Self, pfpsf: &mut _IDEC_flags) -> Self {
459 bid128_maxnum_mag(x, y, pfpsf)
460 }
461
462 #[must_use]
466 pub fn min_num(x: &Self, y: &Self, pfpsf: &mut _IDEC_flags) -> Self {
467 bid128_minnum(x, y, pfpsf)
468 }
469
470 #[must_use]
473 pub fn min_num_mag(x: &Self, y: &Self, pfpsf: &mut _IDEC_flags) -> Self {
474 bid128_minnum_mag(x, y, pfpsf)
475 }
476
477 #[must_use]
479 pub fn modf(&self, pfpsf: &mut _IDEC_flags) -> (Self, Self) {
480 bid128_modf(self, pfpsf)
481 }
482
483 #[must_use]
485 pub fn nearbyint(&self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
486 bid128_nearbyint(self, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
487 }
488
489 #[must_use]
492 pub fn next_after(x: &Self, y:&Self, pfpsf: &mut _IDEC_flags) -> Self {
493 bid128_nextafter(x, y, pfpsf)
494 }
495
496 #[must_use]
499 pub fn next_down(&self, pfpsf: &mut _IDEC_flags) -> Self {
500 bid128_nextdown(self, pfpsf)
501 }
502
503 #[must_use]
505 pub fn next_toward(x: &Self, y: &Self, pfpsf: &mut _IDEC_flags) -> Self {
506 bid128_nexttoward(x, y, pfpsf)
507 }
508
509 #[must_use]
512 pub fn next_up(&self, pfpsf: &mut _IDEC_flags) -> Self {
513 bid128_nextup(self, pfpsf)
514 }
515
516 #[must_use]
518 pub fn quantexp(&self, pfpsf: &mut _IDEC_flags) -> i32 {
519 bid128_quantexp(self, pfpsf)
520 }
521
522 #[must_use]
534 pub fn quantize(x: &Self, y: &Self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
535 bid128_quantize(x, y, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
536 }
537
538 #[must_use]
541 pub fn quantum(&self) -> Self {
542 bid128_quantum(self)
543 }
544
545 #[allow(unused)]
546 #[must_use]
547 pub (crate) fn scale(&self) -> i32 {
548 let mut x_exp: BID_UINT64;
549 let mut exp: i32; #[cfg(target_endian = "big")]
552 let mut x = *x;
553
554 #[cfg(target_endian = "big")]
555 BID_SWAP128(&mut x);
556
557 if ((self.w[1] & MASK_COEFF) == 0x0u64) && (self.w[0] == 0x0u64) {
559 exp = (((self.w[1] & MASK_EXP) >> 49) - 6176) as i32;
560
561 if exp > (((0x5ffe) >> 1) - (6176)) {
562 exp = ((((self.w[1] << 2) & MASK_EXP) >> 49) as i32) - 6176;
563 }
564
565 exp
566 } else { x_exp = self.w[1] & MASK_EXP; if (self.w[1] & 0x6000000000000000u64) == 0x6000000000000000u64 {
571 x_exp = (self.w[1] << 2) & MASK_EXP; }
573
574 ((x_exp >> 49) - 6176) as i32
575 }
576 }
577
578 #[must_use]
580 pub fn scaleb(&self, n: i32, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
581 bid128_scalbn(self, n, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
582 }
583
584 #[must_use]
586 pub fn scalebln(&self, n: i64, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
587 bid128_scalbln(self, n, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
588 }
589
590 #[must_use]
592 pub fn square_root(&self, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> Self {
593 bid128_sqrt(self, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
594 }
595
596 #[must_use]
599 pub fn convert_to_i32_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> i32 {
600 bid128_to_int32_rnint(self, pfpsf)
601 }
602
603 #[must_use]
606 pub fn convert_to_i32_exact_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> i32 {
607 bid128_to_int32_xrnint(self, pfpsf)
608 }
609
610 #[must_use]
613 pub fn convert_to_i32_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> i32 {
614 bid128_to_int32_floor(self, pfpsf)
615 }
616
617 #[must_use]
620 pub fn convert_to_i32_exact_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> i32 {
621 bid128_to_int32_xfloor(self, pfpsf)
622 }
623
624 #[must_use]
627 pub fn convert_to_i32_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> i32 {
628 bid128_to_int32_ceil(self, pfpsf)
629 }
630
631 #[must_use]
634 pub fn convert_to_i32_exact_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> i32 {
635 bid128_to_int32_xceil(self, pfpsf)
636 }
637
638 #[must_use]
641 pub fn convert_to_i32_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> i32 {
642 bid128_to_int32_int(self, pfpsf)
643 }
644
645 #[must_use]
648 pub fn convert_to_i32_exact_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> i32 {
649 bid128_to_int32_xint(self, pfpsf)
650 }
651
652 #[must_use]
655 pub fn convert_to_i32_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> i32 {
656 bid128_to_int32_rninta(self, pfpsf)
657 }
658
659 #[must_use]
662 pub fn convert_to_i32_exact_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> i32 {
663 bid128_to_int32_xrninta(self, pfpsf)
664 }
665
666 #[must_use]
669 pub fn convert_to_i64_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> i64 {
670 bid128_to_int64_ceil(self, pfpsf)
671 }
672
673 #[must_use]
676 pub fn convert_to_i64_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> i64 {
677 bid128_to_int64_floor(self, pfpsf)
678 }
679
680 #[must_use]
683 pub fn convert_to_i64_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> i64 {
684 bid128_to_int64_int(self, pfpsf)
685 }
686
687 #[must_use]
690 pub fn convert_to_i64_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> i64 {
691 bid128_to_int64_rnint(self, pfpsf)
692 }
693
694 #[must_use]
697 pub fn convert_to_i64_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> i64 {
698 bid128_to_int64_rninta(self, pfpsf)
699 }
700
701 #[must_use]
704 pub fn convert_to_i64_exact_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> i64 {
705 bid128_to_int64_xceil(self, pfpsf)
706 }
707
708 #[must_use]
711 pub fn convert_to_i64_exact_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> i64 {
712 bid128_to_int64_xfloor(self, pfpsf)
713 }
714
715 #[must_use]
718 pub fn convert_to_i64_exact_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> i64 {
719 bid128_to_int64_xint(self, pfpsf)
720 }
721
722 #[must_use]
725 pub fn convert_to_i64_exact_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> i64 {
726 bid128_to_int64_xrnint(self, pfpsf)
727 }
728
729 #[must_use]
732 pub fn convert_to_i64_exact_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> i64 {
733 bid128_to_int64_xrninta(self, pfpsf)
734 }
735
736 #[must_use]
739 pub fn convert_to_u32_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> u32 {
740 bid128_to_uint32_ceil(self, pfpsf)
741 }
742
743 #[must_use]
746 pub fn convert_to_u32_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> u32 {
747 bid128_to_uint32_floor(self, pfpsf)
748 }
749
750 #[must_use]
753 pub fn convert_to_u32_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> u32 {
754 bid128_to_uint32_int(self, pfpsf)
755 }
756
757 #[must_use]
760 pub fn convert_to_u32_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> u32 {
761 bid128_to_uint32_rnint(self, pfpsf)
762 }
763
764 #[must_use]
767 pub fn convert_to_u32_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> u32 {
768 bid128_to_uint32_rninta(self, pfpsf)
769 }
770
771 #[must_use]
774 pub fn convert_to_u32_exact_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> u32 {
775 bid128_to_uint32_xceil(self, pfpsf)
776 }
777
778 #[must_use]
781 pub fn convert_to_u32_exact_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> u32 {
782 bid128_to_uint32_xfloor(self, pfpsf)
783 }
784
785 #[must_use]
788 pub fn convert_to_u32_exact_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> u32 {
789 bid128_to_uint32_xint(self, pfpsf)
790 }
791
792 #[must_use]
795 pub fn convert_to_u32_exact_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> u32 {
796 bid128_to_uint32_xrnint(self, pfpsf)
797 }
798
799 #[must_use]
802 pub fn convert_to_u32_exact_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> u32 {
803 bid128_to_uint32_xrninta(self, pfpsf)
804 }
805
806 #[must_use]
809 pub fn convert_to_u64_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> u64 {
810 bid128_to_uint64_ceil(self, pfpsf)
811 }
812
813 #[must_use]
816 pub fn convert_to_u64_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> u64 {
817 bid128_to_uint64_floor(self, pfpsf)
818 }
819
820 #[must_use]
823 pub fn convert_to_u64_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> u64 {
824 bid128_to_uint64_int(self, pfpsf)
825 }
826
827 #[must_use]
830 pub fn convert_to_u64_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> u64 {
831 bid128_to_uint64_rnint(self, pfpsf)
832 }
833
834 #[must_use]
837 pub fn convert_to_u64_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> u64 {
838 bid128_to_uint64_rninta(self, pfpsf)
839 }
840
841 #[must_use]
844 pub fn convert_to_u64_exact_toward_positive(&self, pfpsf: &mut _IDEC_flags) -> u64 {
845 bid128_to_uint64_xceil(self, pfpsf)
846 }
847
848 #[must_use]
851 pub fn convert_to_u64_exact_toward_negative(&self, pfpsf: &mut _IDEC_flags) -> u64 {
852 bid128_to_uint64_xfloor(self, pfpsf)
853 }
854
855 #[must_use]
858 pub fn convert_to_u64_exact_toward_zero(&self, pfpsf: &mut _IDEC_flags) -> u64 {
859 bid128_to_uint64_xint(self, pfpsf)
860 }
861
862 #[must_use]
865 pub fn convert_to_u64_exact_ties_to_even(&self, pfpsf: &mut _IDEC_flags) -> u64 {
866 bid128_to_uint64_xrnint(self, pfpsf)
867 }
868
869 #[must_use]
872 pub fn convert_to_u64_exact_ties_to_away(&self, pfpsf: &mut _IDEC_flags) -> u64 {
873 bid128_to_uint64_xrninta(self, pfpsf)
874 }
875
876 #[must_use]
878 pub fn addition(lhs: &Self, rhs: &Self, rnd_mode: Option<RoundingMode>, status: &mut _IDEC_flags) -> Self {
879 bid128_add(lhs, rhs, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), status)
880 }
881
882 #[must_use]
884 pub fn division(lhs: &Self, rhs: &Self, rnd_mode: Option<RoundingMode>, status: &mut _IDEC_flags) -> Self {
885 bid128_div(lhs, rhs, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), status)
886 }
887
888 #[must_use]
890 pub fn multiplication(lhs: &Self, rhs: &Self, rnd_mode: Option<RoundingMode>, status: &mut _IDEC_flags) -> Self {
891 bid128_mul(lhs, rhs, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), status)
892 }
893
894 #[must_use]
896 pub fn remainder(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> Self {
897 bid128_rem(lhs, rhs, status)
898 }
899
900 #[must_use]
902 pub fn subtraction(lhs: &Self, rhs: &Self, rnd_mode: Option<RoundingMode>, status: &mut _IDEC_flags) -> Self {
903 bid128_sub(lhs, rhs, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), status)
904 }
905
906 #[must_use]
909 pub fn compare_quiet_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
910 bid128_quiet_equal(lhs, rhs, status)
911 }
912
913 #[must_use]
916 pub fn compare_quiet_greater(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
917 bid128_quiet_greater(lhs, rhs, status)
918 }
919
920 #[must_use]
923 pub fn compare_quiet_unordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
924 bid128_quiet_unordered(lhs, rhs, status)
925 }
926
927 #[must_use]
930 pub fn compare_quiet_ordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
931 bid128_quiet_ordered(lhs, rhs, status)
932 }
933
934 #[must_use]
937 pub fn compare_quiet_greater_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
938 bid128_quiet_greater_equal(lhs, rhs, status)
939 }
940
941 #[must_use]
944 pub fn compare_quiet_greater_unordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
945 bid128_quiet_greater_unordered(lhs, rhs, status)
946 }
947
948 #[must_use]
951 pub fn compare_quiet_less(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
952 bid128_quiet_less(lhs, rhs, status)
953 }
954
955 #[must_use]
958 pub fn compare_quiet_less_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
959 bid128_quiet_less_equal(lhs, rhs, status)
960 }
961
962 #[must_use]
965 pub fn compare_quiet_less_unordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
966 bid128_quiet_less_unordered(lhs, rhs, status)
967 }
968
969 #[must_use]
972 pub fn compare_quiet_not_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
973 bid128_quiet_not_equal(lhs, rhs, status)
974 }
975
976 #[must_use]
979 pub fn compare_quiet_not_greater(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
980 bid128_quiet_not_greater(lhs, rhs, status)
981 }
982
983 #[must_use]
986 pub fn compare_quiet_not_less(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
987 bid128_quiet_not_less(lhs, rhs, status)
988 }
989
990 #[must_use]
993 pub fn compare_signaling_greater(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
994 bid128_signaling_greater(lhs, rhs, status)
995 }
996
997 #[must_use]
1000 pub fn compare_signaling_greater_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1001 bid128_signaling_greater_equal(lhs, rhs, status)
1002 }
1003
1004 #[must_use]
1007 pub fn compare_signaling_greater_unordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1008 bid128_signaling_greater_unordered(lhs, rhs, status)
1009 }
1010
1011 #[must_use]
1014 pub fn compare_signaling_less(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1015 bid128_signaling_less(lhs, rhs, status)
1016 }
1017
1018 #[must_use]
1021 pub fn compare_signaling_less_equal(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1022 bid128_signaling_less_equal(lhs, rhs, status)
1023 }
1024
1025 #[must_use]
1028 pub fn compare_signaling_less_unordered(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1029 bid128_signaling_less_unordered(lhs, rhs, status)
1030 }
1031
1032 #[must_use]
1035 pub fn compare_signaling_not_greater(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1036 bid128_signaling_not_greater(lhs, rhs, status)
1037 }
1038
1039 #[must_use]
1042 pub fn compare_signaling_not_less(lhs: &Self, rhs: &Self, status: &mut _IDEC_flags) -> bool {
1043 bid128_signaling_not_less(lhs, rhs, status)
1044 }
1045
1046 #[must_use]
1050 pub fn round_to_integral_exact(x: &BID_UINT128, rnd_mode: Option<RoundingMode>, pfpsf: &mut _IDEC_flags) -> d128 {
1051 bid128_round_integral_exact(x, rnd_mode.unwrap_or(DEFAULT_ROUNDING_MODE), pfpsf)
1052 }
1053
1054 #[must_use]
1058 pub fn round_to_integral_ties_to_away(x: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> d128 {
1059 bid128_round_integral_nearest_away(x, pfpsf)
1060 }
1061
1062 #[must_use]
1066 pub fn round_to_integral_ties_to_even(x: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> d128 {
1067 bid128_round_integral_nearest_even(x, pfpsf)
1068 }
1069
1070 #[must_use]
1074 pub fn round_to_integral_ties_toward_negative(x: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> d128 {
1075 bid128_round_integral_negative(x, pfpsf)
1076 }
1077
1078 #[must_use]
1082 pub fn round_to_integral_ties_toward_positive(x: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> d128 {
1083 bid128_round_integral_positive(x, pfpsf)
1084 }
1085
1086 #[must_use]
1090 pub fn round_to_integral_ties_toward_zero(x: &BID_UINT128, pfpsf: &mut _IDEC_flags) -> d128 {
1091 bid128_round_integral_zero(x, pfpsf)
1092 }
1093}
1094
1095impl Eq for d128 { }
1096
1097impl PartialEq for d128 {
1098 fn eq(&self, other: &Self) -> bool {
1099 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1100 let s_nan: bool = self.is_nan();
1101 let o_nan: bool = other.is_nan();
1102
1103 if s_nan && o_nan {
1104 bid128_quiet_unordered(self, other, &mut status)
1105 } else if s_nan || o_nan {
1106 bid128_quiet_ordered(self, other, &mut status)
1107 } else {
1108 bid128_quiet_equal(self, other, &mut status)
1109 }
1110 }
1111}
1112
1113impl PartialOrd for d128 {
1114 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1115 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1116 let equal: bool = self.eq(other);
1117 if equal {
1118 return Some(Ordering::Equal)
1119 }
1120 let less = bid128_quiet_less(self, other, &mut status);
1121 if less {
1122 return Some(Ordering::Less);
1123 }
1124 let greater = bid128_quiet_greater(self, other, &mut status);
1125 if greater {
1126 return Some(Ordering::Greater);
1127 }
1128 None
1129 }
1130
1131 fn lt(&self, other: &Self) -> bool {
1132 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1133 bid128_quiet_less(self, other, &mut status)
1134 }
1135
1136 fn le(&self, other: &Self) -> bool {
1137 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1138 bid128_quiet_less_equal(self, other, &mut status)
1139 }
1140
1141 fn gt(&self, other: &Self) -> bool {
1142 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1143 bid128_quiet_greater(self, other, &mut status)
1144 }
1145
1146 fn ge(&self, other: &Self) -> bool {
1147 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1148 bid128_quiet_greater_equal(self, other, &mut status)
1149 }
1150}
1151
1152impl Debug for d128 {
1153 fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
1154 bid128_to_string(self, fmt, true)
1155 }
1156}
1157
1158impl Display for d128 {
1159 fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
1160 bid128_to_string(self, fmt, true)
1161 }
1162}
1163
1164impl LowerExp for d128 {
1165 fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
1166 bid128_to_string(self, fmt, false)
1167 }
1168}
1169
1170impl UpperExp for d128 {
1171 fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
1172 bid128_to_string(self, fmt, true)
1173 }
1174}
1175
1176impl FromStr for d128 {
1177 type Err = u32;
1178
1179 fn from_str(s: &str) -> Result<Self, Self::Err> {
1187 let mut status: _IDEC_flags = 0;
1188 let dec: BID_UINT128 = bid128_from_string(s, DEFAULT_ROUNDING_MODE, &mut status);
1189
1190 match status {
1191 StatusFlags::BID_EXACT_STATUS | StatusFlags::BID_INEXACT_EXCEPTION => Ok(dec),
1192 _ => Err(status)
1193 }
1194 }
1195}
1196
1197impl From<f32> for d128 {
1198 fn from(value: f32) -> Self {
1206 let mut status: _IDEC_flags = 0;
1207 binary32_to_bid128(value, DEFAULT_ROUNDING_MODE, &mut status)
1208 }
1209}
1210
1211impl From<f64> for d128 {
1212 fn from(value: f64) -> Self {
1220 let mut status: _IDEC_flags = 0;
1221 binary64_to_bid128(value, DEFAULT_ROUNDING_MODE, &mut status)
1222 }
1223}
1224
1225impl From<i32> for d128 {
1226 fn from(value: i32) -> Self {
1234 bid128_from_int32(value)
1235 }
1236}
1237
1238impl From<u32> for d128 {
1239 fn from(value: u32) -> Self {
1247 bid128_from_uint32(value)
1248 }
1249}
1250
1251impl From<i64> for d128 {
1252 fn from(value: i64) -> Self {
1260 bid128_from_int64(value)
1261 }
1262}
1263
1264impl From<u64> for d128 {
1265 fn from(value: u64) -> Self {
1273 bid128_from_uint64(value)
1274 }
1275}
1276
1277impl From<u128> for d128 {
1278 fn from(value: u128) -> Self {
1285 Self::new((value >> 64) as u64, value as u64)
1286 }
1287}
1288
1289impl From<&str> for d128 {
1290 fn from(value: &str) -> Self {
1291 let mut status: _IDEC_flags = StatusFlags::BID_EXACT_STATUS;
1292 bid128_from_string(value, DEFAULT_ROUNDING_MODE, &mut status)
1293 }
1294}
1295
1296impl Neg for d128 {
1297 type Output = Self;
1298
1299 fn neg(self) -> Self::Output {
1309 bid128_negate(&self)
1310 }
1311}
1312
1313forward_ref_unop! { impl Neg, neg for d128 }
1314
1315impl Add for d128 {
1316 type Output = Self;
1317
1318 fn add(self, rhs: Self) -> Self::Output {
1327 let mut status: _IDEC_flags = 0;
1328 bid128_add(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
1329 }
1330}
1331
1332forward_ref_binop!(impl Add, add for d128, d128);
1333
1334impl AddAssign for d128 {
1335 fn add_assign(&mut self, rhs: Self) {
1345 let mut status: _IDEC_flags = 0;
1346 let dec: BID_UINT128 = bid128_add(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);
1347
1348 self.w[0] = dec.w[0];
1349 self.w[1] = dec.w[1];
1350 }
1351}
1352
1353forward_ref_op_assign! { impl AddAssign, add_assign for d128, d128 }
1354
1355impl Div for d128 {
1356 type Output = Self;
1357
1358 fn div(self, rhs: Self) -> Self::Output {
1367 let mut status: _IDEC_flags = 0;
1368 bid128_div(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
1369 }
1370}
1371
1372forward_ref_binop!(impl Div, div for d128, d128);
1373
1374impl DivAssign for d128 {
1375 fn div_assign(&mut self, rhs: Self) {
1385 let mut status: _IDEC_flags = 0;
1386 let dec: BID_UINT128 = bid128_div(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);
1387
1388 self.w[0] = dec.w[0];
1389 self.w[1] = dec.w[1];
1390 }
1391}
1392
1393forward_ref_op_assign! { impl DivAssign, div_assign for d128, d128 }
1394
1395impl Mul for d128 {
1396 type Output = Self;
1397
1398 fn mul(self, rhs: Self) -> Self::Output {
1407 let mut status: _IDEC_flags = 0;
1408 bid128_mul(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
1409 }
1410}
1411
1412forward_ref_binop!(impl Mul, mul for d128, d128);
1413
1414impl MulAssign for d128 {
1415 fn mul_assign(&mut self, rhs: Self) {
1425 let mut status: _IDEC_flags = 0;
1426 let dec: BID_UINT128 = bid128_mul(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);
1427
1428 self.w[0] = dec.w[0];
1429 self.w[1] = dec.w[1];
1430 }
1431}
1432
1433forward_ref_op_assign! { impl MulAssign, mul_assign for d128, d128 }
1434
1435impl Rem for d128 {
1436 type Output = Self;
1437
1438 fn rem(self, rhs: Self) -> Self::Output {
1447 let mut status: _IDEC_flags = 0;
1448 bid128_rem(&self, &rhs, &mut status)
1449 }
1450}
1451
1452forward_ref_binop!(impl Rem, rem for d128, d128);
1453
1454impl RemAssign for d128 {
1455 fn rem_assign(&mut self, rhs: Self) {
1465 let mut status: _IDEC_flags = 0;
1466 let dec: BID_UINT128 = bid128_rem(self, &rhs, &mut status);
1467
1468 self.w[0] = dec.w[0];
1469 self.w[1] = dec.w[1];
1470 }
1471}
1472
1473forward_ref_op_assign! { impl RemAssign, rem_assign for d128, d128 }
1474
1475impl Sub for d128 {
1476 type Output = Self;
1477
1478 fn sub(self, rhs: Self) -> Self::Output {
1487 let mut status: _IDEC_flags = 0;
1488 bid128_sub(&self, &rhs, DEFAULT_ROUNDING_MODE, &mut status)
1489 }
1490}
1491
1492forward_ref_binop!(impl Sub, sub for d128, d128);
1493
1494impl SubAssign for d128 {
1495 fn sub_assign(&mut self, rhs: Self) {
1505 let mut status: _IDEC_flags = 0;
1506 let dec: BID_UINT128 = bid128_sub(self, &rhs, DEFAULT_ROUNDING_MODE, &mut status);
1507
1508 self.w[0] = dec.w[0];
1509 self.w[1] = dec.w[1];
1510 }
1511}
1512
1513forward_ref_op_assign! { impl SubAssign, sub_assign for d128, d128 }
1514
1515impl std::iter::Sum for d128 {
1516 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1517 iter.fold(ZERO, |a, b| a + b)
1518 }
1519}
1520
1521impl std::iter::Product for d128 {
1522 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1523 iter.fold(ONE, |a, b| a * b)
1524 }
1525}
1526
1527impl<'a> std::iter::Sum<&'a d128> for d128 {
1528 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
1529 iter.fold(ZERO, |a, b| a + b)
1530 }
1531}
1532
1533impl<'a> std::iter::Product<&'a d128> for d128 {
1534 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
1535 iter.fold(ONE, |a, b| a * b)
1536 }
1537}
1538
1539impl std::hash::Hash for d128 {
1540 #[inline]
1549 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1550 state.write_u64(self.w[0]);
1551 state.write_u64(self.w[1]);
1552 }
1553
1554 #[inline]
1564 fn hash_slice<H: std::hash::Hasher>(data: &[d128], state: &mut H) {
1565 let newlen: usize = std::mem::size_of_val(data);
1566 let ptr: *const u8 = data.as_ptr() as *const u8;
1567 state.write(unsafe { std::slice::from_raw_parts(ptr, newlen) })
1568 }
1569}