| 2682 | } |
| 2683 | |
| 2684 | private void multiply64(long multiplier) { |
| 2685 | // Perform 256-bit × 64-bit multiplication |
| 2686 | // Result is at most 320 bits, but we keep only the lower 256 bits |
| 2687 | |
| 2688 | // Split this into eight 32-bit parts |
| 2689 | long a7 = hh >>> 32; |
| 2690 | long a6 = hh & 0xFFFFFFFFL; |
| 2691 | long a5 = hl >>> 32; |
| 2692 | long a4 = hl & 0xFFFFFFFFL; |
| 2693 | long a3 = lh >>> 32; |
| 2694 | long a2 = lh & 0xFFFFFFFFL; |
| 2695 | long a1 = ll >>> 32; |
| 2696 | long a0 = ll & 0xFFFFFFFFL; |
| 2697 | |
| 2698 | long b1 = multiplier >>> 32; |
| 2699 | long b0 = multiplier & 0xFFFFFFFFL; |
| 2700 | |
| 2701 | // Compute all partial products |
| 2702 | long p00 = a0 * b0; |
| 2703 | long p01 = a0 * b1; |
| 2704 | long p10 = a1 * b0; |
| 2705 | long p11 = a1 * b1; |
| 2706 | long p20 = a2 * b0; |
| 2707 | long p21 = a2 * b1; |
| 2708 | long p30 = a3 * b0; |
| 2709 | long p31 = a3 * b1; |
| 2710 | long p40 = a4 * b0; |
| 2711 | long p41 = a4 * b1; |
| 2712 | long p50 = a5 * b0; |
| 2713 | long p51 = a5 * b1; |
| 2714 | long p60 = a6 * b0; |
| 2715 | long p61 = a6 * b1; |
| 2716 | long p70 = a7 * b0; |
| 2717 | long p71 = a7 * b1; |
| 2718 | if (p71 != 0) { |
| 2719 | throw NumericException.instance().put("Overflow in multiplication (256-bit × 64-bit): product exceeds 256-bit capacity"); |
| 2720 | } |
| 2721 | |
| 2722 | // Gather results into 256-bit result |
| 2723 | long r0 = (p00 & 0xFFFFFFFFL); |
| 2724 | long r1 = (p00 >>> 32) + (p01 & 0xFFFFFFFFL) + (p10 & 0xFFFFFFFFL); |
| 2725 | long r2 = (r1 >>> 32) + (p01 >>> 32) + (p10 >>> 32) + |
| 2726 | (p11 & 0xFFFFFFFFL) + (p20 & 0xFFFFFFFFL); |
| 2727 | long r3 = (r2 >>> 32) + (p11 >>> 32) + (p20 >>> 32) + |
| 2728 | (p21 & 0xFFFFFFFFL) + (p30 & 0xFFFFFFFFL); |
| 2729 | long r4 = (r3 >>> 32) + (p21 >>> 32) + (p30 >>> 32) + |
| 2730 | (p31 & 0xFFFFFFFFL) + (p40 & 0xFFFFFFFFL); |
| 2731 | long r5 = (r4 >>> 32) + (p31 >>> 32) + (p40 >>> 32) + |
| 2732 | (p41 & 0xFFFFFFFFL) + (p50 & 0xFFFFFFFFL); |
| 2733 | long r6 = (r5 >>> 32) + (p41 >>> 32) + (p50 >>> 32) + |
| 2734 | (p51 & 0xFFFFFFFFL) + (p60 & 0xFFFFFFFFL); |
| 2735 | long r7 = (r6 >>> 32) + (p51 >>> 32) + (p60 >>> 32) + |
| 2736 | (p61 & 0xFFFFFFFFL) + (p70 & 0xFFFFFFFFL); |
| 2737 | long overflow = (r7 >>> 31) | (p61 >>> 32) | (p70 >>> 32); |
| 2738 | if (overflow != 0) { |
| 2739 | throw NumericException.instance().put("Overflow in multiplication (256-bit × 64-bit): product exceeds 256-bit capacity"); |
| 2740 | } |
| 2741 | |