public static long get_BID64_UF()

in java/dfp/src/main/java/com/epam/deltix/dfp/JavaImplParse.java [733:872]


    public static long get_BID64_UF(final long sgn, final int expon, long coeff, final long R, int rmode, final FloatingPointStatusFlag fpsc) {
        long C128_w0, C128_w1, Q_low_w0, Q_low_w1, Stemp_w0, Stemp_w1;
        long _C64, remainder_h, QH, carry;
        int extra_digits, amount, amount2;
        int status;

        // underflow
        if (expon + MAX_FORMAT_DIGITS < 0) {
            __set_status_flags(fpsc, BID_UNDERFLOW_EXCEPTION | BID_INEXACT_EXCEPTION);
            if (rmode == BID_ROUNDING_DOWN && sgn != 0)
                return 0x8000000000000001L;
            if (rmode == BID_ROUNDING_UP && sgn == 0)
                return 1L;
            // result is 0
            return sgn;
        }
        // 10*coeff
        coeff = (coeff << 3) + (coeff << 1);
        if (sgn != 0 && (rmode == BID_ROUNDING_DOWN || rmode == BID_ROUNDING_UP) /*(uint)(rmode - 1) < 2*/)
            rmode = 3 - rmode;
        if (R != 0)
            coeff |= 1;
        // get digits to be shifted out
        extra_digits = 1 - expon;
        C128_w0 = coeff + bid_round_const_table[rmode][extra_digits];

        // get coeff*(2^M[extra_digits])/10^extra_digits
        //__mul_64x128_full(out QH, out Q_low, C128.w0, bid_reciprocals10_128_flat[extra_digits << 1], bid_reciprocals10_128_flat[(extra_digits << 1) + 1]);
        //public static void __mul_64x128_full(/*out*/ long Ph, /*out*/ final BID_UINT128 Ql, final long A, final long B_w0, final long B_w1)
        {
            final long _B_w0 = bid_reciprocals10_128_BID_UINT128[extra_digits << 1];
            final long _B_w1 = bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1];

            long _ALBL_w0, _ALBL_w1, _ALBH_w0, _ALBH_w1, _QM2_w0, _QM2_w1;

            //__mul_64x64_to_128(out ALBH, A, B.w1);
            _ALBH_w1 = Mul64Impl.unsignedMultiplyHigh(C128_w0, _B_w1);
            _ALBH_w0 = C128_w0 * _B_w1;
            //__mul_64x64_to_128(out ALBL, A, B.w0);
            _ALBL_w1 = Mul64Impl.unsignedMultiplyHigh(C128_w0, _B_w0);
            _ALBL_w0 = C128_w0 * _B_w0;

            Q_low_w0 = _ALBL_w0;
            //__add_128_64(out QM2, ALBH, ALBL.w1);
            {
                long R64H;
                R64H = _ALBH_w1;
                _QM2_w0 = (_ALBL_w1) + _ALBH_w0;
                if ((UnsignedLong.isLess(_QM2_w0, _ALBL_w1)))
                    R64H++;
                _QM2_w1 = R64H;
            }
            Q_low_w1 = _QM2_w0;
            QH = _QM2_w1;
        }

        // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
        amount = bid_recip_scale[extra_digits];

        _C64 = QH >>> amount;
        //__shr_128(C128, Q_high, amount);

        if (rmode == 0) //BID_ROUNDING_TO_NEAREST
            if ((_C64 & 1) != 0) {
                // check whether fractional part of initial_P/10^extra_digits is exactly .5

                // get remainder
                amount2 = 64 - amount;
                remainder_h = 0;
                remainder_h--;
                remainder_h >>>= amount2;
                remainder_h = remainder_h & QH;

                if (remainder_h == 0
                    && ((UnsignedLong.isLess(Q_low_w1, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]))
                    || (Q_low_w1 == bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]
                    && (UnsignedLong.isLess(Q_low_w0, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) /*+ 0*/]))))) {
                    _C64--;
                }
            }


        if (is_inexact(fpsc))
            __set_status_flags(fpsc, BID_UNDERFLOW_EXCEPTION);
        else {
            status = BID_INEXACT_EXCEPTION;
            // get remainder
            remainder_h = QH << (64 - amount);

            switch (rmode) {
                case BID_ROUNDING_TO_NEAREST:
                case BID_ROUNDING_TIES_AWAY:
                    // test whether fractional part is 0
                    if (remainder_h == 0x8000000000000000L
                        && ((UnsignedLong.isLess(Q_low_w1, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]))
                        || (Q_low_w1 == bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]
                        && (UnsignedLong.isLess(Q_low_w0, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) /*+ 0*/])))))
                        status = BID_EXACT_STATUS;
                    break;
                case BID_ROUNDING_DOWN:
                case BID_ROUNDING_TO_ZERO:
                    if (remainder_h == 0
                        && ((UnsignedLong.isLess(Q_low_w1, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]))
                        || (Q_low_w1 == bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1]
                        && (UnsignedLong.isLess(Q_low_w0, bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) /*+ 0*/])))))
                        status = BID_EXACT_STATUS;
                    break;
                default:
                    // round up
                    long CY;
                    //__add_carry_out(out Stemp_w0, out CY, Q_low_w0, bid_reciprocals10_128_flat[(extra_digits << 1) + 0]);
                {
                    final long __Y = bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) /*+ 0*/];

                    Stemp_w0 = Q_low_w0 + __Y;
                    CY = (UnsignedLong.isLess(Stemp_w0, Q_low_w0)) ? 1L : 0;
                }
                //__add_carry_in_out(out Stemp_w1, out carry, Q_low_w1, bid_reciprocals10_128_flat[(extra_digits << 1) + 1], CY);
                {
                    final long __Y = bid_reciprocals10_128_BID_UINT128[(extra_digits << 1) + 1];

                    final long __X1;
                    __X1 = Q_low_w1 + CY;
                    Stemp_w1 = __X1 + __Y;
                    carry = ((UnsignedLong.isLess(Stemp_w1, __X1)) || (UnsignedLong.isLess(__X1, CY))) ? 1L : 0;
                }

                if ((UnsignedLong.isGreaterOrEqual((remainder_h >>> (64 - amount)) + carry, 1L << amount)))
                    status = BID_EXACT_STATUS;
                break;
            }

            if (status != BID_EXACT_STATUS)
                __set_status_flags(fpsc, BID_UNDERFLOW_EXCEPTION | status);
        }


        return sgn | _C64;

    }