| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 char buffer_container[kBufferSize]; | 57 char buffer_container[kBufferSize]; |
| 58 Vector<char> buffer(buffer_container, kBufferSize); | 58 Vector<char> buffer(buffer_container, kBufferSize); |
| 59 int length; | 59 int length; |
| 60 int point; | 60 int point; |
| 61 int status; | 61 int status; |
| 62 | 62 |
| 63 double min_double = 5e-324; | 63 double min_double = 5e-324; |
| 64 status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0, | 64 status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0, |
| 65 buffer, &length, &point); | 65 buffer, &length, &point); |
| 66 CHECK(status); | 66 CHECK(status); |
| 67 CHECK_EQ("5", buffer.start()); | 67 CHECK_EQ(0, strcmp("5", buffer.start())); |
| 68 CHECK_EQ(-323, point); | 68 CHECK_EQ(-323, point); |
| 69 | 69 |
| 70 double max_double = 1.7976931348623157e308; | 70 double max_double = 1.7976931348623157e308; |
| 71 status = FastDtoa(max_double, FAST_DTOA_SHORTEST, 0, | 71 status = FastDtoa(max_double, FAST_DTOA_SHORTEST, 0, |
| 72 buffer, &length, &point); | 72 buffer, &length, &point); |
| 73 CHECK(status); | 73 CHECK(status); |
| 74 CHECK_EQ("17976931348623157", buffer.start()); | 74 CHECK_EQ(0, strcmp("17976931348623157", buffer.start())); |
| 75 CHECK_EQ(309, point); | 75 CHECK_EQ(309, point); |
| 76 | 76 |
| 77 status = FastDtoa(4294967272.0, FAST_DTOA_SHORTEST, 0, | 77 status = FastDtoa(4294967272.0, FAST_DTOA_SHORTEST, 0, |
| 78 buffer, &length, &point); | 78 buffer, &length, &point); |
| 79 CHECK(status); | 79 CHECK(status); |
| 80 CHECK_EQ("4294967272", buffer.start()); | 80 CHECK_EQ(0, strcmp("4294967272", buffer.start())); |
| 81 CHECK_EQ(10, point); | 81 CHECK_EQ(10, point); |
| 82 | 82 |
| 83 status = FastDtoa(4.1855804968213567e298, FAST_DTOA_SHORTEST, 0, | 83 status = FastDtoa(4.1855804968213567e298, FAST_DTOA_SHORTEST, 0, |
| 84 buffer, &length, &point); | 84 buffer, &length, &point); |
| 85 CHECK(status); | 85 CHECK(status); |
| 86 CHECK_EQ("4185580496821357", buffer.start()); | 86 CHECK_EQ(0, strcmp("4185580496821357", buffer.start())); |
| 87 CHECK_EQ(299, point); | 87 CHECK_EQ(299, point); |
| 88 | 88 |
| 89 status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_SHORTEST, 0, | 89 status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_SHORTEST, 0, |
| 90 buffer, &length, &point); | 90 buffer, &length, &point); |
| 91 CHECK(status); | 91 CHECK(status); |
| 92 CHECK_EQ("5562684646268003", buffer.start()); | 92 CHECK_EQ(0, strcmp("5562684646268003", buffer.start())); |
| 93 CHECK_EQ(-308, point); | 93 CHECK_EQ(-308, point); |
| 94 | 94 |
| 95 status = FastDtoa(2147483648.0, FAST_DTOA_SHORTEST, 0, | 95 status = FastDtoa(2147483648.0, FAST_DTOA_SHORTEST, 0, |
| 96 buffer, &length, &point); | 96 buffer, &length, &point); |
| 97 CHECK(status); | 97 CHECK(status); |
| 98 CHECK_EQ("2147483648", buffer.start()); | 98 CHECK_EQ(0, strcmp("2147483648", buffer.start())); |
| 99 CHECK_EQ(10, point); | 99 CHECK_EQ(10, point); |
| 100 | 100 |
| 101 status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_SHORTEST, 0, | 101 status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_SHORTEST, 0, |
| 102 buffer, &length, &point); | 102 buffer, &length, &point); |
| 103 if (status) { // Not all FastDtoa variants manage to compute this number. | 103 if (status) { // Not all FastDtoa variants manage to compute this number. |
| 104 CHECK_EQ("35844466002796428", buffer.start()); | 104 CHECK_EQ(0, strcmp("35844466002796428", buffer.start())); |
| 105 CHECK_EQ(299, point); | 105 CHECK_EQ(299, point); |
| 106 } | 106 } |
| 107 | 107 |
| 108 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); | 108 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); |
| 109 double v = Double(smallest_normal64).value(); | 109 double v = Double(smallest_normal64).value(); |
| 110 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); | 110 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); |
| 111 if (status) { | 111 if (status) { |
| 112 CHECK_EQ("22250738585072014", buffer.start()); | 112 CHECK_EQ(0, strcmp("22250738585072014", buffer.start())); |
| 113 CHECK_EQ(-307, point); | 113 CHECK_EQ(-307, point); |
| 114 } | 114 } |
| 115 | 115 |
| 116 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | 116 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); |
| 117 v = Double(largest_denormal64).value(); | 117 v = Double(largest_denormal64).value(); |
| 118 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); | 118 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); |
| 119 if (status) { | 119 if (status) { |
| 120 CHECK_EQ("2225073858507201", buffer.start()); | 120 CHECK_EQ(0, strcmp("2225073858507201", buffer.start())); |
| 121 CHECK_EQ(-307, point); | 121 CHECK_EQ(-307, point); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 TEST(FastDtoaPrecisionVariousDoubles) { | 126 TEST(FastDtoaPrecisionVariousDoubles) { |
| 127 char buffer_container[kBufferSize]; | 127 char buffer_container[kBufferSize]; |
| 128 Vector<char> buffer(buffer_container, kBufferSize); | 128 Vector<char> buffer(buffer_container, kBufferSize); |
| 129 int length; | 129 int length; |
| 130 int point; | 130 int point; |
| 131 int status; | 131 int status; |
| 132 | 132 |
| 133 status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point); | 133 status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point); |
| 134 CHECK(status); | 134 CHECK(status); |
| 135 CHECK_GE(3, length); | 135 CHECK_GE(3, length); |
| 136 TrimRepresentation(buffer); | 136 TrimRepresentation(buffer); |
| 137 CHECK_EQ("1", buffer.start()); | 137 CHECK_EQ(0, strcmp("1", buffer.start())); |
| 138 CHECK_EQ(1, point); | 138 CHECK_EQ(1, point); |
| 139 | 139 |
| 140 status = FastDtoa(1.5, FAST_DTOA_PRECISION, 10, buffer, &length, &point); | 140 status = FastDtoa(1.5, FAST_DTOA_PRECISION, 10, buffer, &length, &point); |
| 141 if (status) { | 141 if (status) { |
| 142 CHECK_GE(10, length); | 142 CHECK_GE(10, length); |
| 143 TrimRepresentation(buffer); | 143 TrimRepresentation(buffer); |
| 144 CHECK_EQ("15", buffer.start()); | 144 CHECK_EQ(0, strcmp("15", buffer.start())); |
| 145 CHECK_EQ(1, point); | 145 CHECK_EQ(1, point); |
| 146 } | 146 } |
| 147 | 147 |
| 148 double min_double = 5e-324; | 148 double min_double = 5e-324; |
| 149 status = FastDtoa(min_double, FAST_DTOA_PRECISION, 5, | 149 status = FastDtoa(min_double, FAST_DTOA_PRECISION, 5, |
| 150 buffer, &length, &point); | 150 buffer, &length, &point); |
| 151 CHECK(status); | 151 CHECK(status); |
| 152 CHECK_EQ("49407", buffer.start()); | 152 CHECK_EQ(0, strcmp("49407", buffer.start())); |
| 153 CHECK_EQ(-323, point); | 153 CHECK_EQ(-323, point); |
| 154 | 154 |
| 155 double max_double = 1.7976931348623157e308; | 155 double max_double = 1.7976931348623157e308; |
| 156 status = FastDtoa(max_double, FAST_DTOA_PRECISION, 7, | 156 status = FastDtoa(max_double, FAST_DTOA_PRECISION, 7, |
| 157 buffer, &length, &point); | 157 buffer, &length, &point); |
| 158 CHECK(status); | 158 CHECK(status); |
| 159 CHECK_EQ("1797693", buffer.start()); | 159 CHECK_EQ(0, strcmp("1797693", buffer.start())); |
| 160 CHECK_EQ(309, point); | 160 CHECK_EQ(309, point); |
| 161 | 161 |
| 162 status = FastDtoa(4294967272.0, FAST_DTOA_PRECISION, 14, | 162 status = FastDtoa(4294967272.0, FAST_DTOA_PRECISION, 14, |
| 163 buffer, &length, &point); | 163 buffer, &length, &point); |
| 164 if (status) { | 164 if (status) { |
| 165 CHECK_GE(14, length); | 165 CHECK_GE(14, length); |
| 166 TrimRepresentation(buffer); | 166 TrimRepresentation(buffer); |
| 167 CHECK_EQ("4294967272", buffer.start()); | 167 CHECK_EQ(0, strcmp("4294967272", buffer.start())); |
| 168 CHECK_EQ(10, point); | 168 CHECK_EQ(10, point); |
| 169 } | 169 } |
| 170 | 170 |
| 171 status = FastDtoa(4.1855804968213567e298, FAST_DTOA_PRECISION, 17, | 171 status = FastDtoa(4.1855804968213567e298, FAST_DTOA_PRECISION, 17, |
| 172 buffer, &length, &point); | 172 buffer, &length, &point); |
| 173 CHECK(status); | 173 CHECK(status); |
| 174 CHECK_EQ("41855804968213567", buffer.start()); | 174 CHECK_EQ(0, strcmp("41855804968213567", buffer.start())); |
| 175 CHECK_EQ(299, point); | 175 CHECK_EQ(299, point); |
| 176 | 176 |
| 177 status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_PRECISION, 1, | 177 status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_PRECISION, 1, |
| 178 buffer, &length, &point); | 178 buffer, &length, &point); |
| 179 CHECK(status); | 179 CHECK(status); |
| 180 CHECK_EQ("6", buffer.start()); | 180 CHECK_EQ(0, strcmp("6", buffer.start())); |
| 181 CHECK_EQ(-308, point); | 181 CHECK_EQ(-308, point); |
| 182 | 182 |
| 183 status = FastDtoa(2147483648.0, FAST_DTOA_PRECISION, 5, | 183 status = FastDtoa(2147483648.0, FAST_DTOA_PRECISION, 5, |
| 184 buffer, &length, &point); | 184 buffer, &length, &point); |
| 185 CHECK(status); | 185 CHECK(status); |
| 186 CHECK_EQ("21475", buffer.start()); | 186 CHECK_EQ(0, strcmp("21475", buffer.start())); |
| 187 CHECK_EQ(10, point); | 187 CHECK_EQ(10, point); |
| 188 | 188 |
| 189 status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_PRECISION, 10, | 189 status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_PRECISION, 10, |
| 190 buffer, &length, &point); | 190 buffer, &length, &point); |
| 191 CHECK(status); | 191 CHECK(status); |
| 192 CHECK_GE(10, length); | 192 CHECK_GE(10, length); |
| 193 TrimRepresentation(buffer); | 193 TrimRepresentation(buffer); |
| 194 CHECK_EQ("35844466", buffer.start()); | 194 CHECK_EQ(0, strcmp("35844466", buffer.start())); |
| 195 CHECK_EQ(299, point); | 195 CHECK_EQ(299, point); |
| 196 | 196 |
| 197 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); | 197 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); |
| 198 double v = Double(smallest_normal64).value(); | 198 double v = Double(smallest_normal64).value(); |
| 199 status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point); | 199 status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point); |
| 200 CHECK(status); | 200 CHECK(status); |
| 201 CHECK_EQ("22250738585072014", buffer.start()); | 201 CHECK_EQ(0, strcmp("22250738585072014", buffer.start())); |
| 202 CHECK_EQ(-307, point); | 202 CHECK_EQ(-307, point); |
| 203 | 203 |
| 204 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | 204 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); |
| 205 v = Double(largest_denormal64).value(); | 205 v = Double(largest_denormal64).value(); |
| 206 status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point); | 206 status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point); |
| 207 CHECK(status); | 207 CHECK(status); |
| 208 CHECK_GE(20, length); | 208 CHECK_GE(20, length); |
| 209 TrimRepresentation(buffer); | 209 TrimRepresentation(buffer); |
| 210 CHECK_EQ("22250738585072009", buffer.start()); | 210 CHECK_EQ(0, strcmp("22250738585072009", buffer.start())); |
| 211 CHECK_EQ(-307, point); | 211 CHECK_EQ(-307, point); |
| 212 | 212 |
| 213 v = 3.3161339052167390562200598e-237; | 213 v = 3.3161339052167390562200598e-237; |
| 214 status = FastDtoa(v, FAST_DTOA_PRECISION, 18, buffer, &length, &point); | 214 status = FastDtoa(v, FAST_DTOA_PRECISION, 18, buffer, &length, &point); |
| 215 CHECK(status); | 215 CHECK(status); |
| 216 CHECK_EQ("331613390521673906", buffer.start()); | 216 CHECK_EQ(0, strcmp("331613390521673906", buffer.start())); |
| 217 CHECK_EQ(-236, point); | 217 CHECK_EQ(-236, point); |
| 218 | 218 |
| 219 v = 7.9885183916008099497815232e+191; | 219 v = 7.9885183916008099497815232e+191; |
| 220 status = FastDtoa(v, FAST_DTOA_PRECISION, 4, buffer, &length, &point); | 220 status = FastDtoa(v, FAST_DTOA_PRECISION, 4, buffer, &length, &point); |
| 221 CHECK(status); | 221 CHECK(status); |
| 222 CHECK_EQ("7989", buffer.start()); | 222 CHECK_EQ(0, strcmp("7989", buffer.start())); |
| 223 CHECK_EQ(192, point); | 223 CHECK_EQ(192, point); |
| 224 } | 224 } |
| 225 | 225 |
| 226 | 226 |
| 227 TEST(FastDtoaGayShortest) { | 227 TEST(FastDtoaGayShortest) { |
| 228 char buffer_container[kBufferSize]; | 228 char buffer_container[kBufferSize]; |
| 229 Vector<char> buffer(buffer_container, kBufferSize); | 229 Vector<char> buffer(buffer_container, kBufferSize); |
| 230 bool status; | 230 bool status; |
| 231 int length; | 231 int length; |
| 232 int point; | 232 int point; |
| 233 int succeeded = 0; | 233 int succeeded = 0; |
| 234 int total = 0; | 234 int total = 0; |
| 235 bool needed_max_length = false; | 235 bool needed_max_length = false; |
| 236 | 236 |
| 237 Vector<const PrecomputedShortest> precomputed = | 237 Vector<const PrecomputedShortest> precomputed = |
| 238 PrecomputedShortestRepresentations(); | 238 PrecomputedShortestRepresentations(); |
| 239 for (int i = 0; i < precomputed.length(); ++i) { | 239 for (int i = 0; i < precomputed.length(); ++i) { |
| 240 const PrecomputedShortest current_test = precomputed[i]; | 240 const PrecomputedShortest current_test = precomputed[i]; |
| 241 total++; | 241 total++; |
| 242 double v = current_test.v; | 242 double v = current_test.v; |
| 243 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); | 243 status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point); |
| 244 CHECK_GE(kFastDtoaMaximalLength, length); | 244 CHECK_GE(kFastDtoaMaximalLength, length); |
| 245 if (!status) continue; | 245 if (!status) continue; |
| 246 if (length == kFastDtoaMaximalLength) needed_max_length = true; | 246 if (length == kFastDtoaMaximalLength) needed_max_length = true; |
| 247 succeeded++; | 247 succeeded++; |
| 248 CHECK_EQ(current_test.decimal_point, point); | 248 CHECK_EQ(current_test.decimal_point, point); |
| 249 CHECK_EQ(current_test.representation, buffer.start()); | 249 CHECK_EQ(0, strcmp(current_test.representation, buffer.start())); |
| 250 } | 250 } |
| 251 CHECK_GT(succeeded*1.0/total, 0.99); | 251 CHECK_GT(succeeded*1.0/total, 0.99); |
| 252 CHECK(needed_max_length); | 252 CHECK(needed_max_length); |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 TEST(FastDtoaGayPrecision) { | 256 TEST(FastDtoaGayPrecision) { |
| 257 char buffer_container[kBufferSize]; | 257 char buffer_container[kBufferSize]; |
| 258 Vector<char> buffer(buffer_container, kBufferSize); | 258 Vector<char> buffer(buffer_container, kBufferSize); |
| 259 bool status; | 259 bool status; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 274 total++; | 274 total++; |
| 275 if (number_digits <= 15) total_15++; | 275 if (number_digits <= 15) total_15++; |
| 276 status = FastDtoa(v, FAST_DTOA_PRECISION, number_digits, | 276 status = FastDtoa(v, FAST_DTOA_PRECISION, number_digits, |
| 277 buffer, &length, &point); | 277 buffer, &length, &point); |
| 278 CHECK_GE(number_digits, length); | 278 CHECK_GE(number_digits, length); |
| 279 if (!status) continue; | 279 if (!status) continue; |
| 280 succeeded++; | 280 succeeded++; |
| 281 if (number_digits <= 15) succeeded_15++; | 281 if (number_digits <= 15) succeeded_15++; |
| 282 TrimRepresentation(buffer); | 282 TrimRepresentation(buffer); |
| 283 CHECK_EQ(current_test.decimal_point, point); | 283 CHECK_EQ(current_test.decimal_point, point); |
| 284 CHECK_EQ(current_test.representation, buffer.start()); | 284 CHECK_EQ(0, strcmp(current_test.representation, buffer.start())); |
| 285 } | 285 } |
| 286 // The precomputed numbers contain many entries with many requested | 286 // The precomputed numbers contain many entries with many requested |
| 287 // digits. These have a high failure rate and we therefore expect a lower | 287 // digits. These have a high failure rate and we therefore expect a lower |
| 288 // success rate than for the shortest representation. | 288 // success rate than for the shortest representation. |
| 289 CHECK_GT(succeeded*1.0/total, 0.85); | 289 CHECK_GT(succeeded*1.0/total, 0.85); |
| 290 // However with less than 15 digits almost the algorithm should almost always | 290 // However with less than 15 digits almost the algorithm should almost always |
| 291 // succeed. | 291 // succeed. |
| 292 CHECK_GT(succeeded_15*1.0/total_15, 0.9999); | 292 CHECK_GT(succeeded_15*1.0/total_15, 0.9999); |
| 293 } | 293 } |
| OLD | NEW |