BignumDtoaTest.java revision 1507:549f06563f1c
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 * @test 75 * @run testng jdk.nashorn.internal.runtime.doubleconv.test.FastDtoaTest 76 */ 77@SuppressWarnings("javadoc") 78public class BignumDtoaTest { 79 80 final static private int BUFFER_SIZE = 100; 81 82 // Removes trailing '0' digits. 83 // Can return the empty string if all digits are 0. 84 private static String trimRepresentation(final String representation) { 85 final int len = representation.length(); 86 int i; 87 for (i = len - 1; i >= 0; --i) { 88 if (representation.charAt(i) != '0') break; 89 } 90 return representation.substring(0, i + 1); 91 } 92 93 @Test 94 public void testBignumVarious() { 95 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 96 97 DoubleConversion.bignumDtoa(1, DtoaMode.SHORTEST, 0, buffer); 98 assertEquals("1", buffer.getRawDigits()); 99 assertEquals(1, buffer.getDecimalPoint()); 100 buffer.reset(); 101 102 DoubleConversion.bignumDtoa(1.0, DtoaMode.FIXED, 3, buffer); 103 assertTrue(3 >= buffer.getLength() - buffer.getDecimalPoint()); 104 assertEquals("1", trimRepresentation(buffer.getRawDigits())); 105 assertEquals(1, buffer.getDecimalPoint()); 106 buffer.reset(); 107 108 DoubleConversion.bignumDtoa(1.0, DtoaMode.PRECISION, 3, buffer); 109 assertTrue(3 >= buffer.getLength()); 110 assertEquals("1", trimRepresentation(buffer.getRawDigits())); 111 assertEquals(1, buffer.getDecimalPoint()); 112 buffer.reset(); 113 114 DoubleConversion.bignumDtoa(1.5, DtoaMode.SHORTEST, 0, buffer); 115 assertEquals("15", buffer.getRawDigits()); 116 assertEquals(1, buffer.getDecimalPoint()); 117 buffer.reset(); 118 119 DoubleConversion.bignumDtoa(1.5, DtoaMode.FIXED, 10, buffer); 120 assertTrue(10 >= buffer.getLength() - buffer.getDecimalPoint()); 121 assertEquals("15", trimRepresentation(buffer.getRawDigits())); 122 assertEquals(1, buffer.getDecimalPoint()); 123 buffer.reset(); 124 125 DoubleConversion.bignumDtoa(1.5, DtoaMode.PRECISION, 10, buffer); 126 assertTrue(10 >= buffer.getLength()); 127 assertEquals("15", trimRepresentation(buffer.getRawDigits())); 128 assertEquals(1, buffer.getDecimalPoint()); 129 buffer.reset(); 130 131 final double min_double = 5e-324; 132 DoubleConversion.bignumDtoa(min_double, DtoaMode.SHORTEST, 0, buffer); 133 assertEquals("5", buffer.getRawDigits()); 134 assertEquals(-323, buffer.getDecimalPoint()); 135 buffer.reset(); 136 137 DoubleConversion.bignumDtoa(min_double, DtoaMode.FIXED, 5, buffer); 138 assertTrue(5 >= buffer.getLength() - buffer.getDecimalPoint()); 139 assertEquals("", trimRepresentation(buffer.getRawDigits())); 140 buffer.reset(); 141 142 DoubleConversion.bignumDtoa(min_double, DtoaMode.PRECISION, 5, buffer); 143 assertTrue(5 >= buffer.getLength()); 144 assertEquals("49407", trimRepresentation(buffer.getRawDigits())); 145 assertEquals(-323, buffer.getDecimalPoint()); 146 buffer.reset(); 147 148 final double max_double = 1.7976931348623157e308; 149 DoubleConversion.bignumDtoa(max_double, DtoaMode.SHORTEST, 0, buffer); 150 assertEquals("17976931348623157", buffer.getRawDigits()); 151 assertEquals(309, buffer.getDecimalPoint()); 152 buffer.reset(); 153 154 DoubleConversion.bignumDtoa(max_double, DtoaMode.PRECISION, 7, buffer); 155 assertTrue(7 >= buffer.getLength()); 156 assertEquals("1797693", trimRepresentation(buffer.getRawDigits())); 157 assertEquals(309, buffer.getDecimalPoint()); 158 buffer.reset(); 159 160 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.SHORTEST, 0, buffer); 161 assertEquals("4294967272", buffer.getRawDigits()); 162 assertEquals(10, buffer.getDecimalPoint()); 163 buffer.reset(); 164 165 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.FIXED, 5, buffer); 166 assertEquals("429496727200000", buffer.getRawDigits()); 167 assertEquals(10, buffer.getDecimalPoint()); 168 buffer.reset(); 169 170 DoubleConversion.bignumDtoa(4294967272.0, DtoaMode.PRECISION, 14, buffer); 171 assertTrue(14 >= buffer.getLength()); 172 assertEquals("4294967272", trimRepresentation(buffer.getRawDigits())); 173 assertEquals(10, buffer.getDecimalPoint()); 174 buffer.reset(); 175 176 DoubleConversion.bignumDtoa(4.1855804968213567e298, DtoaMode.SHORTEST, 0, buffer); 177 assertEquals("4185580496821357", buffer.getRawDigits()); 178 assertEquals(299, buffer.getDecimalPoint()); 179 buffer.reset(); 180 181 DoubleConversion.bignumDtoa(4.1855804968213567e298, DtoaMode.PRECISION, 20, buffer); 182 assertTrue(20 >= buffer.getLength()); 183 assertEquals("41855804968213567225", trimRepresentation(buffer.getRawDigits())); 184 assertEquals(299, buffer.getDecimalPoint()); 185 buffer.reset(); 186 187 DoubleConversion.bignumDtoa(5.5626846462680035e-309, DtoaMode.SHORTEST, 0, buffer); 188 assertEquals("5562684646268003", buffer.getRawDigits()); 189 assertEquals(-308, buffer.getDecimalPoint()); 190 buffer.reset(); 191 192 DoubleConversion.bignumDtoa(5.5626846462680035e-309, DtoaMode.PRECISION, 1, buffer); 193 assertTrue(1 >= buffer.getLength()); 194 assertEquals("6", trimRepresentation(buffer.getRawDigits())); 195 assertEquals(-308, buffer.getDecimalPoint()); 196 buffer.reset(); 197 198 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.SHORTEST, 0, buffer); 199 assertEquals("2147483648", buffer.getRawDigits()); 200 assertEquals(10, buffer.getDecimalPoint()); 201 buffer.reset(); 202 203 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.FIXED, 2, buffer); 204 assertTrue(2 >= buffer.getLength() - buffer.getDecimalPoint()); 205 assertEquals("2147483648", trimRepresentation(buffer.getRawDigits())); 206 assertEquals(10, buffer.getDecimalPoint()); 207 buffer.reset(); 208 209 DoubleConversion.bignumDtoa(2147483648.0, DtoaMode.PRECISION, 5, buffer); 210 assertTrue(5 >= buffer.getLength()); 211 assertEquals("21475", trimRepresentation(buffer.getRawDigits())); 212 assertEquals(10, buffer.getDecimalPoint()); 213 buffer.reset(); 214 215 DoubleConversion.bignumDtoa(3.5844466002796428e+298, DtoaMode.SHORTEST, 0, buffer); 216 assertEquals("35844466002796428", buffer.getRawDigits()); 217 assertEquals(299, buffer.getDecimalPoint()); 218 buffer.reset(); 219 220 DoubleConversion.bignumDtoa(3.5844466002796428e+298, DtoaMode.PRECISION, 10, buffer); 221 assertTrue(10 >= buffer.getLength()); 222 assertEquals("35844466", trimRepresentation(buffer.getRawDigits())); 223 assertEquals(299, buffer.getDecimalPoint()); 224 buffer.reset(); 225 226 final long smallest_normal64 = 0x0010000000000000L; 227 double v = Double.longBitsToDouble(smallest_normal64); 228 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 229 assertEquals("22250738585072014", buffer.getRawDigits()); 230 assertEquals(-307, buffer.getDecimalPoint()); 231 buffer.reset(); 232 233 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 20, buffer); 234 assertTrue(20 >= buffer.getLength()); 235 assertEquals("22250738585072013831", trimRepresentation(buffer.getRawDigits())); 236 assertEquals(-307, buffer.getDecimalPoint()); 237 buffer.reset(); 238 239 final long largest_denormal64 = 0x000FFFFFFFFFFFFFL; 240 v = Double.longBitsToDouble(largest_denormal64); 241 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 242 assertEquals("2225073858507201", buffer.getRawDigits()); 243 assertEquals(-307, buffer.getDecimalPoint()); 244 buffer.reset(); 245 246 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 20, buffer); 247 assertTrue(20 >= buffer.getLength()); 248 assertEquals("2225073858507200889", trimRepresentation(buffer.getRawDigits())); 249 assertEquals(-307, buffer.getDecimalPoint()); 250 buffer.reset(); 251 252 DoubleConversion.bignumDtoa(4128420500802942e-24, DtoaMode.SHORTEST, 0, buffer); 253 assertEquals("4128420500802942", buffer.getRawDigits()); 254 assertEquals(-8, buffer.getDecimalPoint()); 255 buffer.reset(); 256 257 DoubleConversion.bignumDtoa(3.9292015898194142585311918e-10, DtoaMode.SHORTEST, 0, buffer); 258 assertEquals("39292015898194143", buffer.getRawDigits()); 259 buffer.reset(); 260 261 v = 4194304.0; 262 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, 5, buffer); 263 assertTrue(5 >= buffer.getLength() - buffer.getDecimalPoint()); 264 assertEquals("4194304", trimRepresentation(buffer.getRawDigits())); 265 buffer.reset(); 266 267 v = 3.3161339052167390562200598e-237; 268 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 19, buffer); 269 assertTrue(19 >= buffer.getLength()); 270 assertEquals("3316133905216739056", trimRepresentation(buffer.getRawDigits())); 271 assertEquals(-236, buffer.getDecimalPoint()); 272 buffer.reset(); 273 274 v = 7.9885183916008099497815232e+191; 275 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, 4, buffer); 276 assertTrue(4 >= buffer.getLength()); 277 assertEquals("7989", trimRepresentation(buffer.getRawDigits())); 278 assertEquals(192, buffer.getDecimalPoint()); 279 buffer.reset(); 280 281 v = 1.0000000000000012800000000e+17; 282 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, 1, buffer); 283 assertTrue(1 >= buffer.getLength() - buffer.getDecimalPoint()); 284 assertEquals("100000000000000128", trimRepresentation(buffer.getRawDigits())); 285 assertEquals(18, buffer.getDecimalPoint()); 286 buffer.reset(); 287 } 288 289 290 @Test 291 public void testBignumShortest() { 292 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-shortest.txt"))) 293 .lines() 294 .forEach(line -> { 295 if (line.isEmpty() || line.startsWith("//")) { 296 return; // comment or empty line 297 } 298 final String[] tokens = line.split(",\\s+"); 299 assertEquals(tokens.length, 3, "*" + line + "*"); 300 final double v = Double.parseDouble(tokens[0]); 301 final String str = tokens[1].replace('"', ' ').trim();; 302 final int point = Integer.parseInt(tokens[2]); 303 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 304 305 DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); 306 assertEquals(str, buffer.getRawDigits()); 307 assertEquals(point, buffer.getDecimalPoint()); 308 }); 309 } 310 311 @Test 312 public void testBignumFixed() { 313 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-fixed.txt"))) 314 .lines() 315 .forEach(line -> { 316 if (line.isEmpty() || line.startsWith("//")) { 317 return; // comment or empty line 318 } 319 final String[] tokens = line.split(",\\s+"); 320 assertEquals(tokens.length, 4); 321 final double v = Double.parseDouble(tokens[0]); 322 final int digits = Integer.parseInt(tokens[1]); 323 final String str = tokens[2].replace('"', ' ').trim(); 324 final int point = Integer.parseInt(tokens[3]); 325 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 326 327 DoubleConversion.bignumDtoa(v, DtoaMode.FIXED, digits, buffer); 328 assertEquals(str, trimRepresentation(buffer.getRawDigits())); 329 assertEquals(point, buffer.getDecimalPoint()); 330 }); 331 } 332 333 @Test 334 public void testBignumPrecision() { 335 new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("resources/gay-precision.txt"))) 336 .lines() 337 .forEach(line -> { 338 if (line.isEmpty() || line.startsWith("//")) { 339 return; // comment or empty line 340 } 341 final String[] tokens = line.split(",\\s+"); 342 assertEquals(tokens.length, 4); 343 final double v = Double.parseDouble(tokens[0]); 344 final int digits = Integer.parseInt(tokens[1]); 345 final String str = tokens[2].replace('"', ' ').trim(); 346 final int point = Integer.parseInt(tokens[3]); 347 final DtoaBuffer buffer = new DtoaBuffer(BUFFER_SIZE); 348 349 DoubleConversion.bignumDtoa(v, DtoaMode.PRECISION, digits, buffer); 350 assertEquals(str, trimRepresentation(buffer.getRawDigits())); 351 assertEquals(point, buffer.getDecimalPoint()); 352 }); 353 } 354 355} 356