All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.util.hll.NumberUtil Maven / Gradle / Ivy

There is a newer version: 9.6.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.solr.util.hll;

/**
 * A collection of utilities to work with numbers.
 */
class NumberUtil {
    // loge(2) (log-base e of 2)
    public static final double LOGE_2 = 0.6931471805599453;

    // ************************************************************************
    /**
     * Computes the log2 (log-base-two) of the specified value.
     *
     * @param  value the double for which the log2 is
     *         desired.
     * @return the log2 of the specified value
     */
    public static double log2(final double value) {
        // REF:  http://en.wikipedia.org/wiki/Logarithmic_scale (conversion of bases)
        return Math.log(value) / LOGE_2;
    }

    // ========================================================================
    // the hex characters
    private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7',
                                        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    // ------------------------------------------------------------------------
    /**
     * Converts the specified array of bytes into a string of
     * hex characters (low byte first).
     *
     * @param  bytes the array of bytes that are to be converted.
     *         This cannot be null though it may be empty.
     * @param  offset the offset in bytes at which the bytes will
     *         be taken.  This cannot be negative and must be less than
     *         bytes.length - 1.
     * @param  count the number of bytes to be retrieved from the specified array.
     *         This cannot be negative.  If greater than bytes.length - offset
     *         then that value is used.
     * @return a string of at most count characters that represents
     *         the specified byte array in hex.  This will never be null
     *         though it may be empty if bytes is empty or count
     *         is zero.
     * @throws IllegalArgumentException if offset is greater than
     *         or equal to bytes.length.
     * @see #fromHex(String, int, int)
     */
    public static String toHex(final byte[] bytes, final int offset, final int count) {
        if(offset >= bytes.length) throw new IllegalArgumentException("Offset is greater than the length (" + offset + " >= " + bytes.length + ").")/*by contract*/;
        final int byteCount = Math.min( (bytes.length - offset), count);
        final int upperBound = byteCount + offset;

        final char[] chars = new char[byteCount * 2/*two chars per byte*/];
        int charIndex = 0;
        for(int i=offset; i>> 4) & 0x0F];
            chars[charIndex++] = HEX[value & 0x0F];
        }

        return new String(chars);
    }

    /**
     * Converts the specified array of hex characters into an array of bytes
     * (low byte first).
     *
     * @param  string the string of hex characters to be converted into bytes.
     *         This cannot be null though it may be blank.
     * @param  offset the offset in the string at which the characters will be
     *         taken.  This cannot be negative and must be less than string.length() - 1.
     * @param  count the number of characters to be retrieved from the specified
     *         string.  This cannot be negative and must be divisible by two
     *         (since there are two characters per byte).
     * @return the array of bytes that were converted from the
     *         specified string (in the specified range).  This will never be
     *         null though it may be empty if string
     *         is empty or count is zero.
     * @throws IllegalArgumentException if offset is greater than
     *         or equal to string.length() or if count
     *         is not divisible by two.
     * @see #toHex(byte[], int, int)
     */
    public static byte[] fromHex(final String string, final int offset, final int count) {
        if(offset >= string.length()) throw new IllegalArgumentException("Offset is greater than the length (" + offset + " >= " + string.length() + ").")/*by contract*/;
        if( (count & 0x01) != 0) throw new IllegalArgumentException("Count is not divisible by two (" + count + ").")/*by contract*/;
        final int charCount = Math.min((string.length() - offset), count);
        final int upperBound = offset + charCount;

        final byte[] bytes = new byte[charCount >>> 1/*aka /2*/];
        int byteIndex = 0/*beginning*/;
        for(int i=offset; ibyte.
     *         This cannot be a character other than [a-fA-F0-9].
     * @return the value of the specified character.  This will be a value 0
     *         through 15.
     * @throws IllegalArgumentException if the specified character is not in
     *         [a-fA-F0-9]
     */
    private static final int digit(final char character) {
        switch(character) {
            case '0':
                return 0;
            case '1':
                return 1;
            case '2':
                return 2;
            case '3':
                return 3;
            case '4':
                return 4;
            case '5':
                return 5;
            case '6':
                return 6;
            case '7':
                return 7;
            case '8':
                return 8;
            case '9':
                return 9;
            case 'a':
            case 'A':
                return 10;
            case 'b':
            case 'B':
                return 11;
            case 'c':
            case 'C':
                return 12;
            case 'd':
            case 'D':
                return 13;
            case 'e':
            case 'E':
                return 14;
            case 'f':
            case 'F':
                return 15;

            default:
                throw new IllegalArgumentException("Character is not in [a-fA-F0-9] ('" + character + "').");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy