<commit_before>package net.katsuster.ememu.generic;

/**
 * 整数演算のクラス
 */
public class IntegerExt {
    /**
     * キャリーが発生する（符号無し演算の加算がオーバーフローする）か、
     * 否か、を取得します。
     *
     * @param left  被加算数
     * @param right 加算する数
     * @return キャリーが発生する場合は true、発生しない場合は false
     */
    public static boolean carryFrom(int left, int right) {
        return compareUint32(left + right, left) < 0;
    }

    /**
     * ボローが発生する（符号無し演算の減算がアンダーフローする）か、
     * 否か、を取得します。
     *
     * @param left  被減算数
     * @param right 減算する数
     * @return キャリーが発生する場合は true、発生しない場合は false
     */
    public static boolean borrowFrom(int left, int right) {
        return compareUint32(left, right) < 0;
    }

    /**
     * オーバーフローが発生する（符号付き演算の結果が符号が変わる）か、
     * 否か、を取得します。
     *
     * @param left  被演算数
     * @param right 演算数
     * @param add   加算なら true、減算なら false
     * @return オーバーフローが発生したなら true、そうでなければ false
     */
    public static boolean overflowFrom(int left, int right, boolean add) {
        int dest;
        boolean cond1, cond2;

        if (add) {
            //加算の場合
            dest = left + right;

            //left と right が同じ符号
            cond1 = (left >= 0 && right >= 0) || (left < 0 && right < 0);
            //なおかつ left, right と dest の符号が異なる
            cond2 = (left < 0 && dest >= 0) || (left >= 0 && dest < 0);
        } else {
            //減算の場合
            dest = left - right;

            //left と right が異なる符号
            cond1 = (left < 0 && right >= 0) || (left >= 0 && right < 0);
            //なおかつ left と dest の符号が異なる
            cond2 = (left < 0 && dest >= 0) || (left >= 0 && dest < 0);
        }

        return cond1 && cond2;
    }

    /**
     * 2 つの 32bit 値を符号無しと見なして数値的に比較します。
     *
     * @param x 比較する最初の値
     * @param y 比較する 2番目の値
     * @return x == y の場合は値 0、
     * x &lt; y の場合は 0 より小さい値、
     * x &gt; y の場合は 0 より大きい値
     */
    public static int compareUint32(int x, int y) {
        int r;

        //上位 31ビットを比べる
        r = (x >>> 1) - (y >>> 1);
        if (r != 0) {
            return r;
        }

        //下位 1ビットを比べる
        return (x & 1) - (y & 1);
    }
}
<commit_msg>generic: add compare 64bit unsigned int<commit_after>package net.katsuster.ememu.generic;

/**
 * 整数演算のクラス
 */
public class IntegerExt {
    /**
     * キャリーが発生する（符号無し演算の加算がオーバーフローする）か、
     * 否か、を取得します。
     *
     * @param left  被加算数
     * @param right 加算する数
     * @return キャリーが発生する場合は true、発生しない場合は false
     */
    public static boolean carryFrom(int left, int right) {
        return compareUint32(left + right, left) < 0;
    }

    /**
     * ボローが発生する（符号無し演算の減算がアンダーフローする）か、
     * 否か、を取得します。
     *
     * @param left  被減算数
     * @param right 減算する数
     * @return キャリーが発生する場合は true、発生しない場合は false
     */
    public static boolean borrowFrom(int left, int right) {
        return compareUint32(left, right) < 0;
    }

    /**
     * オーバーフローが発生する（符号付き演算の結果が符号が変わる）か、
     * 否か、を取得します。
     *
     * @param left  被演算数
     * @param right 演算数
     * @param add   加算なら true、減算なら false
     * @return オーバーフローが発生したなら true、そうでなければ false
     */
    public static boolean overflowFrom(int left, int right, boolean add) {
        int dest;
        boolean cond1, cond2;

        if (add) {
            //加算の場合
            dest = left + right;

            //left と right が同じ符号
            cond1 = (left >= 0 && right >= 0) || (left < 0 && right < 0);
            //なおかつ left, right と dest の符号が異なる
            cond2 = (left < 0 && dest >= 0) || (left >= 0 && dest < 0);
        } else {
            //減算の場合
            dest = left - right;

            //left と right が異なる符号
            cond1 = (left < 0 && right >= 0) || (left >= 0 && right < 0);
            //なおかつ left と dest の符号が異なる
            cond2 = (left < 0 && dest >= 0) || (left >= 0 && dest < 0);
        }

        return cond1 && cond2;
    }

    /**
     * 2 つの 32bit 値を符号無しと見なして数値的に比較します。
     *
     * @param x 比較する最初の値
     * @param y 比較する 2番目の値
     * @return x == y の場合は値 0、
     * x &lt; y の場合は 0 より小さい値、
     * x &gt; y の場合は 0 より大きい値
     */
    public static int compareUint32(int x, int y) {
        int r;

        //上位 31ビットを比べる
        r = (x >>> 1) - (y >>> 1);
        if (r != 0) {
            return r;
        }

        //下位 1ビットを比べる
        return (x & 1) - (y & 1);
    }

    /**
     * 2 つの 64bit 値を符号無しと見なして数値的に比較します。
     *
     * @param x 比較する最初の値
     * @param y 比較する 2番目の値
     * @return x == y の場合は値 0、
     * x &lt; y の場合は 0 より小さい値、
     * x &gt; y の場合は 0 より大きい値
     */
    public static long compareUint64(long x, long y) {
        long r;

        //上位 63ビットを比べる
        r = (x >>> 1) - (y >>> 1);
        if (r != 0) {
            return r;
        }

        //下位 1ビットを比べる
        return (x & 1) - (y & 1);
    }
}

{'fraction_non_alphanumeric': 0.12681388012618297, 'fraction_numerical': 0.023764458464773923, 'mean_word_length': 1.525756771109931, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7144831', 'n_tokens_mistral': 2275, 'n_tokens_neox': 2148, 'n_words': 479}