/*
 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 4504839 4215269 6322074
 * @summary Basic tests for unsigned operations
 * @author Joseph D. Darcy
 */

import java.math.*;

public class Unsigned {
    public static void main(String... args) {
        int errors = 0;

        errors += testRoundtrip();
        errors += testByteToUnsignedLong();
        errors += testShortToUnsignedLong();
        errors += testUnsignedCompare();
        errors += testToStringUnsigned();
        errors += testParseUnsignedLong();
        errors += testDivideAndRemainder();

        if (errors > 0) {
            throw new RuntimeException(errors + " errors found in unsigned operations.");
        }
    }

    private static final BigInteger TWO = BigInteger.valueOf(2L);

    private static int testRoundtrip() {
        int errors = 0;

        long[] data = {-1L, 0L, 1L};

        for(long datum : data) {
            if (Long.parseUnsignedLong(Long.toBinaryString(datum), 2) != datum) {
                errors++;
                System.err.println("Bad binary roundtrip conversion of " + datum);
            }

            if (Long.parseUnsignedLong(Long.toOctalString(datum), 8) != datum) {
                errors++;
                System.err.println("Bad octal roundtrip conversion of " + datum);
            }

            if (Long.parseUnsignedLong(Long.toHexString(datum), 16) != datum) {
                errors++;
                System.err.println("Bad hex roundtrip conversion of " + datum);
            }
        }
        return errors;
    }

    private static int testByteToUnsignedLong() {
        int errors = 0;

        for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
            byte datum = (byte) i;
            long ui = Byte.toUnsignedLong(datum);

            if ( (ui & (~0xffL)) != 0L ||
                 ((byte)ui != datum )) {
                errors++;
                System.err.printf("Bad conversion of byte %d to unsigned long %d%n",
                                  datum, ui);
            }
        }
        return errors;
    }

    private static int testShortToUnsignedLong() {
        int errors = 0;

        for(int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) {
            short datum = (short) i;
            long ui = Short.toUnsignedLong(datum);

            if ( (ui & (~0xffffL)) != 0L ||
                 ((short)ui != datum )) {
                errors++;
                System.err.printf("Bad conversion of short %d to unsigned long %d%n",
                                  datum, ui);
            }
        }
        return errors;
    }
    private static int testUnsignedCompare() {
        int errors = 0;

        long[] data = {
            0L,
            1L,
            2L,
            3L,
            0x00000000_80000000L,
            0x00000000_FFFFFFFFL,
            0x00000001_00000000L,
            0x80000000_00000000L,
            0x80000000_00000001L,
            0x80000000_00000002L,
            0x80000000_00000003L,
            0x80000000_80000000L,
            0xFFFFFFFF_FFFFFFFEL,
            0xFFFFFFFF_FFFFFFFFL,
        };

        for(long i : data) {
            for(long j : data) {
                long libraryResult    = Long.compareUnsigned(i, j);
                long libraryResultRev = Long.compareUnsigned(j, i);
                long localResult      = compUnsigned(i, j);

                if (i == j) {
                    if (libraryResult != 0) {
                        errors++;
                        System.err.printf("Value 0x%x did not compare as " +
                                          "an unsigned equal to itself; got %d%n",
                                          i, libraryResult);
                    }
                }

                   if (Long.signum(libraryResult) != Long.signum(localResult)) {
                       errors++;
                       System.err.printf("Unsigned compare of 0x%x to 0x%x%n:" +
                                         "\texpected sign of %d, got %d%n",
                                         i, j, localResult, libraryResult);
                   }

                if (Long.signum(libraryResult) !=
                    -Long.signum(libraryResultRev)) {
                    errors++;
                    System.err.printf("signum(compareUnsigned(x, y)) != -signum(compareUnsigned(y,x))" +
                                      " for \t0x%x and 0x%x, computed %d and %d%n",
                                      i, j, libraryResult, libraryResultRev);
                }
            }
        }

        return errors;
    }

    private static int compUnsigned(long x, long y) {
        BigInteger big_x = toUnsignedBigInt(x);
        BigInteger big_y = toUnsignedBigInt(y);

        return big_x.compareTo(big_y);
    }

    private static BigInteger toUnsignedBigInt(long x) {
        if (x >= 0)
            return BigInteger.valueOf(x);
        else {
            int upper = (int)(((long)x) >> 32);
            int lower = (int) x;

            BigInteger bi = // (upper << 32) + lower
                (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
                add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));

            // System.out.printf("%n\t%d%n\t%s%n", x, bi.toString());
            return bi;
        }
    }

    private static int testToStringUnsigned() {
        int errors = 0;

        long[] data = {
            0L,
            1L,
            2L,
            3L,
            99999L,
            100000L,
            999999L,
            100000L,
            999999999L,
            1000000000L,
            0x1234_5678L,
            0x8000_0000L,
            0x8000_0001L,
            0x8000_0002L,
            0x8000_0003L,
            0x8765_4321L,
            0xFFFF_FFFEL,
            0xFFFF_FFFFL,

            // Long-range values
              999_999_999_999L,
            1_000_000_000_000L,

              999_999_999_999_999_999L,
            1_000_000_000_000_000_000L,

            0xFFFF_FFFF_FFFF_FFFEL,
            0xFFFF_FFFF_FFFF_FFFFL,
        };

        for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
            for(long datum : data) {
                String result1 = Long.toUnsignedString(datum, radix);
                String result2 = toUnsignedBigInt(datum).toString(radix);

                if (!result1.equals(result2)) {
                    errors++;
                    System.err.printf("Unexpected string difference converting 0x%x:" +
                                      "\t%s %s%n",
                                      datum, result1, result2);
                }

                if (radix == 10) {
                    String result3 = Long.toUnsignedString(datum);
                    if (!result2.equals(result3)) {
                        errors++;
                        System.err.printf("Unexpected string difference converting 0x%x:" +
                                          "\t%s %s%n",
                                          datum, result3, result2);
                    }
                }

                long parseResult = Long.parseUnsignedLong(result1, radix);

                if (parseResult != datum) {
                    errors++;
                        System.err.printf("Bad roundtrip conversion of %d in base %d" +
                                          "\tconverting back ''%s'' resulted in %d%n",
                                          datum, radix, result1,  parseResult);
                }
            }
        }

        return errors;
    }

    private static int testParseUnsignedLong() {
        int errors = 0;
        long maxUnsignedInt = Integer.toUnsignedLong(0xffff_ffff);

        // Values include those between signed Long.MAX_VALUE and
        // unsignted Long MAX_VALUE.
        BigInteger[] inRange = {
            BigInteger.valueOf(0L),
            BigInteger.valueOf(1L),
            BigInteger.valueOf(10L),
            BigInteger.valueOf(2147483646L),   // Integer.MAX_VALUE - 1
            BigInteger.valueOf(2147483647L),   // Integer.MAX_VALUE
            BigInteger.valueOf(2147483648L),   // Integer.MAX_VALUE + 1

            BigInteger.valueOf(maxUnsignedInt - 1L),
            BigInteger.valueOf(maxUnsignedInt),

            BigInteger.valueOf(Long.MAX_VALUE - 1L),
            BigInteger.valueOf(Long.MAX_VALUE),
            BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE),

            TWO.pow(64).subtract(BigInteger.ONE)
        };

        for(BigInteger value : inRange) {
            for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
                String bigString = value.toString(radix);
                long longResult = Long.parseUnsignedLong(bigString, radix);

                if (!toUnsignedBigInt(longResult).equals(value)) {
                    errors++;
                    System.err.printf("Bad roundtrip conversion of %d in base %d" +
                                      "\tconverting back ''%s'' resulted in %d%n",
                                      value, radix, bigString,  longResult);
                }
            }
        }

        String[] outOfRange = {
            null,
            "",
            "-1",
            TWO.pow(64).toString(),
        };

        for(String s : outOfRange) {
            try {
                long result = Long.parseUnsignedLong(s);
                errors++; // Should not reach here
                System.err.printf("Unexpected got %d from an unsigned conversion of %s",
                                  result, s);
            } catch(NumberFormatException nfe) {
                ; // Correct result
            }
        }

        return errors;
    }

    private static int testDivideAndRemainder() {
        int errors = 0;
        long MAX_UNSIGNED_INT = Integer.toUnsignedLong(0xffff_ffff);

        BigInteger[] inRange = {
            BigInteger.valueOf(0L),
            BigInteger.valueOf(1L),
            BigInteger.valueOf(10L),
            BigInteger.valueOf(2147483646L),   // Integer.MAX_VALUE - 1
            BigInteger.valueOf(2147483647L),   // Integer.MAX_VALUE
            BigInteger.valueOf(2147483648L),   // Integer.MAX_VALUE + 1

            BigInteger.valueOf(MAX_UNSIGNED_INT - 1L),
            BigInteger.valueOf(MAX_UNSIGNED_INT),

            BigInteger.valueOf(Long.MAX_VALUE - 1L),
            BigInteger.valueOf(Long.MAX_VALUE),
            BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE),

            TWO.pow(64).subtract(BigInteger.ONE)
        };

        for(BigInteger dividend : inRange) {
            for(BigInteger divisor : inRange) {
                long quotient;
                BigInteger longQuotient;

                long remainder;
                BigInteger longRemainder;

                if (divisor.equals(BigInteger.ZERO)) {
                    try {
                        quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue());
                        errors++;
                    } catch(ArithmeticException ea) {
                        ; // Expected
                    }

                    try {
                        remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue());
                        errors++;
                    } catch(ArithmeticException ea) {
                        ; // Expected
                    }
                } else {
                    quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue());
                    longQuotient = dividend.divide(divisor);

                    if (quotient != longQuotient.longValue()) {
                        errors++;
                        System.err.printf("Unexpected unsigned divide result %s on %s/%s%n",
                                          Long.toUnsignedString(quotient),
                                          Long.toUnsignedString(dividend.longValue()),
                                          Long.toUnsignedString(divisor.longValue()));
                    }

                    remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue());
                    longRemainder = dividend.remainder(divisor);

                    if (remainder != longRemainder.longValue()) {
                        errors++;
                        System.err.printf("Unexpected unsigned remainder result %s on %s%%%s%n",
                                          Long.toUnsignedString(remainder),
                                          Long.toUnsignedString(dividend.longValue()),
                                          Long.toUnsignedString(divisor.longValue()));
                    }
                }
            }
        }

        return errors;
    }
}
