Coverage Report

Created: 2025-07-11 06:39

/rust/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.19/src/d2s_intrinsics.rs
Line
Count
Source (jump to first uncovered line)
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
0
pub fn div5(x: u64) -> u64 {
25
0
    x / 5
26
0
}
27
28
#[cfg_attr(feature = "no-panic", inline)]
29
0
pub fn div10(x: u64) -> u64 {
30
0
    x / 10
31
0
}
32
33
#[cfg_attr(feature = "no-panic", inline)]
34
0
pub fn div100(x: u64) -> u64 {
35
0
    x / 100
36
0
}
37
38
#[cfg_attr(feature = "no-panic", inline)]
39
0
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
0
    let mut count = 0u32;
43
    loop {
44
0
        debug_assert!(value != 0);
45
0
        value = value.wrapping_mul(M_INV_5);
46
0
        if value > N_DIV_5 {
47
0
            break;
48
0
        }
49
0
        count += 1;
50
    }
51
0
    count
52
0
}
53
54
// Returns true if value is divisible by 5^p.
55
#[cfg_attr(feature = "no-panic", inline)]
56
0
pub fn multiple_of_power_of_5(value: u64, p: u32) -> bool {
57
0
    // I tried a case distinction on p, but there was no performance difference.
58
0
    pow5_factor(value) >= p
59
0
}
60
61
// Returns true if value is divisible by 2^p.
62
#[cfg_attr(feature = "no-panic", inline)]
63
0
pub fn multiple_of_power_of_2(value: u64, p: u32) -> bool {
64
0
    debug_assert!(value != 0);
65
0
    debug_assert!(p < 64);
66
    // __builtin_ctzll doesn't appear to be faster here.
67
0
    (value & ((1u64 << p) - 1)) == 0
68
0
}
69
70
#[cfg_attr(feature = "no-panic", inline)]
71
0
pub fn mul_shift_64(m: u64, mul: &(u64, u64), j: u32) -> u64 {
72
0
    let b0 = m as u128 * mul.0 as u128;
73
0
    let b2 = m as u128 * mul.1 as u128;
74
0
    (((b0 >> 64) + b2) >> (j - 64)) as u64
75
0
}
76
77
#[cfg_attr(feature = "no-panic", inline)]
78
0
pub unsafe fn mul_shift_all_64(
79
0
    m: u64,
80
0
    mul: &(u64, u64),
81
0
    j: u32,
82
0
    vp: *mut u64,
83
0
    vm: *mut u64,
84
0
    mm_shift: u32,
85
0
) -> u64 {
86
0
    ptr::write(vp, mul_shift_64(4 * m + 2, mul, j));
87
0
    ptr::write(vm, mul_shift_64(4 * m - 1 - mm_shift as u64, mul, j));
88
0
    mul_shift_64(4 * m, mul, j)
89
0
}