serde_json/lexical/
float.rs1use super::num::*;
6use super::rounding::*;
7use super::shift::*;
8
9#[doc(hidden)]
13#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ExtendedFloat { }
#[automatically_derived]
impl ::core::clone::Clone for ExtendedFloat {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u64>;
let _: ::core::clone::AssertParamIsClone<i32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ExtendedFloat { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for ExtendedFloat {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "ExtendedFloat",
"mant", &self.mant, "exp", &&self.exp)
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for ExtendedFloat { }
#[automatically_derived]
impl ::core::cmp::PartialEq for ExtendedFloat {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.mant == other.mant && self.exp == other.exp
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ExtendedFloat {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u64>;
let _: ::core::cmp::AssertParamIsEq<i32>;
}
}Eq)]
14pub(crate) struct ExtendedFloat {
15 pub mant: u64,
17 pub exp: i32,
19}
20
21impl ExtendedFloat {
22 pub(crate) fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat {
37 if true {
if !((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0)) {
::core::panicking::panic("assertion failed: (self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0)")
};
};debug_assert!((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0));
39
40 let ah = self.mant >> u64::HALF;
42 let al = self.mant & u64::LOMASK;
43 let bh = b.mant >> u64::HALF;
44 let bl = b.mant & u64::LOMASK;
45
46 let ah_bl = ah * bl;
48 let al_bh = al * bh;
49 let al_bl = al * bl;
50 let ah_bh = ah * bh;
51
52 let mut tmp = (ah_bl & u64::LOMASK) + (al_bh & u64::LOMASK) + (al_bl >> u64::HALF);
53 tmp += 1 << (u64::HALF - 1);
55
56 ExtendedFloat {
57 mant: ah_bh + (ah_bl >> u64::HALF) + (al_bh >> u64::HALF) + (tmp >> u64::HALF),
58 exp: self.exp + b.exp + u64::FULL,
59 }
60 }
61
62 #[inline]
66 pub(crate) fn imul(&mut self, b: &ExtendedFloat) {
67 *self = self.mul(b);
68 }
69
70 #[inline]
79 pub(crate) fn normalize(&mut self) -> u32 {
80 let shift = if self.mant == 0 {
94 0
95 } else {
96 self.mant.leading_zeros()
97 };
98 shl(self, shift as i32);
99 shift
100 }
101
102 #[inline]
106 pub(crate) fn round_to_native<F, Algorithm>(&mut self, algorithm: Algorithm)
107 where
108 F: Float,
109 Algorithm: FnOnce(&mut ExtendedFloat, i32),
110 {
111 round_to_native::<F, _>(self, algorithm);
112 }
113
114 #[inline]
118 pub fn from_float<F: Float>(f: F) -> ExtendedFloat {
119 from_float(f)
120 }
121
122 #[inline]
126 pub(crate) fn into_float<F: Float>(mut self) -> F {
127 self.round_to_native::<F, _>(round_nearest_tie_even);
128 into_float(self)
129 }
130
131 #[inline]
133 pub(crate) fn into_downward_float<F: Float>(mut self) -> F {
134 self.round_to_native::<F, _>(round_downward);
135 into_float(self)
136 }
137}
138
139#[inline]
143pub(crate) fn from_float<F>(f: F) -> ExtendedFloat
144where
145 F: Float,
146{
147 ExtendedFloat {
148 mant: u64::as_cast(f.mantissa()),
149 exp: f.exponent(),
150 }
151}
152
153#[inline]
160pub(crate) fn into_float<F>(fp: ExtendedFloat) -> F
161where
162 F: Float,
163{
164 if fp.mant == 0 || fp.exp < F::DENORMAL_EXPONENT {
166 F::ZERO
168 } else if fp.exp >= F::MAX_EXPONENT {
169 F::from_bits(F::INFINITY_BITS)
171 } else {
172 let exp: u64;
174 if (fp.exp == F::DENORMAL_EXPONENT) && (fp.mant & F::HIDDEN_BIT_MASK.as_u64()) == 0 {
175 exp = 0;
176 } else {
177 exp = (fp.exp + F::EXPONENT_BIAS) as u64;
178 }
179 let exp = exp << F::MANTISSA_SIZE;
180 let mant = fp.mant & F::MANTISSA_MASK.as_u64();
181 F::from_bits(F::Unsigned::as_cast(mant | exp))
182 }
183}