/rust/registry/src/index.crates.io-1949cf8c6b5b557f/lexical-util-1.0.7/src/mul.rs
Line | Count | Source |
1 | | //! Fast multiplication routines. |
2 | | |
3 | | use crate::num::{as_cast, UnsignedInteger}; |
4 | | |
5 | | /// Multiply two unsigned, integral values, and return the high and low product. |
6 | | /// |
7 | | /// The high product is the upper half of the product and the low product is the |
8 | | /// lower half. The `full` type is the full type size, while the `half` type is |
9 | | /// the type with exactly half the bits. |
10 | | #[inline(always)] |
11 | 0 | pub fn mul<Full, Half>(x: Full, y: Full) -> (Full, Full) |
12 | 0 | where |
13 | 0 | Full: UnsignedInteger, |
14 | 0 | Half: UnsignedInteger, |
15 | | { |
16 | | // Extract high-and-low masks. |
17 | 0 | let x1 = x >> Half::BITS as i32; |
18 | 0 | let x0 = x & as_cast(Half::MAX); |
19 | 0 | let y1 = y >> Half::BITS as i32; |
20 | 0 | let y0 = y & as_cast(Half::MAX); |
21 | | |
22 | 0 | let w0 = x0 * y0; |
23 | 0 | let tmp = (x1 * y0) + (w0 >> Half::BITS as i32); |
24 | 0 | let w1 = tmp & as_cast(Half::MAX); |
25 | 0 | let w2 = tmp >> Half::BITS as i32; |
26 | 0 | let w1 = w1 + x0 * y1; |
27 | 0 | let hi = (x1 * y1) + w2 + (w1 >> Half::BITS as i32); |
28 | 0 | let lo = x.wrapping_mul(y); |
29 | | |
30 | 0 | (hi, lo) |
31 | 0 | } |
32 | | |
33 | | /// Multiply two unsigned, integral values, and return the high product. |
34 | | /// |
35 | | /// The high product is the upper half of the product. The `full` type is the |
36 | | /// full type size, while the `half` type is the type with exactly half the |
37 | | /// bits. |
38 | | #[inline(always)] |
39 | 0 | pub fn mulhi<Full, Half>(x: Full, y: Full) -> Full |
40 | 0 | where |
41 | 0 | Full: UnsignedInteger, |
42 | 0 | Half: UnsignedInteger, |
43 | | { |
44 | | // Extract high-and-low masks. |
45 | 0 | let x1 = x >> Half::BITS as i32; |
46 | 0 | let x0 = x & as_cast(Half::MAX); |
47 | 0 | let y1 = y >> Half::BITS as i32; |
48 | 0 | let y0 = y & as_cast(Half::MAX); |
49 | | |
50 | 0 | let w0 = x0 * y0; |
51 | 0 | let m = (x0 * y1) + (w0 >> Half::BITS as i32); |
52 | 0 | let w1 = m & as_cast(Half::MAX); |
53 | 0 | let w2 = m >> Half::BITS as i32; |
54 | | |
55 | 0 | let w3 = (x1 * y0 + w1) >> Half::BITS as i32; |
56 | | |
57 | 0 | x1 * y1 + w2 + w3 |
58 | 0 | } |