jdk/test/java/lang/IntegralPrimitiveToString.java
changeset 17929 5ef41523c723
child 23010 6dadb192ad81
equal deleted inserted replaced
17928:717ffe79604d 17929:5ef41523c723
       
     1 /*
       
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 import org.testng.annotations.DataProvider;
       
    25 import org.testng.annotations.Test;
       
    26 
       
    27 import java.math.BigInteger;
       
    28 import java.util.ArrayList;
       
    29 import java.util.Iterator;
       
    30 import java.util.Arrays;
       
    31 import java.util.List;
       
    32 import java.util.function.LongFunction;
       
    33 import java.util.function.Function;
       
    34 
       
    35 import static org.testng.Assert.assertEquals;
       
    36 
       
    37 /**
       
    38  * @test
       
    39  * @run testng IntegralPrimitiveToString
       
    40  * @summary test string conversions for primitive integral types.
       
    41  * @author Mike Duigou
       
    42  */
       
    43 public class IntegralPrimitiveToString {
       
    44 
       
    45     @Test(dataProvider="numbers")
       
    46     public <N extends Number> void testToString(String description,
       
    47         Function<N, BigInteger> converter,
       
    48         Function<N, BigInteger> unsignedConverter,
       
    49         N[] values,
       
    50         Stringifier<N>[] stringifiers) {
       
    51         System.out.printf("%s : conversions: %d values: %d\n", description, stringifiers.length, values.length);
       
    52         for( N value : values) {
       
    53             BigInteger asBigInt = converter.apply(value);
       
    54             BigInteger asUnsignedBigInt = unsignedConverter.apply(value);
       
    55             for(Stringifier<N> stringifier : stringifiers) {
       
    56                 stringifier.assertMatchingToString(value, asBigInt, asUnsignedBigInt, description);
       
    57             }
       
    58         }
       
    59     }
       
    60 
       
    61     static class Stringifier<N extends Number> {
       
    62         final boolean signed;
       
    63         final int  radix;
       
    64         final Function<N,String> toString;
       
    65         Stringifier(boolean signed, int radix, Function<N,String> toString) {
       
    66             this.signed = signed;
       
    67             this.radix = radix;
       
    68             this.toString = toString;
       
    69         }
       
    70 
       
    71         public void assertMatchingToString(N value, BigInteger asSigned, BigInteger asUnsigned, String description) {
       
    72             String expected = signed
       
    73                 ? asSigned.toString(radix)
       
    74                 : asUnsigned.toString(radix);
       
    75 
       
    76             String actual = toString.apply(value);
       
    77 
       
    78             assertEquals(actual, expected, description + " conversion should be the same");
       
    79         }
       
    80     }
       
    81 
       
    82     @DataProvider(name="numbers", parallel=true)
       
    83     public Iterator<Object[]> testSetProvider() {
       
    84 
       
    85     return Arrays.asList(
       
    86         new Object[] { "Byte",
       
    87             (Function<Byte,BigInteger>) b -> BigInteger.valueOf((long) b),
       
    88             (Function<Byte,BigInteger>) b -> BigInteger.valueOf(Integer.toUnsignedLong((byte) b)),
       
    89             numberProvider((LongFunction<Byte>) l -> Byte.valueOf((byte) l), Byte.SIZE),
       
    90             new Stringifier[] {
       
    91                 new Stringifier<Byte>(true, 10, b -> b.toString()),
       
    92                 new Stringifier<Byte>(true, 10, b -> Byte.toString(b))
       
    93             }
       
    94         },
       
    95         new Object[] { "Short",
       
    96             (Function<Short,BigInteger>) s -> BigInteger.valueOf((long) s),
       
    97             (Function<Short,BigInteger>) s -> BigInteger.valueOf(Integer.toUnsignedLong((short) s)),
       
    98             numberProvider((LongFunction<Short>) l -> Short.valueOf((short) l), Short.SIZE),
       
    99             new Stringifier[] {
       
   100                 new Stringifier<Short>(true, 10, s -> s.toString()),
       
   101                 new Stringifier<Short>(true, 10, s -> Short.toString( s))
       
   102             }
       
   103         },
       
   104         new Object[] { "Integer",
       
   105             (Function<Integer,BigInteger>) i -> BigInteger.valueOf((long) i),
       
   106             (Function<Integer,BigInteger>) i -> BigInteger.valueOf(Integer.toUnsignedLong(i)),
       
   107             numberProvider((LongFunction<Integer>) l -> Integer.valueOf((int) l), Integer.SIZE),
       
   108             new Stringifier[] {
       
   109                 new Stringifier<Integer>(true, 10, i -> i.toString()),
       
   110                 new Stringifier<Integer>(true, 10, i -> Integer.toString(i)),
       
   111                 new Stringifier<Integer>(false, 2, Integer::toBinaryString),
       
   112                 new Stringifier<Integer>(false, 16, Integer::toHexString),
       
   113                 new Stringifier<Integer>(false, 8, Integer::toOctalString),
       
   114                 new Stringifier<Integer>(true, 2, i -> Integer.toString(i, 2)),
       
   115                 new Stringifier<Integer>(true, 8, i -> Integer.toString(i, 8)),
       
   116                 new Stringifier<Integer>(true, 10, i -> Integer.toString(i, 10)),
       
   117                 new Stringifier<Integer>(true, 16, i -> Integer.toString(i, 16)),
       
   118                 new Stringifier<Integer>(true, Character.MAX_RADIX, i -> Integer.toString(i, Character.MAX_RADIX)),
       
   119                 new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i)),
       
   120                 new Stringifier<Integer>(false, 2, i -> Integer.toUnsignedString(i, 2)),
       
   121                 new Stringifier<Integer>(false, 8, i -> Integer.toUnsignedString(i, 8)),
       
   122                 new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i, 10)),
       
   123                 new Stringifier<Integer>(false, 16, i -> Integer.toUnsignedString(i, 16)),
       
   124                 new Stringifier<Integer>(false, Character.MAX_RADIX, i -> Integer.toUnsignedString(i, Character.MAX_RADIX))
       
   125             }
       
   126         },
       
   127         new Object[] { "Long",
       
   128             (Function<Long, BigInteger>) BigInteger::valueOf,
       
   129             (Function<Long, BigInteger>) l -> {
       
   130                 if (l >= 0) {
       
   131                     return BigInteger.valueOf((long) l);
       
   132                 } else {
       
   133                     int upper = (int)(l >>> 32);
       
   134                     int lower = (int) (long) l;
       
   135 
       
   136                     // return (upper << 32) + lower
       
   137                     return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
       
   138                     add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
       
   139                 }
       
   140             },
       
   141             numberProvider((LongFunction<Long>) Long::valueOf, Long.SIZE),
       
   142             new Stringifier[] {
       
   143                 new Stringifier<Long>(true, 10, l -> l.toString()),
       
   144                 new Stringifier<Long>(true, 10, l -> Long.toString(l)),
       
   145                 new Stringifier<Long>(false, 2, Long::toBinaryString),
       
   146                 new Stringifier<Long>(false, 16, Long::toHexString),
       
   147                 new Stringifier<Long>(false, 8, Long::toOctalString),
       
   148                 new Stringifier<Long>(true, 2, l -> Long.toString(l, 2)),
       
   149                 new Stringifier<Long>(true, 8, l -> Long.toString(l, 8)),
       
   150                 new Stringifier<Long>(true, 10, l -> Long.toString(l, 10)),
       
   151                 new Stringifier<Long>(true, 16, l -> Long.toString(l, 16)),
       
   152                 new Stringifier<Long>(true, Character.MAX_RADIX, l -> Long.toString(l, Character.MAX_RADIX)),
       
   153                 new Stringifier<Long>(false, 10, Long::toUnsignedString),
       
   154                 new Stringifier<Long>(false, 2, l -> Long.toUnsignedString(l, 2)),
       
   155                 new Stringifier<Long>(false, 8, l-> Long.toUnsignedString(l, 8)),
       
   156                 new Stringifier<Long>(false, 10, l -> Long.toUnsignedString(l, 10)),
       
   157                 new Stringifier<Long>(false, 16, l -> Long.toUnsignedString(l, 16)),
       
   158                 new Stringifier<Long>(false, Character.MAX_RADIX, l -> Long.toUnsignedString(l, Character.MAX_RADIX))
       
   159             }
       
   160         }
       
   161         ).iterator();
       
   162     }
       
   163     private static final long[] SOME_PRIMES = {
       
   164         3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L, 41L, 43L, 47L, 53L,
       
   165         59L, 61L, 71L, 73L, 79L, 83L, 89L, 97L, 101L, 103L, 107L, 109L, 113L,
       
   166         5953L, 5981L, 5987L, 6007L, 6011L, 6029L, 6037L, 6043L, 6047L, 6053L,
       
   167         16369L, 16381L, 16411L, 32749L, 32771L, 65521L, 65537L,
       
   168         (long) Integer.MAX_VALUE };
       
   169 
       
   170     public <N extends Number> N[] numberProvider(LongFunction<N> boxer, int bits, N... extras) {
       
   171         List<N> numbers = new ArrayList<>();
       
   172 
       
   173         for(int bitmag = 0; bitmag < bits; bitmag++) {
       
   174             long value = 1L << bitmag;
       
   175             numbers.add(boxer.apply(value));
       
   176             numbers.add(boxer.apply(value - 1));
       
   177             numbers.add(boxer.apply(value + 1));
       
   178             numbers.add(boxer.apply(-value));
       
   179             for(int divisor = 0; divisor < SOME_PRIMES.length && value < SOME_PRIMES[divisor]; divisor++) {
       
   180                 numbers.add(boxer.apply(value - SOME_PRIMES[divisor]));
       
   181                 numbers.add(boxer.apply(value + SOME_PRIMES[divisor]));
       
   182                 numbers.add(boxer.apply(value * SOME_PRIMES[divisor]));
       
   183                 numbers.add(boxer.apply(value / SOME_PRIMES[divisor]));
       
   184                 numbers.add(boxer.apply(value | SOME_PRIMES[divisor]));
       
   185                 numbers.add(boxer.apply(value & SOME_PRIMES[divisor]));
       
   186                 numbers.add(boxer.apply(value ^ SOME_PRIMES[divisor]));
       
   187             }
       
   188         }
       
   189 
       
   190         numbers.addAll(Arrays.asList(extras));
       
   191 
       
   192         return (N[]) numbers.toArray(new Number[numbers.size()]);
       
   193     }
       
   194 }