test-bignum-dtoa.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. // Copyright 2012 the V8 project authors. All rights reserved.
  2. // Redistribution and use in source and binary forms, with or without
  3. // modification, are permitted provided that the following conditions are
  4. // met:
  5. //
  6. // * Redistributions of source code must retain the above copyright
  7. // notice, this list of conditions and the following disclaimer.
  8. // * Redistributions in binary form must reproduce the above
  9. // copyright notice, this list of conditions and the following
  10. // disclaimer in the documentation and/or other materials provided
  11. // with the distribution.
  12. // * Neither the name of Google Inc. nor the names of its
  13. // contributors may be used to endorse or promote products derived
  14. // from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #include <stdlib.h>
  28. #include "bignum-dtoa.h"
  29. #include "cctest.h"
  30. #include "gay-fixed.h"
  31. #include "gay-precision.h"
  32. #include "gay-shortest.h"
  33. #include "gay-shortest-single.h"
  34. #include "ieee.h"
  35. #include "utils.h"
  36. using namespace double_conversion;
  37. // Removes trailing '0' digits.
  38. // Can return the empty string if all digits are 0.
  39. static void TrimRepresentation(Vector<char> representation) {
  40. int len = strlen(representation.start());
  41. int i;
  42. for (i = len - 1; i >= 0; --i) {
  43. if (representation[i] != '0') break;
  44. }
  45. representation[i + 1] = '\0';
  46. }
  47. static const int kBufferSize = 100;
  48. TEST(BignumDtoaVariousDoubles) {
  49. char buffer_container[kBufferSize];
  50. Vector<char> buffer(buffer_container, kBufferSize);
  51. int length;
  52. int point;
  53. BignumDtoa(1.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  54. CHECK_EQ("1", buffer.start());
  55. CHECK_EQ(1, point);
  56. BignumDtoa(1.0, BIGNUM_DTOA_FIXED, 3, buffer, &length, &point);
  57. CHECK_GE(3, length - point);
  58. TrimRepresentation(buffer);
  59. CHECK_EQ("1", buffer.start());
  60. CHECK_EQ(1, point);
  61. BignumDtoa(1.0, BIGNUM_DTOA_PRECISION, 3, buffer, &length, &point);
  62. CHECK_GE(3, length);
  63. TrimRepresentation(buffer);
  64. CHECK_EQ("1", buffer.start());
  65. CHECK_EQ(1, point);
  66. BignumDtoa(1.5, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  67. CHECK_EQ("15", buffer.start());
  68. CHECK_EQ(1, point);
  69. BignumDtoa(1.5, BIGNUM_DTOA_FIXED, 10, buffer, &length, &point);
  70. CHECK_GE(10, length - point);
  71. TrimRepresentation(buffer);
  72. CHECK_EQ("15", buffer.start());
  73. CHECK_EQ(1, point);
  74. BignumDtoa(1.5, BIGNUM_DTOA_PRECISION, 10, buffer, &length, &point);
  75. CHECK_GE(10, length);
  76. TrimRepresentation(buffer);
  77. CHECK_EQ("15", buffer.start());
  78. CHECK_EQ(1, point);
  79. double min_double = 5e-324;
  80. BignumDtoa(min_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  81. CHECK_EQ("5", buffer.start());
  82. CHECK_EQ(-323, point);
  83. BignumDtoa(min_double, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
  84. CHECK_GE(5, length - point);
  85. TrimRepresentation(buffer);
  86. CHECK_EQ("", buffer.start());
  87. BignumDtoa(min_double, BIGNUM_DTOA_PRECISION, 5, buffer, &length, &point);
  88. CHECK_GE(5, length);
  89. TrimRepresentation(buffer);
  90. CHECK_EQ("49407", buffer.start());
  91. CHECK_EQ(-323, point);
  92. double max_double = 1.7976931348623157e308;
  93. BignumDtoa(max_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  94. CHECK_EQ("17976931348623157", buffer.start());
  95. CHECK_EQ(309, point);
  96. BignumDtoa(max_double, BIGNUM_DTOA_PRECISION, 7, buffer, &length, &point);
  97. CHECK_GE(7, length);
  98. TrimRepresentation(buffer);
  99. CHECK_EQ("1797693", buffer.start());
  100. CHECK_EQ(309, point);
  101. BignumDtoa(4294967272.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  102. CHECK_EQ("4294967272", buffer.start());
  103. CHECK_EQ(10, point);
  104. BignumDtoa(4294967272.0, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
  105. CHECK_EQ("429496727200000", buffer.start());
  106. CHECK_EQ(10, point);
  107. BignumDtoa(4294967272.0, BIGNUM_DTOA_PRECISION, 14, buffer, &length, &point);
  108. CHECK_GE(14, length);
  109. TrimRepresentation(buffer);
  110. CHECK_EQ("4294967272", buffer.start());
  111. CHECK_EQ(10, point);
  112. BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_SHORTEST, 0,
  113. buffer, &length, &point);
  114. CHECK_EQ("4185580496821357", buffer.start());
  115. CHECK_EQ(299, point);
  116. BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_PRECISION, 20,
  117. buffer, &length, &point);
  118. CHECK_GE(20, length);
  119. TrimRepresentation(buffer);
  120. CHECK_EQ("41855804968213567225", buffer.start());
  121. CHECK_EQ(299, point);
  122. BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_SHORTEST, 0,
  123. buffer, &length, &point);
  124. CHECK_EQ("5562684646268003", buffer.start());
  125. CHECK_EQ(-308, point);
  126. BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_PRECISION, 1,
  127. buffer, &length, &point);
  128. CHECK_GE(1, length);
  129. TrimRepresentation(buffer);
  130. CHECK_EQ("6", buffer.start());
  131. CHECK_EQ(-308, point);
  132. BignumDtoa(2147483648.0, BIGNUM_DTOA_SHORTEST, 0,
  133. buffer, &length, &point);
  134. CHECK_EQ("2147483648", buffer.start());
  135. CHECK_EQ(10, point);
  136. BignumDtoa(2147483648.0, BIGNUM_DTOA_FIXED, 2,
  137. buffer, &length, &point);
  138. CHECK_GE(2, length - point);
  139. TrimRepresentation(buffer);
  140. CHECK_EQ("2147483648", buffer.start());
  141. CHECK_EQ(10, point);
  142. BignumDtoa(2147483648.0, BIGNUM_DTOA_PRECISION, 5,
  143. buffer, &length, &point);
  144. CHECK_GE(5, length);
  145. TrimRepresentation(buffer);
  146. CHECK_EQ("21475", buffer.start());
  147. CHECK_EQ(10, point);
  148. BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_SHORTEST, 0,
  149. buffer, &length, &point);
  150. CHECK_EQ("35844466002796428", buffer.start());
  151. CHECK_EQ(299, point);
  152. BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_PRECISION, 10,
  153. buffer, &length, &point);
  154. CHECK_GE(10, length);
  155. TrimRepresentation(buffer);
  156. CHECK_EQ("35844466", buffer.start());
  157. CHECK_EQ(299, point);
  158. uint64_t smallest_normal64 = UINT64_2PART_C(0x00100000, 00000000);
  159. double v = Double(smallest_normal64).value();
  160. BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  161. CHECK_EQ("22250738585072014", buffer.start());
  162. CHECK_EQ(-307, point);
  163. BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
  164. CHECK_GE(20, length);
  165. TrimRepresentation(buffer);
  166. CHECK_EQ("22250738585072013831", buffer.start());
  167. CHECK_EQ(-307, point);
  168. uint64_t largest_denormal64 = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
  169. v = Double(largest_denormal64).value();
  170. BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  171. CHECK_EQ("2225073858507201", buffer.start());
  172. CHECK_EQ(-307, point);
  173. BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
  174. CHECK_GE(20, length);
  175. TrimRepresentation(buffer);
  176. CHECK_EQ("2225073858507200889", buffer.start());
  177. CHECK_EQ(-307, point);
  178. BignumDtoa(4128420500802942e-24, BIGNUM_DTOA_SHORTEST, 0,
  179. buffer, &length, &point);
  180. CHECK_EQ("4128420500802942", buffer.start());
  181. CHECK_EQ(-8, point);
  182. v = 3.9292015898194142585311918e-10;
  183. BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  184. CHECK_EQ("39292015898194143", buffer.start());
  185. v = 4194304.0;
  186. BignumDtoa(v, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
  187. CHECK_GE(5, length - point);
  188. TrimRepresentation(buffer);
  189. CHECK_EQ("4194304", buffer.start());
  190. v = 3.3161339052167390562200598e-237;
  191. BignumDtoa(v, BIGNUM_DTOA_PRECISION, 19, buffer, &length, &point);
  192. CHECK_GE(19, length);
  193. TrimRepresentation(buffer);
  194. CHECK_EQ("3316133905216739056", buffer.start());
  195. CHECK_EQ(-236, point);
  196. v = 7.9885183916008099497815232e+191;
  197. BignumDtoa(v, BIGNUM_DTOA_PRECISION, 4, buffer, &length, &point);
  198. CHECK_GE(4, length);
  199. TrimRepresentation(buffer);
  200. CHECK_EQ("7989", buffer.start());
  201. CHECK_EQ(192, point);
  202. v = 1.0000000000000012800000000e+17;
  203. BignumDtoa(v, BIGNUM_DTOA_FIXED, 1, buffer, &length, &point);
  204. CHECK_GE(1, length - point);
  205. TrimRepresentation(buffer);
  206. CHECK_EQ("100000000000000128", buffer.start());
  207. CHECK_EQ(18, point);
  208. }
  209. TEST(BignumDtoaShortestVariousFloats) {
  210. char buffer_container[kBufferSize];
  211. Vector<char> buffer(buffer_container, kBufferSize);
  212. int length;
  213. int point;
  214. float min_float = 1e-45f;
  215. BignumDtoa(min_float, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  216. buffer, &length, &point);
  217. CHECK_EQ("1", buffer.start());
  218. CHECK_EQ(-44, point);
  219. float max_float = 3.4028234e38f;
  220. BignumDtoa(max_float, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  221. buffer, &length, &point);
  222. CHECK_EQ("34028235", buffer.start());
  223. CHECK_EQ(39, point);
  224. BignumDtoa(4294967272.0f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  225. buffer, &length, &point);
  226. CHECK_EQ("42949673", buffer.start());
  227. CHECK_EQ(10, point);
  228. BignumDtoa(3.32306998946228968226e+35f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  229. buffer, &length, &point);
  230. CHECK_EQ("332307", buffer.start());
  231. CHECK_EQ(36, point);
  232. BignumDtoa(1.2341e-41f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  233. buffer, &length, &point);
  234. CHECK_EQ("12341", buffer.start());
  235. CHECK_EQ(-40, point);
  236. BignumDtoa(3.3554432e7, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  237. buffer, &length, &point);
  238. CHECK_EQ("33554432", buffer.start());
  239. CHECK_EQ(8, point);
  240. BignumDtoa(3.26494756798464e14f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  241. buffer, &length, &point);
  242. CHECK_EQ("32649476", buffer.start());
  243. CHECK_EQ(15, point);
  244. BignumDtoa(3.91132223637771935344e37f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
  245. buffer, &length, &point);
  246. CHECK_EQ("39113222", buffer.start());
  247. CHECK_EQ(38, point);
  248. uint32_t smallest_normal32 = 0x00800000;
  249. double v = Single(smallest_normal32).value();
  250. BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
  251. CHECK_EQ("11754944", buffer.start());
  252. CHECK_EQ(-37, point);
  253. uint32_t largest_denormal32 = 0x007FFFFF;
  254. v = Single(largest_denormal32).value();
  255. BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
  256. CHECK_EQ("11754942", buffer.start());
  257. CHECK_EQ(-37, point);
  258. }
  259. TEST(BignumDtoaGayShortest) {
  260. char buffer_container[kBufferSize];
  261. Vector<char> buffer(buffer_container, kBufferSize);
  262. int length;
  263. int point;
  264. Vector<const PrecomputedShortest> precomputed =
  265. PrecomputedShortestRepresentations();
  266. for (int i = 0; i < precomputed.length(); ++i) {
  267. const PrecomputedShortest current_test = precomputed[i];
  268. double v = current_test.v;
  269. BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
  270. CHECK_EQ(current_test.decimal_point, point);
  271. CHECK_EQ(current_test.representation, buffer.start());
  272. }
  273. }
  274. TEST(BignumDtoaGayShortestSingle) {
  275. char buffer_container[kBufferSize];
  276. Vector<char> buffer(buffer_container, kBufferSize);
  277. int length;
  278. int point;
  279. Vector<const PrecomputedShortestSingle> precomputed =
  280. PrecomputedShortestSingleRepresentations();
  281. for (int i = 0; i < precomputed.length(); ++i) {
  282. const PrecomputedShortestSingle current_test = precomputed[i];
  283. float v = current_test.v;
  284. BignumDtoa(v, BIGNUM_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
  285. CHECK_EQ(current_test.decimal_point, point);
  286. CHECK_EQ(current_test.representation, buffer.start());
  287. }
  288. }
  289. TEST(BignumDtoaGayFixed) {
  290. char buffer_container[kBufferSize];
  291. Vector<char> buffer(buffer_container, kBufferSize);
  292. int length;
  293. int point;
  294. Vector<const PrecomputedFixed> precomputed =
  295. PrecomputedFixedRepresentations();
  296. for (int i = 0; i < precomputed.length(); ++i) {
  297. const PrecomputedFixed current_test = precomputed[i];
  298. double v = current_test.v;
  299. int number_digits = current_test.number_digits;
  300. BignumDtoa(v, BIGNUM_DTOA_FIXED, number_digits, buffer, &length, &point);
  301. CHECK_EQ(current_test.decimal_point, point);
  302. CHECK_GE(number_digits, length - point);
  303. TrimRepresentation(buffer);
  304. CHECK_EQ(current_test.representation, buffer.start());
  305. }
  306. }
  307. TEST(BignumDtoaGayPrecision) {
  308. char buffer_container[kBufferSize];
  309. Vector<char> buffer(buffer_container, kBufferSize);
  310. int length;
  311. int point;
  312. Vector<const PrecomputedPrecision> precomputed =
  313. PrecomputedPrecisionRepresentations();
  314. for (int i = 0; i < precomputed.length(); ++i) {
  315. const PrecomputedPrecision current_test = precomputed[i];
  316. double v = current_test.v;
  317. int number_digits = current_test.number_digits;
  318. BignumDtoa(v, BIGNUM_DTOA_PRECISION, number_digits,
  319. buffer, &length, &point);
  320. CHECK_EQ(current_test.decimal_point, point);
  321. CHECK_GE(number_digits, length);
  322. TrimRepresentation(buffer);
  323. CHECK_EQ(current_test.representation, buffer.start());
  324. }
  325. }