Coverage Report

Created: 2026-04-29 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/lexical-parse-float-1.0.6/src/shared.rs
Line
Count
Source
1
//! Shared utilities and algorithms.
2
3
#![doc(hidden)]
4
5
#[cfg(feature = "power-of-two")]
6
use lexical_util::format::NumberFormat;
7
use lexical_util::num::AsPrimitive;
8
9
use crate::float::{ExtendedFloat80, RawFloat};
10
use crate::mask::{lower_n_halfway, lower_n_mask};
11
12
// 8 DIGIT
13
// -------
14
15
/// Check if we can try to parse 8 digits at one.
16
#[cfg(not(feature = "compact"))]
17
macro_rules! can_try_parse_multidigit {
18
    ($iter:expr, $radix:expr) => {
19
        $iter.is_contiguous() && (cfg!(not(feature = "power-of-two")) || $radix <= 10)
20
    };
21
}
22
23
// POWER2
24
// ------
25
26
/// Calculate the shift to move the significant digits into place.
27
#[inline(always)]
28
0
pub fn calculate_shift<F: RawFloat>(power2: i32) -> i32 {
29
0
    let mantissa_shift = 64 - F::MANTISSA_SIZE - 1;
30
0
    if -power2 >= mantissa_shift {
31
0
        -power2 + 1
32
    } else {
33
0
        mantissa_shift
34
    }
35
0
}
36
37
/// Calculate the biased, binary exponent from the mantissa shift and exponent.
38
#[inline(always)]
39
#[cfg(feature = "power-of-two")]
40
pub fn calculate_power2<F: RawFloat, const FORMAT: u128>(exponent: i64, ctlz: u32) -> i32 {
41
    let format = NumberFormat::<{ FORMAT }> {};
42
    exponent as i32 * log2(format.exponent_base()) + F::EXPONENT_BIAS - ctlz as i32
43
}
44
45
/// Bias for marking an invalid extended float.
46
pub const INVALID_FP: i32 = i16::MIN as i32;
47
48
// LOG2
49
// ----
50
51
/// Quick log2 that evaluates at compile time for the radix.
52
/// Note that this may produce inaccurate results for other radixes:
53
/// we don't care since it's only called for powers-of-two.
54
#[inline(always)]
55
11.3k
pub const fn log2(radix: u32) -> i32 {
56
11.3k
    match radix {
57
0
        2 => 1,
58
0
        4 => 2,
59
0
        8 => 3,
60
0
        16 => 4,
61
0
        32 => 5,
62
        // Fallthrough to 1 for non-power-of-two radixes.
63
11.3k
        _ => 1,
64
    }
65
11.3k
}
66
67
// STARTS WITH
68
// -----------
69
70
/// Check if left iter starts with right iter.
71
///
72
/// This optimizes decently well, to the following ASM for pure slices:
73
///
74
/// ```text
75
/// starts_with_slc:
76
///         xor     eax, eax
77
/// .LBB0_1:
78
///         cmp     rcx, rax
79
///         je      .LBB0_2
80
///         cmp     rsi, rax
81
///         je      .LBB0_5
82
///         movzx   r8d, byte ptr [rdi + rax]
83
///         lea     r9, [rax + 1]
84
///         cmp     r8b, byte ptr [rdx + rax]
85
///         mov     rax, r9
86
///         je      .LBB0_1
87
/// .LBB0_5:
88
///         xor     eax, eax
89
///         ret
90
/// .LBB0_2:
91
///         mov     al, 1
92
///         ret
93
/// ```
94
#[cfg_attr(not(feature = "compact"), inline(always))]
95
0
pub fn starts_with<'a, 'b, Iter1, Iter2>(mut x: Iter1, mut y: Iter2) -> bool
96
0
where
97
0
    Iter1: Iterator<Item = &'a u8>,
98
0
    Iter2: Iterator<Item = &'b u8>,
99
{
100
    loop {
101
        // Only call `next()` on x if y is not None, otherwise,
102
        // we may incorrectly consume an x character.
103
0
        let yi = y.next();
104
0
        if yi.is_none() {
105
0
            return true;
106
0
        } else if x.next() != yi {
107
0
            return false;
108
0
        }
109
    }
110
0
}
111
112
/// Check if left iter starts with right iter without case-sensitivity.
113
///
114
/// This optimizes decently well, to the following ASM for pure slices:
115
///
116
/// ```text
117
/// starts_with_uncased:
118
///         xor     eax, eax
119
/// .LBB1_1:
120
///         cmp     rcx, rax
121
///         je      .LBB1_2
122
///         cmp     rsi, rax
123
///         je      .LBB1_5
124
///         movzx   r8d, byte ptr [rdi + rax]
125
///         xor     r8b, byte ptr [rdx + rax]
126
///         add     rax, 1
127
///         test    r8b, -33
128
///         je      .LBB1_1
129
/// .LBB1_5:
130
///         xor     eax, eax
131
///         ret
132
/// .LBB1_2:
133
///         mov     al, 1
134
///         ret
135
/// ```
136
#[cfg_attr(not(feature = "compact"), inline(always))]
137
#[allow(clippy::unwrap_used)] // reason="yi cannot be none due to previous check"
138
2.39k
pub fn starts_with_uncased<'a, 'b, Iter1, Iter2>(mut x: Iter1, mut y: Iter2) -> bool
139
2.39k
where
140
2.39k
    Iter1: Iterator<Item = &'a u8>,
141
2.39k
    Iter2: Iterator<Item = &'b u8>,
142
{
143
    // We use a faster optimization here for ASCII letters, which NaN
144
    // and infinite strings **must** be. [A-Z] is 0x41-0x5A, while
145
    // [a-z] is 0x61-0x7A. Therefore, the xor must be 0 or 32 if they
146
    // are case-insensitive equal, but only if at least 1 of the inputs
147
    // is an ASCII letter.
148
    loop {
149
2.57k
        let yi = y.next();
150
2.57k
        if yi.is_none() {
151
0
            return true;
152
2.57k
        }
153
2.57k
        let yi = *yi.unwrap();
154
2.57k
        let is_not_equal = x.next().map_or(true, |&xi| {
155
2.57k
            let xor = xi ^ yi;
156
2.57k
            xor != 0 && xor != 0x20
157
2.57k
        });
lexical_parse_float::shared::starts_with_uncased::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, core::slice::iter::Iter<u8>>::{closure#0}
Line
Count
Source
154
2.57k
        let is_not_equal = x.next().map_or(true, |&xi| {
155
2.57k
            let xor = xi ^ yi;
156
2.57k
            xor != 0 && xor != 0x20
157
2.57k
        });
Unexecuted instantiation: lexical_parse_float::shared::starts_with_uncased::<_, _>::{closure#0}
158
2.57k
        if is_not_equal {
159
2.39k
            return false;
160
177
        }
161
    }
162
2.39k
}
lexical_parse_float::shared::starts_with_uncased::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, core::slice::iter::Iter<u8>>
Line
Count
Source
138
2.39k
pub fn starts_with_uncased<'a, 'b, Iter1, Iter2>(mut x: Iter1, mut y: Iter2) -> bool
139
2.39k
where
140
2.39k
    Iter1: Iterator<Item = &'a u8>,
141
2.39k
    Iter2: Iterator<Item = &'b u8>,
142
{
143
    // We use a faster optimization here for ASCII letters, which NaN
144
    // and infinite strings **must** be. [A-Z] is 0x41-0x5A, while
145
    // [a-z] is 0x61-0x7A. Therefore, the xor must be 0 or 32 if they
146
    // are case-insensitive equal, but only if at least 1 of the inputs
147
    // is an ASCII letter.
148
    loop {
149
2.57k
        let yi = y.next();
150
2.57k
        if yi.is_none() {
151
0
            return true;
152
2.57k
        }
153
2.57k
        let yi = *yi.unwrap();
154
2.57k
        let is_not_equal = x.next().map_or(true, |&xi| {
155
            let xor = xi ^ yi;
156
            xor != 0 && xor != 0x20
157
        });
158
2.57k
        if is_not_equal {
159
2.39k
            return false;
160
177
        }
161
    }
162
2.39k
}
Unexecuted instantiation: lexical_parse_float::shared::starts_with_uncased::<_, _>
163
164
// ROUNDING
165
// --------
166
167
/// Round an extended-precision float to the nearest machine float.
168
///
169
/// Shifts the significant digits into place, adjusts the exponent,
170
/// so it can be easily converted to a native float.
171
#[cfg_attr(not(feature = "compact"), inline(always))]
172
851
pub fn round<F, Cb>(fp: &mut ExtendedFloat80, cb: Cb)
173
851
where
174
851
    F: RawFloat,
175
851
    Cb: Fn(&mut ExtendedFloat80, i32),
176
{
177
851
    let fp_inf = ExtendedFloat80 {
178
851
        mant: 0,
179
851
        exp: F::INFINITE_POWER,
180
851
    };
181
182
    // Calculate our shift in significant digits.
183
851
    let mantissa_shift = 64 - F::MANTISSA_SIZE - 1;
184
185
    // Check for a denormal float, if after the shift the exponent is negative.
186
851
    if -fp.exp >= mantissa_shift {
187
        // Have a denormal float that isn't a literal 0.
188
        // The extra 1 is to adjust for the denormal float, which is
189
        // `1 - F::EXPONENT_BIAS`. This works as before, because our
190
        // old logic rounded to `F::DENORMAL_EXPONENT` (now 1), and then
191
        // checked if `exp == F::DENORMAL_EXPONENT` and no hidden mask
192
        // bit was set. Here, we handle that here, rather than later.
193
        //
194
        // This might round-down to 0, but shift will be at **max** 65,
195
        // for halfway cases rounding towards 0.
196
0
        let shift = -fp.exp + 1;
197
0
        debug_assert!(shift <= 65);
198
0
        cb(fp, shift.min(64));
199
        // Check for round-up: if rounding-nearest carried us to the hidden bit.
200
0
        fp.exp = (fp.mant >= F::HIDDEN_BIT_MASK.as_u64()) as i32;
201
0
        return;
202
851
    }
203
204
    // The float is normal, round to the hidden bit.
205
851
    cb(fp, mantissa_shift);
206
207
    // Check if we carried, and if so, shift the bit to the hidden bit.
208
851
    let carry_mask = F::CARRY_MASK.as_u64();
209
851
    if fp.mant & carry_mask == carry_mask {
210
0
        fp.mant >>= 1;
211
0
        fp.exp += 1;
212
851
    }
213
214
    // Handle if we carried and check for overflow again.
215
851
    if fp.exp >= F::INFINITE_POWER {
216
        // Exponent is above largest normal value, must be infinite.
217
0
        *fp = fp_inf;
218
0
        return;
219
851
    }
220
221
    // Remove the hidden bit.
222
851
    fp.mant &= F::MANTISSA_MASK.as_u64();
223
851
}
lexical_parse_float::shared::round::<f64, lexical_parse_float::slow::negative_digit_comp<f64, 0xa0000000000000000000000000c>::{closure#0}>
Line
Count
Source
172
338
pub fn round<F, Cb>(fp: &mut ExtendedFloat80, cb: Cb)
173
338
where
174
338
    F: RawFloat,
175
338
    Cb: Fn(&mut ExtendedFloat80, i32),
176
{
177
338
    let fp_inf = ExtendedFloat80 {
178
338
        mant: 0,
179
338
        exp: F::INFINITE_POWER,
180
338
    };
181
182
    // Calculate our shift in significant digits.
183
338
    let mantissa_shift = 64 - F::MANTISSA_SIZE - 1;
184
185
    // Check for a denormal float, if after the shift the exponent is negative.
186
338
    if -fp.exp >= mantissa_shift {
187
        // Have a denormal float that isn't a literal 0.
188
        // The extra 1 is to adjust for the denormal float, which is
189
        // `1 - F::EXPONENT_BIAS`. This works as before, because our
190
        // old logic rounded to `F::DENORMAL_EXPONENT` (now 1), and then
191
        // checked if `exp == F::DENORMAL_EXPONENT` and no hidden mask
192
        // bit was set. Here, we handle that here, rather than later.
193
        //
194
        // This might round-down to 0, but shift will be at **max** 65,
195
        // for halfway cases rounding towards 0.
196
0
        let shift = -fp.exp + 1;
197
0
        debug_assert!(shift <= 65);
198
0
        cb(fp, shift.min(64));
199
        // Check for round-up: if rounding-nearest carried us to the hidden bit.
200
0
        fp.exp = (fp.mant >= F::HIDDEN_BIT_MASK.as_u64()) as i32;
201
0
        return;
202
338
    }
203
204
    // The float is normal, round to the hidden bit.
205
338
    cb(fp, mantissa_shift);
206
207
    // Check if we carried, and if so, shift the bit to the hidden bit.
208
338
    let carry_mask = F::CARRY_MASK.as_u64();
209
338
    if fp.mant & carry_mask == carry_mask {
210
0
        fp.mant >>= 1;
211
0
        fp.exp += 1;
212
338
    }
213
214
    // Handle if we carried and check for overflow again.
215
338
    if fp.exp >= F::INFINITE_POWER {
216
        // Exponent is above largest normal value, must be infinite.
217
0
        *fp = fp_inf;
218
0
        return;
219
338
    }
220
221
    // Remove the hidden bit.
222
338
    fp.mant &= F::MANTISSA_MASK.as_u64();
223
338
}
lexical_parse_float::shared::round::<f64, lexical_parse_float::slow::positive_digit_comp<f64, 0xa0000000000000000000000000c>::{closure#0}>
Line
Count
Source
172
175
pub fn round<F, Cb>(fp: &mut ExtendedFloat80, cb: Cb)
173
175
where
174
175
    F: RawFloat,
175
175
    Cb: Fn(&mut ExtendedFloat80, i32),
176
{
177
175
    let fp_inf = ExtendedFloat80 {
178
175
        mant: 0,
179
175
        exp: F::INFINITE_POWER,
180
175
    };
181
182
    // Calculate our shift in significant digits.
183
175
    let mantissa_shift = 64 - F::MANTISSA_SIZE - 1;
184
185
    // Check for a denormal float, if after the shift the exponent is negative.
186
175
    if -fp.exp >= mantissa_shift {
187
        // Have a denormal float that isn't a literal 0.
188
        // The extra 1 is to adjust for the denormal float, which is
189
        // `1 - F::EXPONENT_BIAS`. This works as before, because our
190
        // old logic rounded to `F::DENORMAL_EXPONENT` (now 1), and then
191
        // checked if `exp == F::DENORMAL_EXPONENT` and no hidden mask
192
        // bit was set. Here, we handle that here, rather than later.
193
        //
194
        // This might round-down to 0, but shift will be at **max** 65,
195
        // for halfway cases rounding towards 0.
196
0
        let shift = -fp.exp + 1;
197
0
        debug_assert!(shift <= 65);
198
0
        cb(fp, shift.min(64));
199
        // Check for round-up: if rounding-nearest carried us to the hidden bit.
200
0
        fp.exp = (fp.mant >= F::HIDDEN_BIT_MASK.as_u64()) as i32;
201
0
        return;
202
175
    }
203
204
    // The float is normal, round to the hidden bit.
205
175
    cb(fp, mantissa_shift);
206
207
    // Check if we carried, and if so, shift the bit to the hidden bit.
208
175
    let carry_mask = F::CARRY_MASK.as_u64();
209
175
    if fp.mant & carry_mask == carry_mask {
210
0
        fp.mant >>= 1;
211
0
        fp.exp += 1;
212
175
    }
213
214
    // Handle if we carried and check for overflow again.
215
175
    if fp.exp >= F::INFINITE_POWER {
216
        // Exponent is above largest normal value, must be infinite.
217
0
        *fp = fp_inf;
218
0
        return;
219
175
    }
220
221
    // Remove the hidden bit.
222
175
    fp.mant &= F::MANTISSA_MASK.as_u64();
223
175
}
lexical_parse_float::shared::round::<f64, lexical_parse_float::shared::round_down>
Line
Count
Source
172
338
pub fn round<F, Cb>(fp: &mut ExtendedFloat80, cb: Cb)
173
338
where
174
338
    F: RawFloat,
175
338
    Cb: Fn(&mut ExtendedFloat80, i32),
176
{
177
338
    let fp_inf = ExtendedFloat80 {
178
338
        mant: 0,
179
338
        exp: F::INFINITE_POWER,
180
338
    };
181
182
    // Calculate our shift in significant digits.
183
338
    let mantissa_shift = 64 - F::MANTISSA_SIZE - 1;
184
185
    // Check for a denormal float, if after the shift the exponent is negative.
186
338
    if -fp.exp >= mantissa_shift {
187
        // Have a denormal float that isn't a literal 0.
188
        // The extra 1 is to adjust for the denormal float, which is
189
        // `1 - F::EXPONENT_BIAS`. This works as before, because our
190
        // old logic rounded to `F::DENORMAL_EXPONENT` (now 1), and then
191
        // checked if `exp == F::DENORMAL_EXPONENT` and no hidden mask
192
        // bit was set. Here, we handle that here, rather than later.
193
        //
194
        // This might round-down to 0, but shift will be at **max** 65,
195
        // for halfway cases rounding towards 0.
196
0
        let shift = -fp.exp + 1;
197
0
        debug_assert!(shift <= 65);
198
0
        cb(fp, shift.min(64));
199
        // Check for round-up: if rounding-nearest carried us to the hidden bit.
200
0
        fp.exp = (fp.mant >= F::HIDDEN_BIT_MASK.as_u64()) as i32;
201
0
        return;
202
338
    }
203
204
    // The float is normal, round to the hidden bit.
205
338
    cb(fp, mantissa_shift);
206
207
    // Check if we carried, and if so, shift the bit to the hidden bit.
208
338
    let carry_mask = F::CARRY_MASK.as_u64();
209
338
    if fp.mant & carry_mask == carry_mask {
210
0
        fp.mant >>= 1;
211
0
        fp.exp += 1;
212
338
    }
213
214
    // Handle if we carried and check for overflow again.
215
338
    if fp.exp >= F::INFINITE_POWER {
216
        // Exponent is above largest normal value, must be infinite.
217
0
        *fp = fp_inf;
218
0
        return;
219
338
    }
220
221
    // Remove the hidden bit.
222
338
    fp.mant &= F::MANTISSA_MASK.as_u64();
223
338
}
Unexecuted instantiation: lexical_parse_float::shared::round::<_, _>
224
225
/// Shift right N-bytes and round towards a direction.
226
///
227
/// Callback should take the following parameters:
228
///     1. `is_odd`
229
///     1. `is_halfway`
230
///     1. `is_above`
231
#[cfg_attr(not(feature = "compact"), inline(always))]
232
513
pub fn round_nearest_tie_even<Cb>(fp: &mut ExtendedFloat80, shift: i32, cb: Cb)
233
513
where
234
513
    // `is_odd`, `is_halfway`, `is_above`
235
513
    Cb: Fn(bool, bool, bool) -> bool,
236
{
237
    // Ensure we've already handled denormal values that underflow.
238
513
    debug_assert!(shift <= 64);
239
240
    // Extract the truncated bits using mask.
241
    // Calculate if the value of the truncated bits are either above
242
    // the mid-way point, or equal to it.
243
    //
244
    // For example, for 4 truncated bytes, the mask would be 0b1111
245
    // and the midway point would be 0b1000.
246
513
    let mask = lower_n_mask(shift as u64);
247
513
    let halfway = lower_n_halfway(shift as u64);
248
513
    let truncated_bits = fp.mant & mask;
249
513
    let is_above = truncated_bits > halfway;
250
513
    let is_halfway = truncated_bits == halfway;
251
252
    // Bit shift so the leading bit is in the hidden bit.
253
    // This optimizes pretty well:
254
    //  ```text
255
    //   mov     ecx, esi
256
    //   shr     rdi, cl
257
    //   xor     eax, eax
258
    //   cmp     esi, 64
259
    //   cmovne  rax, rdi
260
    //   ret
261
    //  ```
262
513
    fp.mant = match shift == 64 {
263
0
        true => 0,
264
513
        false => fp.mant >> shift,
265
    };
266
513
    fp.exp += shift;
267
268
    // Extract the last bit after shifting (and determine if it is odd).
269
513
    let is_odd = fp.mant & 1 == 1;
270
271
    // Calculate if we need to roundup.
272
    // We need to roundup if we are above halfway, or if we are odd
273
    // and at half-way (need to tie-to-even). Avoid the branch here.
274
513
    fp.mant += cb(is_odd, is_halfway, is_above) as u64;
275
513
}
lexical_parse_float::shared::round_nearest_tie_even::<lexical_parse_float::slow::negative_digit_comp<f64, 0xa0000000000000000000000000c>::{closure#0}::{closure#0}>
Line
Count
Source
232
338
pub fn round_nearest_tie_even<Cb>(fp: &mut ExtendedFloat80, shift: i32, cb: Cb)
233
338
where
234
338
    // `is_odd`, `is_halfway`, `is_above`
235
338
    Cb: Fn(bool, bool, bool) -> bool,
236
{
237
    // Ensure we've already handled denormal values that underflow.
238
338
    debug_assert!(shift <= 64);
239
240
    // Extract the truncated bits using mask.
241
    // Calculate if the value of the truncated bits are either above
242
    // the mid-way point, or equal to it.
243
    //
244
    // For example, for 4 truncated bytes, the mask would be 0b1111
245
    // and the midway point would be 0b1000.
246
338
    let mask = lower_n_mask(shift as u64);
247
338
    let halfway = lower_n_halfway(shift as u64);
248
338
    let truncated_bits = fp.mant & mask;
249
338
    let is_above = truncated_bits > halfway;
250
338
    let is_halfway = truncated_bits == halfway;
251
252
    // Bit shift so the leading bit is in the hidden bit.
253
    // This optimizes pretty well:
254
    //  ```text
255
    //   mov     ecx, esi
256
    //   shr     rdi, cl
257
    //   xor     eax, eax
258
    //   cmp     esi, 64
259
    //   cmovne  rax, rdi
260
    //   ret
261
    //  ```
262
338
    fp.mant = match shift == 64 {
263
0
        true => 0,
264
338
        false => fp.mant >> shift,
265
    };
266
338
    fp.exp += shift;
267
268
    // Extract the last bit after shifting (and determine if it is odd).
269
338
    let is_odd = fp.mant & 1 == 1;
270
271
    // Calculate if we need to roundup.
272
    // We need to roundup if we are above halfway, or if we are odd
273
    // and at half-way (need to tie-to-even). Avoid the branch here.
274
338
    fp.mant += cb(is_odd, is_halfway, is_above) as u64;
275
338
}
lexical_parse_float::shared::round_nearest_tie_even::<lexical_parse_float::slow::positive_digit_comp<f64, 0xa0000000000000000000000000c>::{closure#0}::{closure#0}>
Line
Count
Source
232
175
pub fn round_nearest_tie_even<Cb>(fp: &mut ExtendedFloat80, shift: i32, cb: Cb)
233
175
where
234
175
    // `is_odd`, `is_halfway`, `is_above`
235
175
    Cb: Fn(bool, bool, bool) -> bool,
236
{
237
    // Ensure we've already handled denormal values that underflow.
238
175
    debug_assert!(shift <= 64);
239
240
    // Extract the truncated bits using mask.
241
    // Calculate if the value of the truncated bits are either above
242
    // the mid-way point, or equal to it.
243
    //
244
    // For example, for 4 truncated bytes, the mask would be 0b1111
245
    // and the midway point would be 0b1000.
246
175
    let mask = lower_n_mask(shift as u64);
247
175
    let halfway = lower_n_halfway(shift as u64);
248
175
    let truncated_bits = fp.mant & mask;
249
175
    let is_above = truncated_bits > halfway;
250
175
    let is_halfway = truncated_bits == halfway;
251
252
    // Bit shift so the leading bit is in the hidden bit.
253
    // This optimizes pretty well:
254
    //  ```text
255
    //   mov     ecx, esi
256
    //   shr     rdi, cl
257
    //   xor     eax, eax
258
    //   cmp     esi, 64
259
    //   cmovne  rax, rdi
260
    //   ret
261
    //  ```
262
175
    fp.mant = match shift == 64 {
263
0
        true => 0,
264
175
        false => fp.mant >> shift,
265
    };
266
175
    fp.exp += shift;
267
268
    // Extract the last bit after shifting (and determine if it is odd).
269
175
    let is_odd = fp.mant & 1 == 1;
270
271
    // Calculate if we need to roundup.
272
    // We need to roundup if we are above halfway, or if we are odd
273
    // and at half-way (need to tie-to-even). Avoid the branch here.
274
175
    fp.mant += cb(is_odd, is_halfway, is_above) as u64;
275
175
}
Unexecuted instantiation: lexical_parse_float::shared::round_nearest_tie_even::<_>
276
277
/// Round our significant digits into place, truncating them.
278
#[cfg_attr(not(feature = "compact"), inline(always))]
279
338
pub fn round_down(fp: &mut ExtendedFloat80, shift: i32) {
280
    // Might have a shift greater than 64 if we have an error.
281
338
    fp.mant = match shift == 64 {
282
0
        true => 0,
283
338
        false => fp.mant >> shift,
284
    };
285
338
    fp.exp += shift;
286
338
}