1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package libcore.java.math; 18 19import java.math.BigInteger; 20import java.util.Random; 21 22public class BigIntegerTest extends junit.framework.TestCase { 23 // http://code.google.com/p/android/issues/detail?id=18452 24 public void test_hashCode() { 25 BigInteger firstBig = new BigInteger("30003543667898318853"); 26 BigInteger secondBig = new BigInteger("3298535022597"); 27 BigInteger andedBigs = firstBig.and(secondBig); 28 BigInteger toCompareBig = BigInteger.valueOf(andedBigs.longValue()); 29 assertEquals(andedBigs, toCompareBig); 30 assertEquals(andedBigs.hashCode(), toCompareBig.hashCode()); 31 } 32 33 // http://b/2981072 - off-by-one error in BigInteger.valueOf 34 public void test_valueOf() { 35 // I assume here that we'll never cache more than 1024 values. 36 // (At the moment, we cache -1 to 10.) 37 for (int i = -1024; i <= 1024; ++i) { 38 assertEquals(i, BigInteger.valueOf(i).intValue()); 39 } 40 } 41 42 // http://code.google.com/p/android/issues/detail?id=7036 43 public void test_invalidBigIntegerStringConversions() { 44 // Check we don't disallow related reasonable strings... 45 new BigInteger("1", 10); 46 new BigInteger("1a", 16); 47 new BigInteger("-1", 10); 48 new BigInteger("-1a", 16); 49 new BigInteger("\u0661", 10); 50 new BigInteger("\u0661a", 16); 51 new BigInteger("-\u0661", 10); 52 new BigInteger("-\u0661a", 16); 53 // This is allowed from Java 7 on. 54 new BigInteger("+1"); 55 // Now check the invalid cases... 56 try { 57 new BigInteger("-a"); // no digits from other bases. 58 fail(); 59 } catch (NumberFormatException expected) { 60 } 61 try { 62 new BigInteger("-1a"); // no trailing digits from other bases. 63 fail(); 64 } catch (NumberFormatException expected) { 65 } 66 try { 67 new BigInteger("-1 hello"); // no trailing junk at all. 68 fail(); 69 } catch (NumberFormatException expected) { 70 } 71 try { 72 new BigInteger("--1"); // only one sign. 73 fail(); 74 } catch (NumberFormatException expected) { 75 } 76 try { 77 new BigInteger(""); // at least one digit. 78 fail(); 79 } catch (NumberFormatException expected) { 80 } 81 try { 82 new BigInteger("-"); // at least one digit, even after a sign. 83 fail(); 84 } catch (NumberFormatException expected) { 85 } 86 } 87 88 public void test_Constructor_ILjava_util_Random() throws Exception { 89 Random rand = new Random(); 90 BigInteger b; 91 for (int rep = 0; rep < 1024; ++rep) { // Manual flakiness protection for random tests. 92 b = new BigInteger(128, rand); 93 assertTrue(b.toString() + " " + b.bitLength(), b.bitLength() <= 128); 94 95 b = new BigInteger(16, rand); 96 assertTrue(b.toString() + " " + b.bitLength(), b.bitLength() <= 16); 97 98 b = new BigInteger(5, rand); 99 assertTrue(b.toString() + " " + b.bitLength(), b.bitLength() <= 5); 100 } 101 } 102 103 public void test_Constructor_IILjava_util_Random() throws Exception { 104 Random rand = new Random(); 105 BigInteger b; 106 for (int rep = 0; rep < 1024; ++rep) { // Manual flakiness protection for random tests. 107 b = new BigInteger(128, 100, rand); 108 assertEquals(b.toString(), 128, b.bitLength()); 109 assertTrue(b.isProbablePrime(100)); 110 111 b = new BigInteger(16, 100, rand); 112 assertEquals(b.toString(), 16, b.bitLength()); 113 assertTrue(b.isProbablePrime(100)); 114 115 b = new BigInteger(5, 100, rand); 116 assertEquals(b.toString(), 5, b.bitLength()); 117 assertTrue(b.isProbablePrime(100)); 118 } 119 120 // Two bits is an interesting special case because there's an even 2-bit prime. 121 int[] primes = new int[1024]; 122 boolean saw2 = false; 123 boolean saw3 = false; 124 for (int rep = 0; rep < primes.length; ++rep) { // Manual flakiness protection for random tests. 125 b = new BigInteger(2, 100, rand); 126 assertEquals(b.toString(), 2, b.bitLength()); 127 assertTrue(b.isProbablePrime(100)); 128 primes[rep] = b.intValue(); 129 } 130 for (int i = 0; i < primes.length; ++i) { 131 if (primes[i] == 2) { 132 saw2 = true; 133 } else if (primes[i] == 3) { 134 saw3 = true; 135 } else { 136 fail(); 137 } 138 } 139 assertTrue(saw2 && saw3); 140 } 141 142 public void test_probablePrime() throws Exception { 143 Random rand = new Random(); 144 BigInteger b; 145 for (int rep = 0; rep < 1024; ++rep) { // Manual flakiness protection for random tests. 146 b = BigInteger.probablePrime(128, rand); 147 assertEquals(b.toString(), 128, b.bitLength()); 148 assertTrue(b.isProbablePrime(100)); 149 150 b = BigInteger.probablePrime(16, rand); 151 assertEquals(b.toString(), 16, b.bitLength()); 152 assertTrue(b.isProbablePrime(100)); 153 154 b = BigInteger.probablePrime(5, rand); 155 assertEquals(b.toString(), 5, b.bitLength()); 156 assertTrue(b.isProbablePrime(100)); 157 } 158 } 159 160 public void test_negativeValues_superfluousZeros() throws Exception { 161 byte[] trimmedBytes = new byte[] { 162 (byte) 0xae, (byte) 0x0f, (byte) 0xa1, (byte) 0x93 163 }; 164 byte[] extraZeroesBytes = new byte[] { 165 (byte) 0xff, (byte) 0xae, (byte) 0x0f, (byte) 0xa1, (byte) 0x93 166 }; 167 168 BigInteger trimmed = new BigInteger(trimmedBytes); 169 BigInteger extraZeroes = new BigInteger(extraZeroesBytes); 170 171 assertEquals(trimmed, extraZeroes); 172 } 173 174 public void test_positiveValues_superfluousZeros() throws Exception { 175 byte[] trimmedBytes = new byte[] { 176 (byte) 0x2e, (byte) 0x0f, (byte) 0xa1, (byte) 0x93 177 }; 178 byte[] extraZeroesBytes = new byte[] { 179 (byte) 0x00, (byte) 0x2e, (byte) 0x0f, (byte) 0xa1, (byte) 0x93 180 }; 181 182 BigInteger trimmed = new BigInteger(trimmedBytes); 183 BigInteger extraZeroes = new BigInteger(extraZeroesBytes); 184 185 assertEquals(trimmed, extraZeroes); 186 } 187 188 /** 189 * Tests that Long.MIN_VALUE / -1 doesn't overflow back to Long.MIN_VALUE, 190 * like it would in long arithmetic. 191 */ 192 public void test_divide_avoids64bitOverflow() throws Exception { 193 BigInteger negV = BigInteger.valueOf(Long.MIN_VALUE); 194 BigInteger posV = negV.divide(BigInteger.valueOf(-1)); 195 assertEquals("-9223372036854775808", negV.toString()); 196 assertEquals( "9223372036854775808", posV.toString()); 197 } 198} 199