static void sort(double[] a, int left, int right,
                     double[] work, int workBase, int workLen) {
        /*
         * Phase 1: Move NaNs to the end of the array.
         */
        while (left <= right && Double.isNaN(a[right])) {
            --right;
        }
        for (int k = right; --k >= left; ) {
            double ak = a[k];
            if (ak != ak) { // a[k] is NaN
                a[k] = a[right];
                a[right] = ak;
                --right;
            }
        }

        /*
         * Phase 2: Sort everything except NaNs (which are already in place).
         */
        doSort(a, left, right, work, workBase, workLen);

        /*
         * Phase 3: Place negative zeros before positive zeros.
         */
        int hi = right;

        /*
         * Find the first zero, or first positive, or last negative element.
         */
        while (left < hi) {
            int middle = (left + hi) >>> 1;
            double middleValue = a[middle];

            if (middleValue < 0.0d) {
                left = middle + 1;
            } else {
                hi = middle;
            }
        }

        /*
         * Skip the last negative value (if any) or all leading negative zeros.
         */
        while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) {
            ++left;
        }

        /*
         * Move negative zeros to the beginning of the sub-range.
         *
         * Partitioning:
         *
         * +----------------------------------------------------+
         * |   < 0.0   |   -0.0   |   0.0   |   ?  ( >= 0.0 )   |
         * +----------------------------------------------------+
         *              ^          ^         ^
         *              |          |         |
         *             left        p         k
         *
         * Invariants:
         *
         *   all in (*,  left)  <  0.0
         *   all in [left,  p) == -0.0
         *   all in [p,     k) ==  0.0
         *   all in [k, right] >=  0.0
         *
         * Pointer k is the first index of ?-part.
         */
        for (int k = left, p = left - 1; ++k <= right; ) {
            double ak = a[k];
            if (ak != 0.0d) {
                break;
            }
            if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d
                a[k] = 0.0d;
                a[++p] = -0.0d;
            }
        }
    }
static void sort ( double [ ] a , int left , int right , double [ ] work , int workBase , int workLen ) { while ( left <= right && Double . isNaN ( a [ right ] ) ) { -- right ; } for ( int k = right ; -- k >= left ; ) { double ak = a [ k ] ; if ( ak != ak ) { a [ k ] = a [ right ] ; a [ right ] = ak ; -- right ; } } doSort ( a , left , right , work , workBase , workLen ) ; int hi = right ; while ( left < hi ) { int middle = ( left + hi ) > > > 1 ; double middleValue = a [ middle ] ; if ( middleValue < 0.0d ) { left = middle + 1 ; } else { hi = middle ; } } while ( left <= right && Double . doubleToRawLongBits ( a [ left ] ) < 0 ) { ++ left ; } for ( int k = left , p = left - 1 ; ++ k <= right ; ) { double ak = a [ k ] ; if ( ak != 0.0d ) { break ; } if ( Double . doubleToRawLongBits ( ak ) < 0 ) { a [ k ] = 0.0d ; a [ ++ p ] = - 0.0d ; } } }
Sorts the specified range of the array using the given
workspace array slice if possible for merging

@param a the array to be sorted
@param left the index of the first element, inclusive, to be sorted
@param right the index of the last element, inclusive, to be sorted
@param work a workspace array (slice)
@param workBase origin of usable space in work array
@param workLen usable size of work array