Coverage Report

Created: 2025-11-16 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.20/src/d2s_intrinsics.rs
Line
Count
Source
1
// Translated from C to Rust. The original C code can be found at
2
// https://github.com/ulfjack/ryu and carries the following license:
3
//
4
// Copyright 2018 Ulf Adams
5
//
6
// The contents of this file may be used under the terms of the Apache License,
7
// Version 2.0.
8
//
9
//    (See accompanying file LICENSE-Apache or copy at
10
//     http://www.apache.org/licenses/LICENSE-2.0)
11
//
12
// Alternatively, the contents of this file may be used under the terms of
13
// the Boost Software License, Version 1.0.
14
//    (See accompanying file LICENSE-Boost or copy at
15
//     https://www.boost.org/LICENSE_1_0.txt)
16
//
17
// Unless required by applicable law or agreed to in writing, this software
18
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
// KIND, either express or implied.
20
21
use core::ptr;
22
23
#[cfg_attr(feature = "no-panic", inline)]
24
3.72k
pub fn div5(x: u64) -> u64 {
25
3.72k
    x / 5
26
3.72k
}
27
28
#[cfg_attr(feature = "no-panic", inline)]
29
289k
pub fn div10(x: u64) -> u64 {
30
289k
    x / 10
31
289k
}
32
33
#[cfg_attr(feature = "no-panic", inline)]
34
22.7k
pub fn div100(x: u64) -> u64 {
35
22.7k
    x / 100
36
22.7k
}
37
38
#[cfg_attr(feature = "no-panic", inline)]
39
3.72k
pub(crate) fn pow5_factor(mut value: u64) -> u32 {
40
    const M_INV_5: u64 = 14757395258967641293; // 5 * m_inv_5 = 1 (mod 2^64)
41
    const N_DIV_5: u64 = 3689348814741910323; // #{ n | n = 0 (mod 2^64) } = 2^64 / 5
42
3.72k
    let mut count = 0u32;
43
    loop {
44
21.7k
        debug_assert!(value != 0);
45
21.7k
        value = value.wrapping_mul(M_INV_5);
46
21.7k
        if value > N_DIV_5 {
47
3.72k
            break;
48
18.0k
        }
49
18.0k
        count += 1;
50
    }
51
3.72k
    count
52
3.72k
}
53
54
// Returns true if value is divisible by 5^p.
55
#[cfg_attr(feature = "no-panic", inline)]
56
3.72k
pub fn multiple_of_power_of_5(value: u64, p: u32) -> bool {
57
    // I tried a case distinction on p, but there was no performance difference.
58
3.72k
    pow5_factor(value) >= p
59
3.72k
}
60
61
// Returns true if value is divisible by 2^p.
62
#[cfg_attr(feature = "no-panic", inline)]
63
4.61k
pub fn multiple_of_power_of_2(value: u64, p: u32) -> bool {
64
4.61k
    debug_assert!(value != 0);
65
4.61k
    debug_assert!(p < 64);
66
    // __builtin_ctzll doesn't appear to be faster here.
67
4.61k
    (value & ((1u64 << p) - 1)) == 0
68
4.61k
}
69
70
#[cfg_attr(feature = "no-panic", inline)]
71
34.5k
pub fn mul_shift_64(m: u64, mul: &(u64, u64), j: u32) -> u64 {
72
34.5k
    let b0 = m as u128 * mul.0 as u128;
73
34.5k
    let b2 = m as u128 * mul.1 as u128;
74
34.5k
    (((b0 >> 64) + b2) >> (j - 64)) as u64
75
34.5k
}
76
77
#[cfg_attr(feature = "no-panic", inline)]
78
11.5k
pub unsafe fn mul_shift_all_64(
79
11.5k
    m: u64,
80
11.5k
    mul: &(u64, u64),
81
11.5k
    j: u32,
82
11.5k
    vp: *mut u64,
83
11.5k
    vm: *mut u64,
84
11.5k
    mm_shift: u32,
85
11.5k
) -> u64 {
86
11.5k
    ptr::write(vp, mul_shift_64(4 * m + 2, mul, j));
87
11.5k
    ptr::write(vm, mul_shift_64(4 * m - 1 - mm_shift as u64, mul, j));
88
11.5k
    mul_shift_64(4 * m, mul, j)
89
11.5k
}