| 2003 | } |
| 2004 | |
| 2005 | private void multiply128(long h, long l) { |
| 2006 | // Perform 256-bit × 128-bit multiplication |
| 2007 | // Result is at most 384 bits, but we keep only the lower 256 bits |
| 2008 | |
| 2009 | // Split this into eight 32-bit parts |
| 2010 | long a7 = hh >>> 32; |
| 2011 | long a6 = hh & 0xFFFFFFFFL; |
| 2012 | long a5 = hl >>> 32; |
| 2013 | long a4 = hl & 0xFFFFFFFFL; |
| 2014 | long a3 = lh >>> 32; |
| 2015 | long a2 = lh & 0xFFFFFFFFL; |
| 2016 | long a1 = ll >>> 32; |
| 2017 | long a0 = ll & 0xFFFFFFFFL; |
| 2018 | |
| 2019 | long b3 = h >>> 32; |
| 2020 | long b2 = h & 0xFFFFFFFFL; |
| 2021 | long b1 = l >>> 32; |
| 2022 | long b0 = l & 0xFFFFFFFFL; |
| 2023 | |
| 2024 | // Compute all partial products |
| 2025 | long p00 = a0 * b0; |
| 2026 | long p01 = a0 * b1; |
| 2027 | long p02 = a0 * b2; |
| 2028 | long p03 = a0 * b3; |
| 2029 | long p10 = a1 * b0; |
| 2030 | long p11 = a1 * b1; |
| 2031 | long p12 = a1 * b2; |
| 2032 | long p13 = a1 * b3; |
| 2033 | long p20 = a2 * b0; |
| 2034 | long p21 = a2 * b1; |
| 2035 | long p22 = a2 * b2; |
| 2036 | long p23 = a2 * b3; |
| 2037 | long p30 = a3 * b0; |
| 2038 | long p31 = a3 * b1; |
| 2039 | long p32 = a3 * b2; |
| 2040 | long p33 = a3 * b3; |
| 2041 | long p40 = a4 * b0; |
| 2042 | long p41 = a4 * b1; |
| 2043 | long p42 = a4 * b2; |
| 2044 | long p43 = a4 * b3; |
| 2045 | long p50 = a5 * b0; |
| 2046 | long p51 = a5 * b1; |
| 2047 | long p52 = a5 * b2; |
| 2048 | long p53 = a5 * b3; |
| 2049 | long p60 = a6 * b0; |
| 2050 | long p61 = a6 * b1; |
| 2051 | long p62 = a6 * b2; |
| 2052 | long p63 = a6 * b3; |
| 2053 | long p70 = a7 * b0; |
| 2054 | long p71 = a7 * b1; |
| 2055 | long p72 = a7 * b2; |
| 2056 | long p73 = a7 * b3; |
| 2057 | |
| 2058 | long overflow = p53 | p62 | p63 | p71 | p72 | p73; |
| 2059 | if (overflow != 0) { |
| 2060 | throw NumericException.instance().put("Overflow in multiplication (128-bit × 128-bit): product exceeds 256-bit capacity"); |
| 2061 | } |
| 2062 | |