dtoa.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. /*
  2. * Copyright 2010-2025 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
  4. */
  5. #include <bx/cpu.h>
  6. #include <bx/math.h>
  7. #include <bx/string.h>
  8. #include <bx/uint32_t.h>
  9. namespace bx
  10. {
  11. /*
  12. * https://github.com/miloyip/dtoa-benchmark
  13. *
  14. * Copyright (C) 2014 Milo Yip
  15. *
  16. * Permission is hereby granted, free of charge, to any person obtaining a copy
  17. * of this software and associated documentation files (the "Software"), to deal
  18. * in the Software without restriction, including without limitation the rights
  19. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  20. * copies of the Software, and to permit persons to whom the Software is
  21. * furnished to do so, subject to the following conditions:
  22. *
  23. * The above copyright notice and this permission notice shall be included in
  24. * all copies or substantial portions of the Software.
  25. *
  26. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  27. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  28. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  29. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  30. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  31. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  32. * THE SOFTWARE.
  33. *
  34. */
  35. struct DiyFp
  36. {
  37. DiyFp()
  38. {
  39. }
  40. DiyFp(uint64_t _f, int32_t _e)
  41. : f(_f)
  42. , e(_e)
  43. {
  44. }
  45. DiyFp(double d)
  46. {
  47. union
  48. {
  49. double d;
  50. uint64_t u64;
  51. } u = { d };
  52. int32_t biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
  53. uint64_t significand = (u.u64 & kDpSignificandMask);
  54. if (biased_e != 0)
  55. {
  56. f = significand + kDpHiddenBit;
  57. e = biased_e - kDpExponentBias;
  58. }
  59. else
  60. {
  61. f = significand;
  62. e = kDpMinExponent + 1;
  63. }
  64. }
  65. DiyFp operator-(const DiyFp& rhs) const
  66. {
  67. BX_ASSERT(e == rhs.e, "");
  68. BX_ASSERT(f >= rhs.f, "");
  69. return DiyFp(f - rhs.f, e);
  70. }
  71. DiyFp operator*(const DiyFp& rhs) const
  72. {
  73. const uint64_t M32 = UINT32_MAX;
  74. const uint64_t a = f >> 32;
  75. const uint64_t b = f & M32;
  76. const uint64_t c = rhs.f >> 32;
  77. const uint64_t d = rhs.f & M32;
  78. const uint64_t ac = a * c;
  79. const uint64_t bc = b * c;
  80. const uint64_t ad = a * d;
  81. const uint64_t bd = b * d;
  82. uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
  83. tmp += 1U << 31; /// mult_round
  84. return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
  85. }
  86. DiyFp Normalize() const
  87. {
  88. uint8_t s = countLeadingZeros(f);
  89. return DiyFp(f << s, e - s);
  90. }
  91. DiyFp NormalizeBoundary() const
  92. {
  93. uint8_t index = countLeadingZeros(f);
  94. return DiyFp (f << index, e - index);
  95. }
  96. void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const
  97. {
  98. DiyFp pl = DiyFp( (f << 1) + 1, e - 1).NormalizeBoundary();
  99. DiyFp mi = (f == kDpHiddenBit) ? DiyFp( (f << 2) - 1, e - 2) : DiyFp( (f << 1) - 1, e - 1);
  100. mi.f <<= mi.e - pl.e;
  101. mi.e = pl.e;
  102. *plus = pl;
  103. *minus = mi;
  104. }
  105. #define UINT64_C2(h, l) ( (static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l) )
  106. static const int32_t kDiySignificandSize = 64;
  107. static const int32_t kDpSignificandSize = 52;
  108. static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize;
  109. static const int32_t kDpMinExponent = -kDpExponentBias;
  110. static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
  111. static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
  112. static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000);
  113. uint64_t f;
  114. int32_t e;
  115. };
  116. // 10^-348, 10^-340, ..., 10^340
  117. static const uint64_t s_kCachedPowers_F[] =
  118. {
  119. UINT64_C2(0xfa8fd5a0, 0x081c0288), UINT64_C2(0xbaaee17f, 0xa23ebf76),
  120. UINT64_C2(0x8b16fb20, 0x3055ac76), UINT64_C2(0xcf42894a, 0x5dce35ea),
  121. UINT64_C2(0x9a6bb0aa, 0x55653b2d), UINT64_C2(0xe61acf03, 0x3d1a45df),
  122. UINT64_C2(0xab70fe17, 0xc79ac6ca), UINT64_C2(0xff77b1fc, 0xbebcdc4f),
  123. UINT64_C2(0xbe5691ef, 0x416bd60c), UINT64_C2(0x8dd01fad, 0x907ffc3c),
  124. UINT64_C2(0xd3515c28, 0x31559a83), UINT64_C2(0x9d71ac8f, 0xada6c9b5),
  125. UINT64_C2(0xea9c2277, 0x23ee8bcb), UINT64_C2(0xaecc4991, 0x4078536d),
  126. UINT64_C2(0x823c1279, 0x5db6ce57), UINT64_C2(0xc2109436, 0x4dfb5637),
  127. UINT64_C2(0x9096ea6f, 0x3848984f), UINT64_C2(0xd77485cb, 0x25823ac7),
  128. UINT64_C2(0xa086cfcd, 0x97bf97f4), UINT64_C2(0xef340a98, 0x172aace5),
  129. UINT64_C2(0xb23867fb, 0x2a35b28e), UINT64_C2(0x84c8d4df, 0xd2c63f3b),
  130. UINT64_C2(0xc5dd4427, 0x1ad3cdba), UINT64_C2(0x936b9fce, 0xbb25c996),
  131. UINT64_C2(0xdbac6c24, 0x7d62a584), UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
  132. UINT64_C2(0xf3e2f893, 0xdec3f126), UINT64_C2(0xb5b5ada8, 0xaaff80b8),
  133. UINT64_C2(0x87625f05, 0x6c7c4a8b), UINT64_C2(0xc9bcff60, 0x34c13053),
  134. UINT64_C2(0x964e858c, 0x91ba2655), UINT64_C2(0xdff97724, 0x70297ebd),
  135. UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), UINT64_C2(0xf8a95fcf, 0x88747d94),
  136. UINT64_C2(0xb9447093, 0x8fa89bcf), UINT64_C2(0x8a08f0f8, 0xbf0f156b),
  137. UINT64_C2(0xcdb02555, 0x653131b6), UINT64_C2(0x993fe2c6, 0xd07b7fac),
  138. UINT64_C2(0xe45c10c4, 0x2a2b3b06), UINT64_C2(0xaa242499, 0x697392d3),
  139. UINT64_C2(0xfd87b5f2, 0x8300ca0e), UINT64_C2(0xbce50864, 0x92111aeb),
  140. UINT64_C2(0x8cbccc09, 0x6f5088cc), UINT64_C2(0xd1b71758, 0xe219652c),
  141. UINT64_C2(0x9c400000, 0x00000000), UINT64_C2(0xe8d4a510, 0x00000000),
  142. UINT64_C2(0xad78ebc5, 0xac620000), UINT64_C2(0x813f3978, 0xf8940984),
  143. UINT64_C2(0xc097ce7b, 0xc90715b3), UINT64_C2(0x8f7e32ce, 0x7bea5c70),
  144. UINT64_C2(0xd5d238a4, 0xabe98068), UINT64_C2(0x9f4f2726, 0x179a2245),
  145. UINT64_C2(0xed63a231, 0xd4c4fb27), UINT64_C2(0xb0de6538, 0x8cc8ada8),
  146. UINT64_C2(0x83c7088e, 0x1aab65db), UINT64_C2(0xc45d1df9, 0x42711d9a),
  147. UINT64_C2(0x924d692c, 0xa61be758), UINT64_C2(0xda01ee64, 0x1a708dea),
  148. UINT64_C2(0xa26da399, 0x9aef774a), UINT64_C2(0xf209787b, 0xb47d6b85),
  149. UINT64_C2(0xb454e4a1, 0x79dd1877), UINT64_C2(0x865b8692, 0x5b9bc5c2),
  150. UINT64_C2(0xc83553c5, 0xc8965d3d), UINT64_C2(0x952ab45c, 0xfa97a0b3),
  151. UINT64_C2(0xde469fbd, 0x99a05fe3), UINT64_C2(0xa59bc234, 0xdb398c25),
  152. UINT64_C2(0xf6c69a72, 0xa3989f5c), UINT64_C2(0xb7dcbf53, 0x54e9bece),
  153. UINT64_C2(0x88fcf317, 0xf22241e2), UINT64_C2(0xcc20ce9b, 0xd35c78a5),
  154. UINT64_C2(0x98165af3, 0x7b2153df), UINT64_C2(0xe2a0b5dc, 0x971f303a),
  155. UINT64_C2(0xa8d9d153, 0x5ce3b396), UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
  156. UINT64_C2(0xbb764c4c, 0xa7a44410), UINT64_C2(0x8bab8eef, 0xb6409c1a),
  157. UINT64_C2(0xd01fef10, 0xa657842c), UINT64_C2(0x9b10a4e5, 0xe9913129),
  158. UINT64_C2(0xe7109bfb, 0xa19c0c9d), UINT64_C2(0xac2820d9, 0x623bf429),
  159. UINT64_C2(0x80444b5e, 0x7aa7cf85), UINT64_C2(0xbf21e440, 0x03acdd2d),
  160. UINT64_C2(0x8e679c2f, 0x5e44ff8f), UINT64_C2(0xd433179d, 0x9c8cb841),
  161. UINT64_C2(0x9e19db92, 0xb4e31ba9), UINT64_C2(0xeb96bf6e, 0xbadf77d9),
  162. UINT64_C2(0xaf87023b, 0x9bf0ee6b)
  163. };
  164. static const int16_t s_kCachedPowers_E[] =
  165. {
  166. -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
  167. -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
  168. -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
  169. -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
  170. -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
  171. 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
  172. 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
  173. 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
  174. 907, 933, 960, 986, 1013, 1039, 1066
  175. };
  176. static const char s_cDigitsLut[200] =
  177. {
  178. '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
  179. '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
  180. '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
  181. '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
  182. '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
  183. '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
  184. '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
  185. '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
  186. '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
  187. '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
  188. };
  189. static const uint32_t s_kPow10[] =
  190. {
  191. 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
  192. };
  193. DiyFp GetCachedPower(int32_t e, int32_t* K)
  194. {
  195. double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
  196. int32_t k = static_cast<int32_t>(dk);
  197. if (k != dk)
  198. {
  199. k++;
  200. }
  201. uint32_t index = static_cast<uint32_t>( (k >> 3) + 1);
  202. *K = -(-348 + static_cast<int32_t>(index << 3) ); // decimal exponent no need lookup table
  203. BX_ASSERT(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]), "");
  204. return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]);
  205. }
  206. void GrisuRound(char* buffer, int32_t len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w)
  207. {
  208. while (rest < wp_w
  209. && delta - rest >= ten_kappa
  210. && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w) )
  211. {
  212. buffer[len - 1]--;
  213. rest += ten_kappa;
  214. }
  215. }
  216. uint32_t CountDecimalDigit32(uint32_t n)
  217. {
  218. // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
  219. if (n < 10) return 1;
  220. if (n < 100) return 2;
  221. if (n < 1000) return 3;
  222. if (n < 10000) return 4;
  223. if (n < 100000) return 5;
  224. if (n < 1000000) return 6;
  225. if (n < 10000000) return 7;
  226. if (n < 100000000) return 8;
  227. if (n < 1000000000) return 9;
  228. return 10;
  229. }
  230. void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int32_t* len, int32_t* K)
  231. {
  232. const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
  233. const DiyFp wp_w = Mp - W;
  234. uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
  235. uint64_t p2 = Mp.f & (one.f - 1);
  236. int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1) );
  237. *len = 0;
  238. while (kappa > 0)
  239. {
  240. uint32_t d;
  241. switch (kappa)
  242. {
  243. case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
  244. case 9: d = p1 / 100000000; p1 %= 100000000; break;
  245. case 8: d = p1 / 10000000; p1 %= 10000000; break;
  246. case 7: d = p1 / 1000000; p1 %= 1000000; break;
  247. case 6: d = p1 / 100000; p1 %= 100000; break;
  248. case 5: d = p1 / 10000; p1 %= 10000; break;
  249. case 4: d = p1 / 1000; p1 %= 1000; break;
  250. case 3: d = p1 / 100; p1 %= 100; break;
  251. case 2: d = p1 / 10; p1 %= 10; break;
  252. case 1: d = p1; p1 = 0; break;
  253. default:
  254. d = 0;
  255. break;
  256. }
  257. if (d || *len)
  258. {
  259. buffer[(*len)++] = '0' + static_cast<char>(d);
  260. }
  261. kappa--;
  262. uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
  263. if (tmp <= delta)
  264. {
  265. *K += kappa;
  266. GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(s_kPow10[kappa]) << -one.e, wp_w.f);
  267. return;
  268. }
  269. }
  270. // kappa = 0
  271. for (;;)
  272. {
  273. p2 *= 10;
  274. delta *= 10;
  275. char d = static_cast<char>(p2 >> -one.e);
  276. if (d || *len)
  277. {
  278. buffer[(*len)++] = '0' + d;
  279. }
  280. p2 &= one.f - 1;
  281. kappa--;
  282. if (p2 < delta)
  283. {
  284. *K += kappa;
  285. const int index = -static_cast<int>(kappa);
  286. GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? s_kPow10[-static_cast<int>(kappa)] : 0));
  287. return;
  288. }
  289. }
  290. }
  291. void Grisu2(double value, char* buffer, int32_t* length, int32_t* K)
  292. {
  293. const DiyFp v(value);
  294. DiyFp w_m, w_p;
  295. v.NormalizedBoundaries(&w_m, &w_p);
  296. const DiyFp c_mk = GetCachedPower(w_p.e, K);
  297. const DiyFp W = v.Normalize() * c_mk;
  298. DiyFp Wp = w_p * c_mk;
  299. DiyFp Wm = w_m * c_mk;
  300. Wm.f++;
  301. Wp.f--;
  302. DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
  303. }
  304. int32_t WriteExponent(int32_t K, char* buffer)
  305. {
  306. const char* ptr = buffer;
  307. if (K < 0)
  308. {
  309. *buffer++ = '-';
  310. K = -K;
  311. }
  312. if (K >= 100)
  313. {
  314. *buffer++ = '0' + static_cast<char>(K / 100);
  315. K %= 100;
  316. const char* d = s_cDigitsLut + K * 2;
  317. *buffer++ = d[0];
  318. *buffer++ = d[1];
  319. }
  320. else if (K >= 10)
  321. {
  322. const char* d = s_cDigitsLut + K * 2;
  323. *buffer++ = d[0];
  324. *buffer++ = d[1];
  325. }
  326. else
  327. {
  328. *buffer++ = '0' + static_cast<char>(K);
  329. }
  330. *buffer = '\0';
  331. return int32_t(buffer - ptr);
  332. }
  333. int32_t Prettify(char* buffer, int32_t length, int32_t k)
  334. {
  335. const int32_t kk = length + k; // 10^(kk-1) <= v < 10^kk
  336. if (length <= kk && kk <= 21)
  337. {
  338. // 1234e7 -> 12340000000
  339. for (int32_t i = length; i < kk; i++)
  340. {
  341. buffer[i] = '0';
  342. }
  343. buffer[kk] = '.';
  344. buffer[kk + 1] = '0';
  345. buffer[kk + 2] = '\0';
  346. return kk + 2;
  347. }
  348. if (0 < kk && kk <= 21)
  349. {
  350. // 1234e-2 -> 12.34
  351. memMove(&buffer[kk + 1], &buffer[kk], length - kk);
  352. buffer[kk] = '.';
  353. buffer[length + 1] = '\0';
  354. return length + 1;
  355. }
  356. if (-6 < kk && kk <= 0)
  357. {
  358. // 1234e-6 -> 0.001234
  359. const int32_t offset = 2 - kk;
  360. memMove(&buffer[offset], &buffer[0], length);
  361. buffer[0] = '0';
  362. buffer[1] = '.';
  363. for (int32_t i = 2; i < offset; i++)
  364. {
  365. buffer[i] = '0';
  366. }
  367. buffer[length + offset] = '\0';
  368. return length + offset;
  369. }
  370. if (length == 1)
  371. {
  372. // 1e30
  373. buffer[1] = 'e';
  374. int32_t exp = WriteExponent(kk - 1, &buffer[2]);
  375. return 2 + exp;
  376. }
  377. // 1234e30 -> 1.234e33
  378. memMove(&buffer[2], &buffer[1], length - 1);
  379. buffer[1] = '.';
  380. buffer[length + 1] = 'e';
  381. int32_t exp = WriteExponent(kk - 1, &buffer[length + 2]);
  382. return length + 2 + exp;
  383. }
  384. int32_t toString(char* _dst, int32_t _max, double _value)
  385. {
  386. int32_t sign = 0 != (doubleToBits(_value) & kDoubleSignMask) ? 1 : 0;
  387. if (1 == sign)
  388. {
  389. *_dst++ = '-';
  390. --_max;
  391. _value = -_value;
  392. }
  393. if (isNan(_value) )
  394. {
  395. return (int32_t)strCopy(_dst, _max, "nan") + sign;
  396. }
  397. else if (isInfinite(_value) )
  398. {
  399. return (int32_t)strCopy(_dst, _max, "inf") + sign;
  400. }
  401. int32_t len;
  402. if (0.0 == _value)
  403. {
  404. len = (int32_t)strCopy(_dst, _max, "0.0");
  405. }
  406. else
  407. {
  408. int32_t kk;
  409. Grisu2(_value, _dst, &len, &kk);
  410. len = Prettify(_dst, len, kk);
  411. }
  412. return len + sign;
  413. }
  414. static void reverse(char* _dst, int32_t _len)
  415. {
  416. for (int32_t ii = 0, jj = _len - 1; ii < jj; ++ii, --jj)
  417. {
  418. swap(_dst[ii], _dst[jj]);
  419. }
  420. }
  421. template<typename Ty>
  422. int32_t toStringSigned(char* _dst, int32_t _max, Ty _value, uint32_t _base, char _separator)
  423. {
  424. if (_base == 10
  425. && _value < 0)
  426. {
  427. if (_max < 1)
  428. {
  429. return 0;
  430. }
  431. _max = toString(_dst + 1, _max - 1, asUnsigned(-_value), _base, _separator);
  432. if (_max == 0)
  433. {
  434. return 0;
  435. }
  436. *_dst = '-';
  437. return int32_t(_max + 1);
  438. }
  439. return toString(_dst, _max, asUnsigned(_value), _base, _separator);
  440. }
  441. int32_t toString(char* _dst, int32_t _max, int32_t _value, uint32_t _base, char _separator)
  442. {
  443. return toStringSigned(_dst, _max, _value, _base, _separator);
  444. }
  445. int32_t toString(char* _dst, int32_t _max, int64_t _value, uint32_t _base, char _separator)
  446. {
  447. return toStringSigned(_dst, _max, _value, _base, _separator);
  448. }
  449. template<typename Ty>
  450. int32_t toStringUnsigned(char* _dst, int32_t _max, Ty _value, uint32_t _base, char _separator)
  451. {
  452. char data[32];
  453. int32_t len = 0;
  454. if (_base > 16
  455. || _base < 2)
  456. {
  457. return 0;
  458. }
  459. uint32_t count = 1;
  460. do
  461. {
  462. const Ty rem = _value % _base;
  463. _value /= _base;
  464. if (rem < 10)
  465. {
  466. data[len++] = char('0' + rem);
  467. }
  468. else
  469. {
  470. data[len++] = char('a' + rem - 10);
  471. }
  472. if ('\0' != _separator
  473. && 0 == count%3
  474. && 0 != _value)
  475. {
  476. data[len++] = _separator;
  477. }
  478. ++count;
  479. }
  480. while (0 != _value);
  481. if (_max < len + 1)
  482. {
  483. return 0;
  484. }
  485. reverse(data, len);
  486. memCopy(_dst, data, len);
  487. _dst[len] = '\0';
  488. return int32_t(len);
  489. }
  490. int32_t toString(char* _dst, int32_t _max, uint32_t _value, uint32_t _base, char _separator)
  491. {
  492. return toStringUnsigned(_dst, _max, _value, _base, _separator);
  493. }
  494. int32_t toString(char* _dst, int32_t _max, uint64_t _value, uint32_t _base, char _separator)
  495. {
  496. return toStringUnsigned(_dst, _max, _value, _base, _separator);
  497. }
  498. /*
  499. * https://github.com/grzegorz-kraszewski/stringtofloat/
  500. *
  501. * MIT License
  502. *
  503. * Copyright (c) 2016 Grzegorz Kraszewski
  504. *
  505. * Permission is hereby granted, free of charge, to any person obtaining a copy
  506. * of this software and associated documentation files (the "Software"), to deal
  507. * in the Software without restriction, including without limitation the rights
  508. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  509. * copies of the Software, and to permit persons to whom the Software is
  510. * furnished to do so, subject to the following conditions:
  511. *
  512. * The above copyright notice and this permission notice shall be included in all
  513. * copies or substantial portions of the Software.
  514. *
  515. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  516. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  517. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  518. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  519. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  520. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  521. * SOFTWARE.
  522. */
  523. /*
  524. * IMPORTANT
  525. *
  526. * The code works in "round towards zero" mode. This is different from
  527. * GCC standard library strtod(), which uses "round half to even" rule.
  528. * Therefore it cannot be used as a direct drop-in replacement, as in
  529. * some cases results will be different on the least significant bit of
  530. * mantissa. Read more in the README.md file.
  531. */
  532. #define DIGITS 18
  533. #define DOUBLE_PLUS_ZERO UINT64_C(0x0000000000000000)
  534. #define DOUBLE_MINUS_ZERO UINT64_C(0x8000000000000000)
  535. #define DOUBLE_PLUS_INFINITY UINT64_C(0x7ff0000000000000)
  536. #define DOUBLE_MINUS_INFINITY UINT64_C(0xfff0000000000000)
  537. #define lsr96(s2, s1, s0, d2, d1, d0) \
  538. d0 = ( (s0) >> 1) | ( ( (s1) & 1) << 31); \
  539. d1 = ( (s1) >> 1) | ( ( (s2) & 1) << 31); \
  540. d2 = (s2) >> 1;
  541. #define lsl96(s2, s1, s0, d2, d1, d0) \
  542. d2 = ( (s2) << 1) | ( ( (s1) & (1 << 31) ) >> 31); \
  543. d1 = ( (s1) << 1) | ( ( (s0) & (1 << 31) ) >> 31); \
  544. d0 = (s0) << 1;
  545. /*
  546. * Undefine the below constant if your processor or compiler is slow
  547. * at 64-bit arithmetic. This is a rare case however. 64-bit macros are
  548. * better for deeply pipelined CPUs (no conditional execution), are
  549. * very efficient for 64-bit processors and also fast on 32-bit processors
  550. * featuring extended precision arithmetic (x86, PowerPC_32, M68k and probably
  551. * more).
  552. */
  553. #define USE_64BIT_FOR_ADDSUB_MACROS 0
  554. #if USE_64BIT_FOR_ADDSUB_MACROS
  555. #define add96(s2, s1, s0, d2, d1, d0) { \
  556. uint64_t w; \
  557. w = (uint64_t)(s0) + (uint64_t)(d0); \
  558. (s0) = w; \
  559. w >>= 32; \
  560. w += (uint64_t)(s1) + (uint64_t)(d1); \
  561. (s1) = w; \
  562. w >>= 32; \
  563. w += (uint64_t)(s2) + (uint64_t)(d2); \
  564. (s2) = w; }
  565. #define sub96(s2, s1, s0, d2, d1, d0) { \
  566. uint64_t w; \
  567. w = (uint64_t)(s0) - (uint64_t)(d0); \
  568. (s0) = w; \
  569. w >>= 32; \
  570. w += (uint64_t)(s1) - (uint64_t)(d1); \
  571. (s1) = w; \
  572. w >>= 32; \
  573. w += (uint64_t)(s2) - (uint64_t)(d2); \
  574. (s2) = w; }
  575. #else
  576. #define add96(s2, s1, s0, d2, d1, d0) { \
  577. uint32_t _x, _c; \
  578. _x = (s0); (s0) += (d0); \
  579. if ( (s0) < _x) _c = 1; else _c = 0; \
  580. _x = (s1); (s1) += (d1) + _c; \
  581. if ( ( (s1) < _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \
  582. (s2) += (d2) + _c; }
  583. #define sub96(s2, s1, s0, d2, d1, d0) { \
  584. uint32_t _x, _c; \
  585. _x = (s0); (s0) -= (d0); \
  586. if ( (s0) > _x) _c = 1; else _c = 0; \
  587. _x = (s1); (s1) -= (d1) + _c; \
  588. if ( ( (s1) > _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \
  589. (s2) -= (d2) + _c; }
  590. #endif /* USE_64BIT_FOR_ADDSUB_MACROS */
  591. /* parser state machine states */
  592. #define FSM_A 0
  593. #define FSM_B 1
  594. #define FSM_C 2
  595. #define FSM_D 3
  596. #define FSM_E 4
  597. #define FSM_F 5
  598. #define FSM_G 6
  599. #define FSM_H 7
  600. #define FSM_I 8
  601. #define FSM_STOP 9
  602. /* The structure is filled by parser, then given to converter. */
  603. struct PrepNumber
  604. {
  605. int negative; /* 0 if positive number, 1 if negative */
  606. int32_t exponent; /* power of 10 exponent */
  607. uint64_t mantissa; /* integer mantissa */
  608. };
  609. /* Possible parser return values. */
  610. #define PARSER_OK 0 // parser finished OK
  611. #define PARSER_PZERO 1 // no digits or number is smaller than +-2^-1022
  612. #define PARSER_MZERO 2 // number is negative, module smaller
  613. #define PARSER_PINF 3 // number is higher than +HUGE_VAL
  614. #define PARSER_MINF 4 // number is lower than -HUGE_VAL
  615. inline char next(const char*& _s, const char* _term)
  616. {
  617. return _s != _term
  618. ? *_s++
  619. : '\0'
  620. ;
  621. }
  622. static int parser(const char* _s, const char* _term, PrepNumber* _pn)
  623. {
  624. int state = FSM_A;
  625. int digx = 0;
  626. char c = ' '; /* initial value for kicking off the state machine */
  627. int result = PARSER_OK;
  628. int expneg = 0;
  629. int32_t expexp = 0;
  630. while (state != FSM_STOP) // && _s != _term)
  631. {
  632. switch (state)
  633. {
  634. case FSM_A:
  635. if (isSpace(c) )
  636. {
  637. c = next(_s, _term);
  638. }
  639. else
  640. {
  641. state = FSM_B;
  642. }
  643. break;
  644. case FSM_B:
  645. state = FSM_C;
  646. if (c == '+')
  647. {
  648. c = next(_s, _term);
  649. }
  650. else if (c == '-')
  651. {
  652. _pn->negative = 1;
  653. c = next(_s, _term);
  654. }
  655. else if (isNumeric(c) )
  656. {
  657. }
  658. else if (c == '.')
  659. {
  660. }
  661. else
  662. {
  663. state = FSM_STOP;
  664. }
  665. break;
  666. case FSM_C:
  667. if (c == '0')
  668. {
  669. c = next(_s, _term);
  670. }
  671. else if (c == '.')
  672. {
  673. c = next(_s, _term);
  674. state = FSM_D;
  675. }
  676. else
  677. {
  678. state = FSM_E;
  679. }
  680. break;
  681. case FSM_D:
  682. if (c == '0')
  683. {
  684. c = next(_s, _term);
  685. if (_pn->exponent > -2147483647) _pn->exponent--;
  686. }
  687. else
  688. {
  689. state = FSM_F;
  690. }
  691. break;
  692. case FSM_E:
  693. if (isNumeric(c) )
  694. {
  695. if (digx < DIGITS)
  696. {
  697. _pn->mantissa *= 10;
  698. _pn->mantissa += c - '0';
  699. digx++;
  700. }
  701. else if (_pn->exponent < 2147483647)
  702. {
  703. _pn->exponent++;
  704. }
  705. c = next(_s, _term);
  706. }
  707. else if (c == '.')
  708. {
  709. c = next(_s, _term);
  710. state = FSM_F;
  711. }
  712. else
  713. {
  714. state = FSM_F;
  715. }
  716. break;
  717. case FSM_F:
  718. if (isNumeric(c) )
  719. {
  720. if (digx < DIGITS)
  721. {
  722. _pn->mantissa *= 10;
  723. _pn->mantissa += c - '0';
  724. _pn->exponent--;
  725. digx++;
  726. }
  727. c = next(_s, _term);
  728. }
  729. else if ('e' == toLower(c) )
  730. {
  731. c = next(_s, _term);
  732. state = FSM_G;
  733. }
  734. else
  735. {
  736. state = FSM_G;
  737. }
  738. break;
  739. case FSM_G:
  740. if (c == '+')
  741. {
  742. c = next(_s, _term);
  743. }
  744. else if (c == '-')
  745. {
  746. expneg = 1;
  747. c = next(_s, _term);
  748. }
  749. state = FSM_H;
  750. break;
  751. case FSM_H:
  752. if (c == '0')
  753. {
  754. c = next(_s, _term);
  755. }
  756. else
  757. {
  758. state = FSM_I;
  759. }
  760. break;
  761. case FSM_I:
  762. if (isNumeric(c) )
  763. {
  764. if (expexp < 214748364)
  765. {
  766. expexp *= 10;
  767. expexp += c - '0';
  768. }
  769. c = next(_s, _term);
  770. }
  771. else
  772. {
  773. state = FSM_STOP;
  774. }
  775. break;
  776. }
  777. }
  778. if (expneg)
  779. {
  780. expexp = -expexp;
  781. }
  782. _pn->exponent += expexp;
  783. if (_pn->mantissa == 0)
  784. {
  785. if (_pn->negative)
  786. {
  787. result = PARSER_MZERO;
  788. }
  789. else
  790. {
  791. result = PARSER_PZERO;
  792. }
  793. }
  794. else if (_pn->exponent > 309)
  795. {
  796. if (_pn->negative)
  797. {
  798. result = PARSER_MINF;
  799. }
  800. else
  801. {
  802. result = PARSER_PINF;
  803. }
  804. }
  805. else if (_pn->exponent < -328)
  806. {
  807. if (_pn->negative)
  808. {
  809. result = PARSER_MZERO;
  810. }
  811. else
  812. {
  813. result = PARSER_PZERO;
  814. }
  815. }
  816. return result;
  817. }
  818. static double converter(PrepNumber* _pn)
  819. {
  820. int binexp = 92;
  821. uint32_t s2, s1, s0; /* 96-bit precision integer */
  822. uint32_t q2, q1, q0; /* 96-bit precision integer */
  823. uint32_t r2, r1, r0; /* 96-bit precision integer */
  824. uint32_t mask28 = UINT32_C(0xf) << 28;
  825. uint64_t hdu = 0;
  826. s0 = (uint32_t)(_pn->mantissa & UINT32_MAX);
  827. s1 = (uint32_t)(_pn->mantissa >> 32);
  828. s2 = 0;
  829. while (_pn->exponent > 0)
  830. {
  831. lsl96(s2, s1, s0, q2, q1, q0); // q = p << 1
  832. lsl96(q2, q1, q0, r2, r1, r0); // r = p << 2
  833. lsl96(r2, r1, r0, s2, s1, s0); // p = p << 3
  834. add96(s2, s1, s0, q2, q1, q0); // p = (p << 3) + (p << 1)
  835. _pn->exponent--;
  836. while (s2 & mask28)
  837. {
  838. lsr96(s2, s1, s0, q2, q1, q0);
  839. binexp++;
  840. s2 = q2;
  841. s1 = q1;
  842. s0 = q0;
  843. }
  844. }
  845. while (_pn->exponent < 0)
  846. {
  847. while (!(s2 & (1 << 31) ) )
  848. {
  849. lsl96(s2, s1, s0, q2, q1, q0);
  850. binexp--;
  851. s2 = q2;
  852. s1 = q1;
  853. s0 = q0;
  854. }
  855. q2 = s2 / 10;
  856. r1 = s2 % 10;
  857. r2 = (s1 >> 8) | (r1 << 24);
  858. q1 = r2 / 10;
  859. r1 = r2 % 10;
  860. r2 = ( (s1 & 0xFF) << 16) | (s0 >> 16) | (r1 << 24);
  861. r0 = r2 / 10;
  862. r1 = r2 % 10;
  863. q1 = (q1 << 8) | ( (r0 & 0x00FF0000) >> 16);
  864. q0 = r0 << 16;
  865. r2 = (s0 & UINT16_MAX) | (r1 << 16);
  866. q0 |= r2 / 10;
  867. s2 = q2;
  868. s1 = q1;
  869. s0 = q0;
  870. _pn->exponent++;
  871. }
  872. if (s2 || s1 || s0)
  873. {
  874. while (!(s2 & mask28) )
  875. {
  876. lsl96(s2, s1, s0, q2, q1, q0);
  877. binexp--;
  878. s2 = q2;
  879. s1 = q1;
  880. s0 = q0;
  881. }
  882. }
  883. binexp += 1023;
  884. if (binexp > 2046)
  885. {
  886. if (_pn->negative)
  887. {
  888. hdu = DOUBLE_MINUS_INFINITY;
  889. }
  890. else
  891. {
  892. hdu = DOUBLE_PLUS_INFINITY;
  893. }
  894. }
  895. else if (binexp < 1)
  896. {
  897. if (_pn->negative)
  898. {
  899. hdu = DOUBLE_MINUS_ZERO;
  900. }
  901. }
  902. else if (s2)
  903. {
  904. uint64_t q;
  905. uint64_t binexs2 = (uint64_t)binexp;
  906. binexs2 <<= 52;
  907. q = ( (uint64_t)(s2 & ~mask28) << 24)
  908. | ( ( (uint64_t)s1 + 128) >> 8) | binexs2;
  909. if (_pn->negative)
  910. {
  911. q |= (1ULL << 63);
  912. }
  913. hdu = q;
  914. }
  915. return bitCast<double>(hdu);
  916. }
  917. int32_t toString(char* _out, int32_t _max, bool _value)
  918. {
  919. StringView str(_value ? "true" : "false");
  920. strCopy(_out, _max, str);
  921. return str.getLength();
  922. }
  923. bool fromString(bool* _out, const StringView& _str)
  924. {
  925. char ch = toLower(_str.getPtr()[0]);
  926. *_out = ch == 't' || ch == '1';
  927. return 0 != _str.getLength();
  928. }
  929. bool fromString(float* _out, const StringView& _str)
  930. {
  931. double dbl;
  932. bool result = fromString(&dbl, _str);
  933. *_out = float(dbl);
  934. return result;
  935. }
  936. bool fromString(double* _out, const StringView& _str)
  937. {
  938. PrepNumber pn;
  939. pn.mantissa = 0;
  940. pn.negative = 0;
  941. pn.exponent = 0;
  942. switch (parser(_str.getPtr(), _str.getTerm(), &pn) )
  943. {
  944. case PARSER_OK:
  945. *_out = converter(&pn);
  946. break;
  947. case PARSER_PZERO:
  948. *_out = bitCast<double>(DOUBLE_PLUS_ZERO);
  949. break;
  950. case PARSER_MZERO:
  951. *_out = bitCast<double>(DOUBLE_MINUS_ZERO);
  952. break;
  953. case PARSER_PINF:
  954. *_out = bitCast<double>(DOUBLE_PLUS_INFINITY);
  955. break;
  956. case PARSER_MINF:
  957. *_out = bitCast<double>(DOUBLE_MINUS_INFINITY);
  958. break;
  959. }
  960. return true;
  961. }
  962. bool fromString(int32_t* _out, const StringView& _str)
  963. {
  964. StringView str = strLTrimSpace(_str);
  965. const char* ptr = str.getPtr();
  966. const char* term = str.getTerm();
  967. char ch = *ptr++;
  968. bool neg = false;
  969. switch (ch)
  970. {
  971. case '-':
  972. case '+': neg = '-' == ch;
  973. break;
  974. default:
  975. --ptr;
  976. break;
  977. }
  978. int32_t result = 0;
  979. for (ch = *ptr++; isNumeric(ch) && ptr <= term; ch = *ptr++)
  980. {
  981. result = 10*result - (ch - '0');
  982. }
  983. *_out = neg ? result : -result;
  984. return true;
  985. }
  986. bool fromString(uint32_t* _out, const StringView& _str)
  987. {
  988. fromString( (int32_t*)_out, _str);
  989. return true;
  990. }
  991. } // namespace bx