BignumDtoaTest.java revision 1511:a1f59730bfb5
1/* 2 * Copyright (c) 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26// This file is available under and governed by the GNU General Public 27// License version 2 only, as published by the Free Software Foundation. 28// However, the following notice accompanied the original version of this 29// file: 30// 31// Copyright 2012 the V8 project authors. All rights reserved. 32// Redistribution and use in source and binary forms, with or without 33// modification, are permitted provided that the following conditions are 34// met: 35// 36// * Redistributions of source code must retain the above copyright 37// notice, this list of conditions and the following disclaimer. 38// * Redistributions in binary form must reproduce the above 39// copyright notice, this list of conditions and the following 40// disclaimer in the documentation and/or other materials provided 41// with the distribution. 42// * Neither the name of Google Inc. nor the names of its 43// contributors may be used to endorse or promote products derived 44// from this software without specific prior written permission. 45// 46// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 47// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 48// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 49// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 50// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 51// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 52// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 56// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 58package jdk.nashorn.internal.runtime.doubleconv.test; 59 60import java.io.BufferedReader; 61import java.io.InputStreamReader; 62import jdk.nashorn.internal.runtime.doubleconv.DoubleConversion; 63import jdk.nashorn.internal.runtime.doubleconv.DtoaBuffer; 64import jdk.nashorn.internal.runtime.doubleconv.DtoaMode; 65 66import org.testng.annotations.Test; 67 68import static org.testng.Assert.assertEquals; 69import static org.testng.Assert.assertTrue; 70 71/** 72 * FastDtoa tests 73 */ 74@SuppressWarnings("javadoc") 75public class BignumDtoaTest { 76 77 final static private int BUFFER_SIZE = 100; 78 79 // Removes trailing '0' digits. 80 // Can return the empty string if all digits are 0. 81 private static String trimRepresentation(final String representation) { 82 final int len = representation.length(); 83 int i; 84 for (i = len - 1; i >= 0; --i) { 85 if (representation.charAt(i) != '0') break; 86 } 87 return representation.substring(0, i + 1); 88 } 89 90 @Test 91 public void testBignumVarious() { 92 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 93 94 DoubleConversion.bignumDtoa(1, DtoaMode.SHORTEST, 0, buffer); 95 assertEquals("1", buffer.getRawDigits()); 96 assertEquals(1, buffer.getDecimalPoint()); 97 buffer.reset(); 98 99 DoubleConversion.bignumDtoa(1.0, DtoaMode.FIXED, 3, buffer); 100 assertTrue(3 >= buffer.getLength() - buffer.getDecimalPoint()); 101 assertEquals("1", trimRepresentation(buffer.getRawDigits())); 102 assertEquals(1, buffer.getDecimalPoint()); 103 buffer.reset(); 104 105 DoubleConversion.bignumDtoa(1.0, DtoaMode.PRECISION, 3, buffer); 106 assertTrue(3 >= buffer.getLength()); 107 assertEquals("1", trimRepresentation(buffer.getRawDigits())); 108 assertEquals(1, buffer.getDecimalPoint()); 109 buffer.reset(); 110 111 DoubleConversion.bignumDtoa(1.5, DtoaMode.SHORTEST, 0, buffer); 112 assertEquals("15", buffer.getRawDigits()); 113 assertEquals(1, buffer.getDecimalPoint()); 114 buffer.reset(); 115 116 DoubleConversion.bignumDtoa(1.5, DtoaMode.FIXED, 10, buffer); 117 assertTrue(10 >= buffer.getLength() - buffer.getDecimalPoint()); 118 assertEquals("15", trimRepresentation(buffer.getRawDigits())); 119 assertEquals(1, buffer.getDecimalPoint()); 120 buffer.reset(); 121 122 DoubleConversion.bignumDtoa(1.5, DtoaMode.PRECISION, 10, buffer); 123 assertTrue(10 >= buffer.getLength()); 124 assertEquals("15", trimRepresentation(buffer.getRawDigits())); 125 assertEquals(1, buffer.getDecimalPoint()); 126 buffer.reset(); 127 128 final double min_double = 5e-324; 129 DoubleConversion.bignumDtoa(min_double, DtoaMode.SHORTEST, 0, buffer); 130 assertEquals("5", buffer.getRawDigits()); 131 assertEquals(-323, buffer.getDecimalPoint()); 132 buffer.reset(); 133 134 DoubleConversion.bignumDtoa(min_double, DtoaMode.FIXED, 5, buffer); 135 assertTrue(5 >= buffer.getLength() - buffer.getDecimalPoint()); 136 assertEquals("", trimRepresentation(buffer.getRawDigits())); 137 buffer.reset(); 138 139 DoubleConversion.bignumDtoa(min_double, DtoaMode.PRECISION, 5, buffer); 140 assertTrue(5 >= buffer.getLength()); 141 assertEquals("49407", trimRepresentation(buffer.getRawDigits())); 142 assertEquals(-323, buffer.getDecimalPoint()); 143 buffer.reset(); 144 145 final double max_double = 1.7976931348623157e308; 146 DoubleConversion.bignumDtoa(max_double, DtoaMode.SHORTEST, 0, buffer); 147 assertEquals("17976931348623157", buffer.getRawDigits()); 148 assertEquals(309, buffer.getDecimalPoint()); 149 buffer.reset(); 150 151 DoubleConversion.bignumDtoa(max_double, DtoaMode.PRECISION, 7, buffer); 152 assertTrue(7 >= buffer.getLength()); 153 assertEquals("1797693", trimRepresentation(buffer.getRawDigits())); 154 assertEquals(309, buffer.getDecimalPoint()); 155 buffer.reset(); 156 157 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.SHORTEST, 0, buffer); 158 assertEquals("4294967272", buffer.getRawDigits()); 159 assertEquals(10, buffer.getDecimalPoint()); 160 buffer.reset(); 161 162 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.FIXED, 5, buffer); 163 assertEquals("429496727200000", buffer.getRawDigits()); 164 assertEquals(10, buffer.getDecimalPoint()); 165 buffer.reset(); 166 167 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.PRECISION, 14, buffer); 168 assertTrue(14 >= buffer.getLength()); 169 assertEquals("4294967272", trimRepresentation(buffer.getRawDigits())); 170 assertEquals(10, buffer.getDecimalPoint()); 171 buffer.reset(); 172 173 DoubleConversion.bignumDtoa(4.1855804968213567e298, DtoaMode.SHORTEST, 0, buffer); 174 assertEquals("4185580496821357", buffer.getRawDigits()); 175 assertEquals(299, buffer.getDecimalPoint()); 176 buffer.reset(); 177 178 DoubleConversion.bignumDtoa(4.1855804968213567e298, DtoaMode.PRECISION, 20, buffer); 179 assertTrue(20 >= buffer.getLength()); 180 assertEquals("41855804968213567225", trimRepresentation(buffer.getRawDigits())); 181 assertEquals(299, buffer.getDecimalPoint()); 182 buffer.reset(); 183 184 DoubleConversion.bignumDtoa(5.5626846462680035e-309, DtoaMode.SHORTEST, 0, buffer); 185 assertEquals("5562684646268003", buffer.getRawDigits()); 186 assertEquals(-308, buffer.getDecimalPoint()); 187 buffer.reset(); 188 189 DoubleConversion.bignumDtoa(5.5626846462680035e-309, DtoaMode.PRECISION, 1, buffer); 190 assertTrue(1 >= buffer.getLength()); 191 assertEquals("6", trimRepresentation(buffer.getRawDigits())); 192 assertEquals(-308, buffer.getDecimalPoint()); 193 buffer.reset(); 194 195 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.SHORTEST, 0, buffer); 196 assertEquals("2147483648", buffer.getRawDigits()); 197 assertEquals(10, buffer.getDecimalPoint()); 198 buffer.reset(); 199 200 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.FIXED, 2, buffer); 201 assertTrue(2 >= buffer.getLength() - buffer.getDecimalPoint()); 202 assertEquals("2147483648", trimRepresentation(buffer.getRawDigits())); 203 assertEquals(10, buffer.getDecimalPoint()); 204 buffer.reset(); 205 206 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.PRECISION, 5, buffer); 207 assertTrue(5 >= buffer.getLength()); 208 assertEquals("21475", trimRepresentation(buffer.getRawDigits())); 209 assertEquals(10, buffer.getDecimalPoint()); 210 buffer.reset(); 211 212 DoubleConversion.bignumDtoa(3.5844466002796428e+298, DtoaMode.SHORTEST, 0, buffer); 213 assertEquals("35844466002796428", buffer.getRawDigits()); 214 assertEquals(299, buffer.getDecimalPoint()); 215 buffer.reset(); 216 217 DoubleConversion.bignumDtoa(3.5844466002796428e+298, DtoaMode.PRECISION, 10, buffer); 218 assertTrue(10 >= buffer.getLength()); 219 assertEquals("35844466", trimRepresentation(buffer.getRawDigits())); 220 assertEquals(299, buffer.getDecimalPoint()); 221 buffer.reset(); 222 223 final long smallest_normal64 = 0x0010000000000000L; 224 double v = Double.longBitsToDouble(smallest_normal64); 225 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 226 assertEquals("22250738585072014", buffer.getRawDigits()); 227 assertEquals(-307, buffer.getDecimalPoint()); 228 buffer.reset(); 229 230 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 20, buffer); 231 assertTrue(20 >= buffer.getLength()); 232 assertEquals("22250738585072013831", trimRepresentation(buffer.getRawDigits())); 233 assertEquals(-307, buffer.getDecimalPoint()); 234 buffer.reset(); 235 236 final long largest_denormal64 = 0x000FFFFFFFFFFFFFL; 237 v = Double.longBitsToDouble(largest_denormal64); 238 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 239 assertEquals("2225073858507201", buffer.getRawDigits()); 240 assertEquals(-307, buffer.getDecimalPoint()); 241 buffer.reset(); 242 243 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 20, buffer); 244 assertTrue(20 >= buffer.getLength()); 245 assertEquals("2225073858507200889", trimRepresentation(buffer.getRawDigits())); 246 assertEquals(-307, buffer.getDecimalPoint()); 247 buffer.reset(); 248 249 DoubleConversion.bignumDtoa(4128420500802942e-24, DtoaMode.SHORTEST, 0, buffer); 250 assertEquals("4128420500802942", buffer.getRawDigits()); 251 assertEquals(-8, buffer.getDecimalPoint()); 252 buffer.reset(); 253 254 DoubleConversion.bignumDtoa(3.9292015898194142585311918e-10, DtoaMode.SHORTEST, 0, buffer); 255 assertEquals("39292015898194143", buffer.getRawDigits()); 256 buffer.reset(); 257 258 v = 4194304.0; 259 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, 5, buffer); 260 assertTrue(5 >= buffer.getLength() - buffer.getDecimalPoint()); 261 assertEquals("4194304", trimRepresentation(buffer.getRawDigits())); 262 buffer.reset(); 263 264 v = 3.3161339052167390562200598e-237; 265 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 19, buffer); 266 assertTrue(19 >= buffer.getLength()); 267 assertEquals("3316133905216739056", trimRepresentation(buffer.getRawDigits())); 268 assertEquals(-236, buffer.getDecimalPoint()); 269 buffer.reset(); 270 271 v = 7.9885183916008099497815232e+191; 272 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 4, buffer); 273 assertTrue(4 >= buffer.getLength()); 274 assertEquals("7989", trimRepresentation(buffer.getRawDigits())); 275 assertEquals(192, buffer.getDecimalPoint()); 276 buffer.reset(); 277 278 v = 1.0000000000000012800000000e+17; 279 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, 1, buffer); 280 assertTrue(1 >= buffer.getLength() - buffer.getDecimalPoint()); 281 assertEquals("100000000000000128", trimRepresentation(buffer.getRawDigits())); 282 assertEquals(18, buffer.getDecimalPoint()); 283 buffer.reset(); 284 } 285 286 287 @Test 288 public void testBignumShortest() { 289 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-shortest.txt"))) 290 .lines() 291 .forEach(line -> { 292 if (line.isEmpty() || line.startsWith("//")) { 293 return; // comment or empty line 294 } 295 final String[] tokens = line.split(",\\s+"); 296 assertEquals(tokens.length, 3, "*" + line + "*"); 297 final double v = Double.parseDouble(tokens[0]); 298 final String str = tokens[1].replace('"', ' ').trim();; 299 final int point = Integer.parseInt(tokens[2]); 300 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 301 302 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 303 assertEquals(str, buffer.getRawDigits()); 304 assertEquals(point, buffer.getDecimalPoint()); 305 }); 306 } 307 308 @Test 309 public void testBignumFixed() { 310 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-fixed.txt"))) 311 .lines() 312 .forEach(line -> { 313 if (line.isEmpty() || line.startsWith("//")) { 314 return; // comment or empty line 315 } 316 final String[] tokens = line.split(",\\s+"); 317 assertEquals(tokens.length, 4); 318 final double v = Double.parseDouble(tokens[0]); 319 final int digits = Integer.parseInt(tokens[1]); 320 final String str = tokens[2].replace('"', ' ').trim(); 321 final int point = Integer.parseInt(tokens[3]); 322 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 323 324 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, digits, buffer); 325 assertEquals(str, trimRepresentation(buffer.getRawDigits())); 326 assertEquals(point, buffer.getDecimalPoint()); 327 }); 328 } 329 330 @Test 331 public void testBignumPrecision() { 332 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-precision.txt"))) 333 .lines() 334 .forEach(line -> { 335 if (line.isEmpty() || line.startsWith("//")) { 336 return; // comment or empty line 337 } 338 final String[] tokens = line.split(",\\s+"); 339 assertEquals(tokens.length, 4); 340 final double v = Double.parseDouble(tokens[0]); 341 final int digits = Integer.parseInt(tokens[1]); 342 final String str = tokens[2].replace('"', ' ').trim(); 343 final int point = Integer.parseInt(tokens[3]); 344 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 345 346 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, digits, buffer); 347 assertEquals(str, trimRepresentation(buffer.getRawDigits())); 348 assertEquals(point, buffer.getDecimalPoint()); 349 }); 350 } 351 352} 353