Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 4e2dbb669434a7691662cb2f0ad38972 > files > 11584

rust-doc-1.28.0-1.mga6.armv7hl.rpm

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source to the Rust file `libcore/num/flt2dec/mod.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>mod.rs.html -- source</title><link rel="stylesheet" type="text/css" href="../../../../normalize.css"><link rel="stylesheet" type="text/css" href="../../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../../../dark.css"><link rel="stylesheet" type="text/css" href="../../../../light.css" id="themeStyle"><script src="../../../../storage.js"></script><link rel="shortcut icon" href="https://doc.rust-lang.org/favicon.ico"></head><body class="rustdoc source"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../../../../core/index.html'><img src='https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png' alt='logo' width='100'></a></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../../../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></div></div><script src="../../../../theme.js"></script><nav class="sub"><form class="search-form js-only"><div class="search-container"><input class="search-input" name="search" autocomplete="off" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><a id="settings-menu" href="../../../../settings.html"><img src="../../../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><pre class="line-numbers"><span id="1">  1</span>
<span id="2">  2</span>
<span id="3">  3</span>
<span id="4">  4</span>
<span id="5">  5</span>
<span id="6">  6</span>
<span id="7">  7</span>
<span id="8">  8</span>
<span id="9">  9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
<span id="536">536</span>
<span id="537">537</span>
<span id="538">538</span>
<span id="539">539</span>
<span id="540">540</span>
<span id="541">541</span>
<span id="542">542</span>
<span id="543">543</span>
<span id="544">544</span>
<span id="545">545</span>
<span id="546">546</span>
<span id="547">547</span>
<span id="548">548</span>
<span id="549">549</span>
<span id="550">550</span>
<span id="551">551</span>
<span id="552">552</span>
<span id="553">553</span>
<span id="554">554</span>
<span id="555">555</span>
<span id="556">556</span>
<span id="557">557</span>
<span id="558">558</span>
<span id="559">559</span>
<span id="560">560</span>
<span id="561">561</span>
<span id="562">562</span>
<span id="563">563</span>
<span id="564">564</span>
<span id="565">565</span>
<span id="566">566</span>
<span id="567">567</span>
<span id="568">568</span>
<span id="569">569</span>
<span id="570">570</span>
<span id="571">571</span>
<span id="572">572</span>
<span id="573">573</span>
<span id="574">574</span>
<span id="575">575</span>
<span id="576">576</span>
<span id="577">577</span>
<span id="578">578</span>
<span id="579">579</span>
<span id="580">580</span>
<span id="581">581</span>
<span id="582">582</span>
<span id="583">583</span>
<span id="584">584</span>
<span id="585">585</span>
<span id="586">586</span>
<span id="587">587</span>
<span id="588">588</span>
<span id="589">589</span>
<span id="590">590</span>
<span id="591">591</span>
<span id="592">592</span>
<span id="593">593</span>
<span id="594">594</span>
<span id="595">595</span>
<span id="596">596</span>
<span id="597">597</span>
<span id="598">598</span>
<span id="599">599</span>
<span id="600">600</span>
<span id="601">601</span>
<span id="602">602</span>
<span id="603">603</span>
<span id="604">604</span>
<span id="605">605</span>
<span id="606">606</span>
<span id="607">607</span>
<span id="608">608</span>
<span id="609">609</span>
<span id="610">610</span>
<span id="611">611</span>
<span id="612">612</span>
<span id="613">613</span>
<span id="614">614</span>
<span id="615">615</span>
<span id="616">616</span>
<span id="617">617</span>
<span id="618">618</span>
<span id="619">619</span>
<span id="620">620</span>
<span id="621">621</span>
<span id="622">622</span>
<span id="623">623</span>
<span id="624">624</span>
<span id="625">625</span>
<span id="626">626</span>
<span id="627">627</span>
<span id="628">628</span>
<span id="629">629</span>
<span id="630">630</span>
<span id="631">631</span>
<span id="632">632</span>
<span id="633">633</span>
<span id="634">634</span>
<span id="635">635</span>
<span id="636">636</span>
<span id="637">637</span>
<span id="638">638</span>
<span id="639">639</span>
<span id="640">640</span>
<span id="641">641</span>
<span id="642">642</span>
<span id="643">643</span>
<span id="644">644</span>
<span id="645">645</span>
<span id="646">646</span>
<span id="647">647</span>
<span id="648">648</span>
<span id="649">649</span>
<span id="650">650</span>
<span id="651">651</span>
<span id="652">652</span>
<span id="653">653</span>
<span id="654">654</span>
<span id="655">655</span>
<span id="656">656</span>
<span id="657">657</span>
<span id="658">658</span>
<span id="659">659</span>
<span id="660">660</span>
<span id="661">661</span>
</pre><pre class="rust ">
<span class="comment">// Copyright 2015 The Rust Project Developers. See the COPYRIGHT</span>
<span class="comment">// file at the top-level directory of this distribution and at</span>
<span class="comment">// http://rust-lang.org/COPYRIGHT.</span>
<span class="comment">//</span>
<span class="comment">// Licensed under the Apache License, Version 2.0 &lt;LICENSE-APACHE or</span>
<span class="comment">// http://www.apache.org/licenses/LICENSE-2.0&gt; or the MIT license</span>
<span class="comment">// &lt;LICENSE-MIT or http://opensource.org/licenses/MIT&gt;, at your</span>
<span class="comment">// option. This file may not be copied, modified, or distributed</span>
<span class="comment">// except according to those terms.</span>

<span class="doccomment">/*!

Floating-point number to decimal conversion routines.

# Problem statement

We are given the floating-point number `v = f * 2^e` with an integer `f`,
and its bounds `minus` and `plus` such that any number between `v - minus` and
`v + plus` will be rounded to `v`. For the simplicity we assume that
this range is exclusive. Then we would like to get the unique decimal
representation `V = 0.d[0..n-1] * 10^k` such that:

- `d[0]` is non-zero.

- It&#39;s correctly rounded when parsed back: `v - minus &lt; V &lt; v + plus`.
  Furthermore it is shortest such one, i.e. there is no representation
  with less than `n` digits that is correctly rounded.

- It&#39;s closest to the original value: `abs(V - v) &lt;= 10^(k-n) / 2`. Note that
  there might be two representations satisfying this uniqueness requirement,
  in which case some tie-breaking mechanism is used.

We will call this mode of operation as to the *shortest* mode. This mode is used
when there is no additional constraint, and can be thought as a &quot;natural&quot; mode
as it matches the ordinary intuition (it at least prints `0.1f32` as &quot;0.1&quot;).

We have two more modes of operation closely related to each other. In these modes
we are given either the number of significant digits `n` or the last-digit
limitation `limit` (which determines the actual `n`), and we would like to get
the representation `V = 0.d[0..n-1] * 10^k` such that:

- `d[0]` is non-zero, unless `n` was zero in which case only `k` is returned.

- It&#39;s closest to the original value: `abs(V - v) &lt;= 10^(k-n) / 2`. Again,
  there might be some tie-breaking mechanism.

When `limit` is given but not `n`, we set `n` such that `k - n = limit`
so that the last digit `d[n-1]` is scaled by `10^(k-n) = 10^limit`.
If such `n` is negative, we clip it to zero so that we will only get `k`.
We are also limited by the supplied buffer. This limitation is used to print
the number up to given number of fractional digits without knowing
the correct `k` beforehand.

We will call the mode of operation requiring `n` as to the *exact* mode,
and one requiring `limit` as to the *fixed* mode. The exact mode is a subset of
the fixed mode: the sufficiently large last-digit limitation will eventually fill
the supplied buffer and let the algorithm to return.

# Implementation overview

It is easy to get the floating point printing correct but slow (Russ Cox has
[demonstrated](http://research.swtch.com/ftoa) how it&#39;s easy), or incorrect but
fast (naïve division and modulo). But it is surprisingly hard to print
floating point numbers correctly *and* efficiently.

There are two classes of algorithms widely known to be correct.

- The &quot;Dragon&quot; family of algorithm is first described by Guy L. Steele Jr. and
  Jon L. White. They rely on the fixed-size big integer for their correctness.
  A slight improvement was found later, which is posthumously described by
  Robert G. Burger and R. Kent Dybvig. David Gay&#39;s `dtoa.c` routine is
  a popular implementation of this strategy.

- The &quot;Grisu&quot; family of algorithm is first described by Florian Loitsch.
  They use very cheap integer-only procedure to determine the close-to-correct
  representation which is at least guaranteed to be shortest. The variant,
  Grisu3, actively detects if the resulting representation is incorrect.

We implement both algorithms with necessary tweaks to suit our requirements.
In particular, published literatures are short of the actual implementation
difficulties like how to avoid arithmetic overflows. Each implementation,
available in `strategy::dragon` and `strategy::grisu` respectively,
extensively describes all necessary justifications and many proofs for them.
(It is still difficult to follow though. You have been warned.)

Both implementations expose two public functions:

- `format_shortest(decoded, buf)`, which always needs at least
  `MAX_SIG_DIGITS` digits of buffer. Implements the shortest mode.

- `format_exact(decoded, buf, limit)`, which accepts as small as
  one digit of buffer. Implements exact and fixed modes.

They try to fill the `u8` buffer with digits and returns the number of digits
written and the exponent `k`. They are total for all finite `f32` and `f64`
inputs (Grisu internally falls back to Dragon if necessary).

The rendered digits are formatted into the actual string form with
four functions:

- `to_shortest_str` prints the shortest representation, which can be padded by
  zeroes to make *at least* given number of fractional digits.

- `to_shortest_exp_str` prints the shortest representation, which can be
  padded by zeroes when its exponent is in the specified ranges,
  or can be printed in the exponential form such as `1.23e45`.

- `to_exact_exp_str` prints the exact representation with given number of
  digits in the exponential form.

- `to_exact_fixed_str` prints the fixed representation with *exactly*
  given number of fractional digits.

They all return a slice of preallocated `Part` array, which corresponds to
the individual part of strings: a fixed string, a part of rendered digits,
a number of zeroes or a small (`u16`) number. The caller is expected to
provide a large enough buffer and `Part` array, and to assemble the final
string from resulting `Part`s itself.

All algorithms and formatting functions are accompanied by extensive tests
in `coretests::num::flt2dec` module. It also shows how to use individual
functions.

*/</span>

<span class="comment">// while this is extensively documented, this is in principle private which is</span>
<span class="comment">// only made public for testing. do not expose us.</span>
<span class="attribute">#![<span class="ident">doc</span>(<span class="ident">hidden</span>)]</span>
<span class="attribute">#![<span class="ident">unstable</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;flt2dec&quot;</span>,
            <span class="ident">reason</span> <span class="op">=</span> <span class="string">&quot;internal routines only exposed for testing&quot;</span>,
            <span class="ident">issue</span> <span class="op">=</span> <span class="string">&quot;0&quot;</span>)]</span>

<span class="kw">use</span> <span class="ident">i16</span>;
<span class="kw">pub</span> <span class="kw">use</span> <span class="self">self</span>::<span class="ident">decoder</span>::{<span class="ident">decode</span>, <span class="ident">DecodableFloat</span>, <span class="ident">FullDecoded</span>, <span class="ident">Decoded</span>};

<span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">estimator</span>;
<span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">decoder</span>;

<span class="doccomment">/// Digit-generation algorithms.</span>
<span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">strategy</span> {
    <span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">dragon</span>;
    <span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">grisu</span>;
}

<span class="doccomment">/// The minimum size of buffer necessary for the shortest mode.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// It is a bit non-trivial to derive, but this is one plus the maximal number of</span>
<span class="doccomment">/// significant decimal digits from formatting algorithms with the shortest result.</span>
<span class="doccomment">/// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`.</span>
<span class="kw">pub</span> <span class="kw">const</span> <span class="ident">MAX_SIG_DIGITS</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="number">17</span>;

<span class="doccomment">/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry.</span>
<span class="doccomment">/// Returns a next digit when it causes the length change.</span>
<span class="attribute">#[<span class="ident">doc</span>(<span class="ident">hidden</span>)]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">round_up</span>(<span class="ident">d</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">n</span>: <span class="ident">usize</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">u8</span><span class="op">&gt;</span> {
    <span class="kw">match</span> <span class="ident">d</span>[..<span class="ident">n</span>].<span class="ident">iter</span>().<span class="ident">rposition</span>(<span class="op">|</span><span class="kw-2">&amp;</span><span class="ident">c</span><span class="op">|</span> <span class="ident">c</span> <span class="op">!=</span> <span class="string">b&#39;9&#39;</span>) {
        <span class="prelude-val">Some</span>(<span class="ident">i</span>) <span class="op">=&gt;</span> { <span class="comment">// d[i+1..n] is all nines</span>
            <span class="ident">d</span>[<span class="ident">i</span>] <span class="op">+=</span> <span class="number">1</span>;
            <span class="kw">for</span> <span class="ident">j</span> <span class="kw">in</span> <span class="ident">i</span><span class="op">+</span><span class="number">1</span>..<span class="ident">n</span> { <span class="ident">d</span>[<span class="ident">j</span>] <span class="op">=</span> <span class="string">b&#39;0&#39;</span>; }
            <span class="prelude-val">None</span>
        }
        <span class="prelude-val">None</span> <span class="kw">if</span> <span class="ident">n</span> <span class="op">&gt;</span> <span class="number">0</span> <span class="op">=&gt;</span> { <span class="comment">// 999..999 rounds to 1000..000 with an increased exponent</span>
            <span class="ident">d</span>[<span class="number">0</span>] <span class="op">=</span> <span class="string">b&#39;1&#39;</span>;
            <span class="kw">for</span> <span class="ident">j</span> <span class="kw">in</span> <span class="number">1</span>..<span class="ident">n</span> { <span class="ident">d</span>[<span class="ident">j</span>] <span class="op">=</span> <span class="string">b&#39;0&#39;</span>; }
            <span class="prelude-val">Some</span>(<span class="string">b&#39;0&#39;</span>)
        }
        <span class="prelude-val">None</span> <span class="op">=&gt;</span> { <span class="comment">// an empty buffer rounds up (a bit strange but reasonable)</span>
            <span class="prelude-val">Some</span>(<span class="string">b&#39;1&#39;</span>)
        }
    }
}

<span class="doccomment">/// Formatted parts.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Copy</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> {
    <span class="doccomment">/// Given number of zero digits.</span>
    <span class="ident">Zero</span>(<span class="ident">usize</span>),
    <span class="doccomment">/// A literal number up to 5 digits.</span>
    <span class="ident">Num</span>(<span class="ident">u16</span>),
    <span class="doccomment">/// A verbatim copy of given bytes.</span>
    <span class="ident">Copy</span>(<span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">u8</span>]),
}

<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> <span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> {
    <span class="doccomment">/// Returns the exact byte length of given part.</span>
    <span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">len</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-&gt;</span> <span class="ident">usize</span> {
        <span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
            <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">nzeroes</span>) <span class="op">=&gt;</span> <span class="ident">nzeroes</span>,
            <span class="ident">Part</span>::<span class="ident">Num</span>(<span class="ident">v</span>) <span class="op">=&gt;</span> <span class="kw">if</span> <span class="ident">v</span> <span class="op">&lt;</span> <span class="number">1_000</span> { <span class="kw">if</span> <span class="ident">v</span> <span class="op">&lt;</span> <span class="number">10</span> { <span class="number">1</span> } <span class="kw">else</span> <span class="kw">if</span> <span class="ident">v</span> <span class="op">&lt;</span> <span class="number">100</span> { <span class="number">2</span> } <span class="kw">else</span> { <span class="number">3</span> } }
                            <span class="kw">else</span> { <span class="kw">if</span> <span class="ident">v</span> <span class="op">&lt;</span> <span class="number">10_000</span> { <span class="number">4</span> } <span class="kw">else</span> { <span class="number">5</span> } },
            <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="ident">buf</span>) <span class="op">=&gt;</span> <span class="ident">buf</span>.<span class="ident">len</span>(),
        }
    }

    <span class="doccomment">/// Writes a part into the supplied buffer.</span>
    <span class="doccomment">/// Returns the number of written bytes, or `None` if the buffer is not enough.</span>
    <span class="doccomment">/// (It may still leave partially written bytes in the buffer; do not rely on that.)</span>
    <span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">write</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">out</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>]) <span class="op">-&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span> {
        <span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">len</span>();
        <span class="kw">if</span> <span class="ident">out</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">len</span> {
            <span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
                <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">nzeroes</span>) <span class="op">=&gt;</span> {
                    <span class="kw">for</span> <span class="ident">c</span> <span class="kw">in</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">out</span>[..<span class="ident">nzeroes</span>] { <span class="kw-2">*</span><span class="ident">c</span> <span class="op">=</span> <span class="string">b&#39;0&#39;</span>; }
                }
                <span class="ident">Part</span>::<span class="ident">Num</span>(<span class="kw-2">mut</span> <span class="ident">v</span>) <span class="op">=&gt;</span> {
                    <span class="kw">for</span> <span class="ident">c</span> <span class="kw">in</span> <span class="ident">out</span>[..<span class="ident">len</span>].<span class="ident">iter_mut</span>().<span class="ident">rev</span>() {
                        <span class="kw-2">*</span><span class="ident">c</span> <span class="op">=</span> <span class="string">b&#39;0&#39;</span> <span class="op">+</span> (<span class="ident">v</span> <span class="op">%</span> <span class="number">10</span>) <span class="kw">as</span> <span class="ident">u8</span>;
                        <span class="ident">v</span> <span class="op">/=</span> <span class="number">10</span>;
                    }
                }
                <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="ident">buf</span>) <span class="op">=&gt;</span> {
                    <span class="ident">out</span>[..<span class="ident">buf</span>.<span class="ident">len</span>()].<span class="ident">copy_from_slice</span>(<span class="ident">buf</span>);
                }
            }
            <span class="prelude-val">Some</span>(<span class="ident">len</span>)
        } <span class="kw">else</span> {
            <span class="prelude-val">None</span>
        }
    }
}

<span class="doccomment">/// Formatted result containing one or more parts.</span>
<span class="doccomment">/// This can be written to the byte buffer or converted to the allocated string.</span>
<span class="attribute">#[<span class="ident">allow</span>(<span class="ident">missing_debug_implementations</span>)]</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> {
    <span class="doccomment">/// A byte slice representing a sign, either `&quot;&quot;`, `&quot;-&quot;` or `&quot;+&quot;`.</span>
    <span class="kw">pub</span> <span class="ident">sign</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;static</span> [<span class="ident">u8</span>],
    <span class="doccomment">/// Formatted parts to be rendered after a sign and optional zero padding.</span>
    <span class="kw">pub</span> <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>],
}

<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span> {
    <span class="doccomment">/// Returns the exact byte length of combined formatted result.</span>
    <span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">len</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-&gt;</span> <span class="ident">usize</span> {
        <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">len</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">sign</span>.<span class="ident">len</span>();
        <span class="kw">for</span> <span class="ident">part</span> <span class="kw">in</span> <span class="self">self</span>.<span class="ident">parts</span> {
            <span class="ident">len</span> <span class="op">+=</span> <span class="ident">part</span>.<span class="ident">len</span>();
        }
        <span class="ident">len</span>
    }

    <span class="doccomment">/// Writes all formatted parts into the supplied buffer.</span>
    <span class="doccomment">/// Returns the number of written bytes, or `None` if the buffer is not enough.</span>
    <span class="doccomment">/// (It may still leave partially written bytes in the buffer; do not rely on that.)</span>
    <span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">write</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">out</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>]) <span class="op">-&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span> {
        <span class="kw">if</span> <span class="ident">out</span>.<span class="ident">len</span>() <span class="op">&lt;</span> <span class="self">self</span>.<span class="ident">sign</span>.<span class="ident">len</span>() { <span class="kw">return</span> <span class="prelude-val">None</span>; }
        <span class="ident">out</span>[..<span class="self">self</span>.<span class="ident">sign</span>.<span class="ident">len</span>()].<span class="ident">copy_from_slice</span>(<span class="self">self</span>.<span class="ident">sign</span>);

        <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">written</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">sign</span>.<span class="ident">len</span>();
        <span class="kw">for</span> <span class="ident">part</span> <span class="kw">in</span> <span class="self">self</span>.<span class="ident">parts</span> {
            <span class="kw">match</span> <span class="ident">part</span>.<span class="ident">write</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">out</span>[<span class="ident">written</span>..]) {
                <span class="prelude-val">Some</span>(<span class="ident">len</span>) <span class="op">=&gt;</span> { <span class="ident">written</span> <span class="op">+=</span> <span class="ident">len</span>; }
                <span class="prelude-val">None</span> <span class="op">=&gt;</span> { <span class="kw">return</span> <span class="prelude-val">None</span>; }
            }
        }
        <span class="prelude-val">Some</span>(<span class="ident">written</span>)
    }
}

<span class="doccomment">/// Formats given decimal digits `0.&lt;...buf...&gt; * 10^exp` into the decimal form</span>
<span class="doccomment">/// with at least given number of fractional digits. The result is stored to</span>
<span class="doccomment">/// the supplied parts array and a slice of written parts is returned.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `frac_digits` can be less than the number of actual fractional digits in `buf`;</span>
<span class="doccomment">/// it will be ignored and full digits will be printed. It is only used to print</span>
<span class="doccomment">/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that</span>
<span class="doccomment">/// it will only print given digits and nothing else.</span>
<span class="kw">fn</span> <span class="ident">digits_to_dec_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>(<span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">u8</span>], <span class="ident">exp</span>: <span class="ident">i16</span>, <span class="ident">frac_digits</span>: <span class="ident">usize</span>,
                         <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>] {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="op">!</span><span class="ident">buf</span>.<span class="ident">is_empty</span>());
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>[<span class="number">0</span>] <span class="op">&gt;</span> <span class="string">b&#39;0&#39;</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">4</span>);

    <span class="comment">// if there is the restriction on the last digit position, `buf` is assumed to be</span>
    <span class="comment">// left-padded with the virtual zeroes. the number of virtual zeroes, `nzeroes`,</span>
    <span class="comment">// equals to `max(0, exp + frac_digits - buf.len())`, so that the position of</span>
    <span class="comment">// the last digit `exp - buf.len() - nzeroes` is no more than `-frac_digits`:</span>
    <span class="comment">//</span>
    <span class="comment">//                       |&lt;-virtual-&gt;|</span>
    <span class="comment">//       |&lt;---- buf ----&gt;|  zeroes   |     exp</span>
    <span class="comment">//    0. 1 2 3 4 5 6 7 8 9 _ _ _ _ _ _ x 10</span>
    <span class="comment">//    |                  |           |</span>
    <span class="comment">// 10^exp    10^(exp-buf.len())   10^(exp-buf.len()-nzeroes)</span>
    <span class="comment">//</span>
    <span class="comment">// `nzeroes` is individually calculated for each case in order to avoid overflow.</span>

    <span class="kw">if</span> <span class="ident">exp</span> <span class="op">&lt;=</span> <span class="number">0</span> {
        <span class="comment">// the decimal point is before rendered digits: [0.][000...000][1234][____]</span>
        <span class="kw">let</span> <span class="ident">minus_exp</span> <span class="op">=</span> <span class="op">-</span>(<span class="ident">exp</span> <span class="kw">as</span> <span class="ident">i32</span>) <span class="kw">as</span> <span class="ident">usize</span>;
        <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0.&quot;</span>);
        <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">minus_exp</span>);
        <span class="ident">parts</span>[<span class="number">2</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="ident">buf</span>);
        <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&amp;&amp;</span> <span class="ident">frac_digits</span> <span class="op">-</span> <span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;</span> <span class="ident">minus_exp</span> {
            <span class="ident">parts</span>[<span class="number">3</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>((<span class="ident">frac_digits</span> <span class="op">-</span> <span class="ident">buf</span>.<span class="ident">len</span>()) <span class="op">-</span> <span class="ident">minus_exp</span>);
            <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">4</span>]
        } <span class="kw">else</span> {
            <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">3</span>]
        }
    } <span class="kw">else</span> {
        <span class="kw">let</span> <span class="ident">exp</span> <span class="op">=</span> <span class="ident">exp</span> <span class="kw">as</span> <span class="ident">usize</span>;
        <span class="kw">if</span> <span class="ident">exp</span> <span class="op">&lt;</span> <span class="ident">buf</span>.<span class="ident">len</span>() {
            <span class="comment">// the decimal point is inside rendered digits: [12][.][34][____]</span>
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">exp</span>]);
            <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;.&quot;</span>);
            <span class="ident">parts</span>[<span class="number">2</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[<span class="ident">exp</span>..]);
            <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">-</span> <span class="ident">exp</span> {
                <span class="ident">parts</span>[<span class="number">3</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">frac_digits</span> <span class="op">-</span> (<span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">-</span> <span class="ident">exp</span>));
                <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">4</span>]
            } <span class="kw">else</span> {
                <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">3</span>]
            }
        } <span class="kw">else</span> {
            <span class="comment">// the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].</span>
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="ident">buf</span>);
            <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">exp</span> <span class="op">-</span> <span class="ident">buf</span>.<span class="ident">len</span>());
            <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="number">0</span> {
                <span class="ident">parts</span>[<span class="number">2</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;.&quot;</span>);
                <span class="ident">parts</span>[<span class="number">3</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">frac_digits</span>);
                <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">4</span>]
            } <span class="kw">else</span> {
                <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">2</span>]
            }
        }
    }
}

<span class="doccomment">/// Formats given decimal digits `0.&lt;...buf...&gt; * 10^exp` into the exponential form</span>
<span class="doccomment">/// with at least given number of significant digits. When `upper` is true,</span>
<span class="doccomment">/// the exponent will be prefixed by `E`; otherwise that&#39;s `e`. The result is</span>
<span class="doccomment">/// stored to the supplied parts array and a slice of written parts is returned.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `min_digits` can be less than the number of actual significant digits in `buf`;</span>
<span class="doccomment">/// it will be ignored and full digits will be printed. It is only used to print</span>
<span class="doccomment">/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that</span>
<span class="doccomment">/// it will only print given digits and nothing else.</span>
<span class="kw">fn</span> <span class="ident">digits_to_exp_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>(<span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">u8</span>], <span class="ident">exp</span>: <span class="ident">i16</span>, <span class="ident">min_ndigits</span>: <span class="ident">usize</span>, <span class="ident">upper</span>: <span class="ident">bool</span>,
                         <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>] {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="op">!</span><span class="ident">buf</span>.<span class="ident">is_empty</span>());
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>[<span class="number">0</span>] <span class="op">&gt;</span> <span class="string">b&#39;0&#39;</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">6</span>);

    <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">n</span> <span class="op">=</span> <span class="number">0</span>;

    <span class="ident">parts</span>[<span class="ident">n</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="number">1</span>]);
    <span class="ident">n</span> <span class="op">+=</span> <span class="number">1</span>;

    <span class="kw">if</span> <span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;</span> <span class="number">1</span> <span class="op">||</span> <span class="ident">min_ndigits</span> <span class="op">&gt;</span> <span class="number">1</span> {
        <span class="ident">parts</span>[<span class="ident">n</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;.&quot;</span>);
        <span class="ident">parts</span>[<span class="ident">n</span> <span class="op">+</span> <span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[<span class="number">1</span>..]);
        <span class="ident">n</span> <span class="op">+=</span> <span class="number">2</span>;
        <span class="kw">if</span> <span class="ident">min_ndigits</span> <span class="op">&gt;</span> <span class="ident">buf</span>.<span class="ident">len</span>() {
            <span class="ident">parts</span>[<span class="ident">n</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">min_ndigits</span> <span class="op">-</span> <span class="ident">buf</span>.<span class="ident">len</span>());
            <span class="ident">n</span> <span class="op">+=</span> <span class="number">1</span>;
        }
    }

    <span class="comment">// 0.1234 x 10^exp = 1.234 x 10^(exp-1)</span>
    <span class="kw">let</span> <span class="ident">exp</span> <span class="op">=</span> <span class="ident">exp</span> <span class="kw">as</span> <span class="ident">i32</span> <span class="op">-</span> <span class="number">1</span>; <span class="comment">// avoid underflow when exp is i16::MIN</span>
    <span class="kw">if</span> <span class="ident">exp</span> <span class="op">&lt;</span> <span class="number">0</span> {
        <span class="ident">parts</span>[<span class="ident">n</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw">if</span> <span class="ident">upper</span> { <span class="string">b&quot;E-&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;e-&quot;</span> });
        <span class="ident">parts</span>[<span class="ident">n</span> <span class="op">+</span> <span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Num</span>(<span class="op">-</span><span class="ident">exp</span> <span class="kw">as</span> <span class="ident">u16</span>);
    } <span class="kw">else</span> {
        <span class="ident">parts</span>[<span class="ident">n</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw">if</span> <span class="ident">upper</span> { <span class="string">b&quot;E&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;e&quot;</span> });
        <span class="ident">parts</span>[<span class="ident">n</span> <span class="op">+</span> <span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Num</span>(<span class="ident">exp</span> <span class="kw">as</span> <span class="ident">u16</span>);
    }
    <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="ident">n</span> <span class="op">+</span> <span class="number">2</span>]
}

<span class="doccomment">/// Sign formatting options.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Copy</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Sign</span> {
    <span class="doccomment">/// Prints `-` only for the negative non-zero values.</span>
    <span class="ident">Minus</span>,        <span class="comment">// -inf -1  0  0  1  inf nan</span>
    <span class="doccomment">/// Prints `-` only for any negative values (including the negative zero).</span>
    <span class="ident">MinusRaw</span>,     <span class="comment">// -inf -1 -0  0  1  inf nan</span>
    <span class="doccomment">/// Prints `-` for the negative non-zero values, or `+` otherwise.</span>
    <span class="ident">MinusPlus</span>,    <span class="comment">// -inf -1 +0 +0 +1 +inf nan</span>
    <span class="doccomment">/// Prints `-` for any negative values (including the negative zero), or `+` otherwise.</span>
    <span class="ident">MinusPlusRaw</span>, <span class="comment">// -inf -1 -0 +0 +1 +inf nan</span>
}

<span class="doccomment">/// Returns the static byte string corresponding to the sign to be formatted.</span>
<span class="doccomment">/// It can be either `b&quot;&quot;`, `b&quot;+&quot;` or `b&quot;-&quot;`.</span>
<span class="kw">fn</span> <span class="ident">determine_sign</span>(<span class="ident">sign</span>: <span class="ident">Sign</span>, <span class="ident">decoded</span>: <span class="kw-2">&amp;</span><span class="ident">FullDecoded</span>, <span class="ident">negative</span>: <span class="ident">bool</span>) <span class="op">-&gt;</span> <span class="kw-2">&amp;</span><span class="lifetime">&#39;static</span> [<span class="ident">u8</span>] {
    <span class="kw">match</span> (<span class="kw-2">*</span><span class="ident">decoded</span>, <span class="ident">sign</span>) {
        (<span class="ident">FullDecoded</span>::<span class="ident">Nan</span>, <span class="kw">_</span>) <span class="op">=&gt;</span> <span class="string">b&quot;&quot;</span>,
        (<span class="ident">FullDecoded</span>::<span class="ident">Zero</span>, <span class="ident">Sign</span>::<span class="ident">Minus</span>) <span class="op">=&gt;</span> <span class="string">b&quot;&quot;</span>,
        (<span class="ident">FullDecoded</span>::<span class="ident">Zero</span>, <span class="ident">Sign</span>::<span class="ident">MinusRaw</span>) <span class="op">=&gt;</span> <span class="kw">if</span> <span class="ident">negative</span> { <span class="string">b&quot;-&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;&quot;</span> },
        (<span class="ident">FullDecoded</span>::<span class="ident">Zero</span>, <span class="ident">Sign</span>::<span class="ident">MinusPlus</span>) <span class="op">=&gt;</span> <span class="string">b&quot;+&quot;</span>,
        (<span class="ident">FullDecoded</span>::<span class="ident">Zero</span>, <span class="ident">Sign</span>::<span class="ident">MinusPlusRaw</span>) <span class="op">=&gt;</span> <span class="kw">if</span> <span class="ident">negative</span> { <span class="string">b&quot;-&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;+&quot;</span> },
        (<span class="kw">_</span>, <span class="ident">Sign</span>::<span class="ident">Minus</span>) <span class="op">|</span> (<span class="kw">_</span>, <span class="ident">Sign</span>::<span class="ident">MinusRaw</span>) <span class="op">=&gt;</span> <span class="kw">if</span> <span class="ident">negative</span> { <span class="string">b&quot;-&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;&quot;</span> },
        (<span class="kw">_</span>, <span class="ident">Sign</span>::<span class="ident">MinusPlus</span>) <span class="op">|</span> (<span class="kw">_</span>, <span class="ident">Sign</span>::<span class="ident">MinusPlusRaw</span>) <span class="op">=&gt;</span> <span class="kw">if</span> <span class="ident">negative</span> { <span class="string">b&quot;-&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;+&quot;</span> },
    }
}

<span class="doccomment">/// Formats given floating point number into the decimal form with at least</span>
<span class="doccomment">/// given number of fractional digits. The result is stored to the supplied parts</span>
<span class="doccomment">/// array while utilizing given byte buffer as a scratch. `upper` is currently</span>
<span class="doccomment">/// unused but left for the future decision to change the case of non-finite values,</span>
<span class="doccomment">/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign`</span>
<span class="doccomment">/// (which can be an empty string if no sign is rendered).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `format_shortest` should be the underlying digit-generation function.</span>
<span class="doccomment">/// You probably would want `strategy::grisu::format_shortest` for this.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `frac_digits` can be less than the number of actual fractional digits in `v`;</span>
<span class="doccomment">/// it will be ignored and full digits will be printed. It is only used to print</span>
<span class="doccomment">/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that</span>
<span class="doccomment">/// it will only print given digits and nothing else.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.</span>
<span class="doccomment">/// There should be at least 4 parts available, due to the worst case like</span>
<span class="doccomment">/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_shortest_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>, <span class="ident">F</span><span class="op">&gt;</span>(<span class="kw-2">mut</span> <span class="ident">format_shortest</span>: <span class="ident">F</span>, <span class="ident">v</span>: <span class="ident">T</span>,
                                 <span class="ident">sign</span>: <span class="ident">Sign</span>, <span class="ident">frac_digits</span>: <span class="ident">usize</span>, <span class="ident">_upper</span>: <span class="ident">bool</span>,
                                 <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>
        <span class="kw">where</span> <span class="ident">T</span>: <span class="ident">DecodableFloat</span>, <span class="ident">F</span>: <span class="ident">FnMut</span>(<span class="kw-2">&amp;</span><span class="ident">Decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>]) <span class="op">-&gt;</span> (<span class="ident">usize</span>, <span class="ident">i16</span>) {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">4</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">MAX_SIG_DIGITS</span>);

    <span class="kw">let</span> (<span class="ident">negative</span>, <span class="ident">full_decoded</span>) <span class="op">=</span> <span class="ident">decode</span>(<span class="ident">v</span>);
    <span class="kw">let</span> <span class="ident">sign</span> <span class="op">=</span> <span class="ident">determine_sign</span>(<span class="ident">sign</span>, <span class="kw-2">&amp;</span><span class="ident">full_decoded</span>, <span class="ident">negative</span>);
    <span class="kw">match</span> <span class="ident">full_decoded</span> {
        <span class="ident">FullDecoded</span>::<span class="ident">Nan</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;NaN&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Infinite</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;inf&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Zero</span> <span class="op">=&gt;</span> {
            <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="number">0</span> { <span class="comment">// [0.][0000]</span>
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0.&quot;</span>);
                <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">frac_digits</span>);
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">2</span>] }
            } <span class="kw">else</span> {
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0&quot;</span>);
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
            }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Finite</span>(<span class="kw-2">ref</span> <span class="ident">decoded</span>) <span class="op">=&gt;</span> {
            <span class="kw">let</span> (<span class="ident">len</span>, <span class="ident">exp</span>) <span class="op">=</span> <span class="ident">format_shortest</span>(<span class="ident">decoded</span>, <span class="ident">buf</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>,
                        <span class="ident">parts</span>: <span class="ident">digits_to_dec_str</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">len</span>], <span class="ident">exp</span>, <span class="ident">frac_digits</span>, <span class="ident">parts</span>) }
        }
    }
}

<span class="doccomment">/// Formats given floating point number into the decimal form or</span>
<span class="doccomment">/// the exponential form, depending on the resulting exponent. The result is</span>
<span class="doccomment">/// stored to the supplied parts array while utilizing given byte buffer</span>
<span class="doccomment">/// as a scratch. `upper` is used to determine the case of non-finite values</span>
<span class="doccomment">/// (`inf` and `nan`) or the case of the exponent prefix (`e` or `E`).</span>
<span class="doccomment">/// The first part to be rendered is always a `Part::Sign` (which can be</span>
<span class="doccomment">/// an empty string if no sign is rendered).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `format_shortest` should be the underlying digit-generation function.</span>
<span class="doccomment">/// You probably would want `strategy::grisu::format_shortest` for this.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted</span>
<span class="doccomment">/// as decimal only when `10^lo &lt;= V &lt; 10^hi`. Note that this is the *apparent* `V`</span>
<span class="doccomment">/// instead of the actual `v`! Thus any printed exponent in the exponential form</span>
<span class="doccomment">/// cannot be in this range, avoiding any confusion.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.</span>
<span class="doccomment">/// There should be at least 6 parts available, due to the worst case like</span>
<span class="doccomment">/// `[+][1][.][2345][e][-][6]`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_shortest_exp_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>, <span class="ident">F</span><span class="op">&gt;</span>(<span class="kw-2">mut</span> <span class="ident">format_shortest</span>: <span class="ident">F</span>, <span class="ident">v</span>: <span class="ident">T</span>,
                                     <span class="ident">sign</span>: <span class="ident">Sign</span>, <span class="ident">dec_bounds</span>: (<span class="ident">i16</span>, <span class="ident">i16</span>), <span class="ident">upper</span>: <span class="ident">bool</span>,
                                     <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>
        <span class="kw">where</span> <span class="ident">T</span>: <span class="ident">DecodableFloat</span>, <span class="ident">F</span>: <span class="ident">FnMut</span>(<span class="kw-2">&amp;</span><span class="ident">Decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>]) <span class="op">-&gt;</span> (<span class="ident">usize</span>, <span class="ident">i16</span>) {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">6</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">MAX_SIG_DIGITS</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">dec_bounds</span>.<span class="number">0</span> <span class="op">&lt;=</span> <span class="ident">dec_bounds</span>.<span class="number">1</span>);

    <span class="kw">let</span> (<span class="ident">negative</span>, <span class="ident">full_decoded</span>) <span class="op">=</span> <span class="ident">decode</span>(<span class="ident">v</span>);
    <span class="kw">let</span> <span class="ident">sign</span> <span class="op">=</span> <span class="ident">determine_sign</span>(<span class="ident">sign</span>, <span class="kw-2">&amp;</span><span class="ident">full_decoded</span>, <span class="ident">negative</span>);
    <span class="kw">match</span> <span class="ident">full_decoded</span> {
        <span class="ident">FullDecoded</span>::<span class="ident">Nan</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;NaN&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Infinite</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;inf&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Zero</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="kw">if</span> <span class="ident">dec_bounds</span>.<span class="number">0</span> <span class="op">&lt;=</span> <span class="number">0</span> <span class="op">&amp;&amp;</span> <span class="number">0</span> <span class="op">&lt;</span> <span class="ident">dec_bounds</span>.<span class="number">1</span> {
                <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0&quot;</span>)
            } <span class="kw">else</span> {
                <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw">if</span> <span class="ident">upper</span> { <span class="string">b&quot;0E0&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;0e0&quot;</span> })
            };
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Finite</span>(<span class="kw-2">ref</span> <span class="ident">decoded</span>) <span class="op">=&gt;</span> {
            <span class="kw">let</span> (<span class="ident">len</span>, <span class="ident">exp</span>) <span class="op">=</span> <span class="ident">format_shortest</span>(<span class="ident">decoded</span>, <span class="ident">buf</span>);
            <span class="kw">let</span> <span class="ident">vis_exp</span> <span class="op">=</span> <span class="ident">exp</span> <span class="kw">as</span> <span class="ident">i32</span> <span class="op">-</span> <span class="number">1</span>;
            <span class="kw">let</span> <span class="ident">parts</span> <span class="op">=</span> <span class="kw">if</span> <span class="ident">dec_bounds</span>.<span class="number">0</span> <span class="kw">as</span> <span class="ident">i32</span> <span class="op">&lt;=</span> <span class="ident">vis_exp</span> <span class="op">&amp;&amp;</span> <span class="ident">vis_exp</span> <span class="op">&lt;</span> <span class="ident">dec_bounds</span>.<span class="number">1</span> <span class="kw">as</span> <span class="ident">i32</span> {
                <span class="ident">digits_to_dec_str</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">len</span>], <span class="ident">exp</span>, <span class="number">0</span>, <span class="ident">parts</span>)
            } <span class="kw">else</span> {
                <span class="ident">digits_to_exp_str</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">len</span>], <span class="ident">exp</span>, <span class="number">0</span>, <span class="ident">upper</span>, <span class="ident">parts</span>)
            };
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="ident">parts</span> }
        }
    }
}

<span class="doccomment">/// Returns rather crude approximation (upper bound) for the maximum buffer size</span>
<span class="doccomment">/// calculated from the given decoded exponent.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The exact limit is:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// - when `exp &lt; 0`, the maximum length is `ceil(log_10 (5^-exp * (2^64 - 1)))`.</span>
<span class="doccomment">/// - when `exp &gt;= 0`, the maximum length is `ceil(log_10 (2^exp * (2^64 - 1)))`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `ceil(log_10 (x^exp * (2^64 - 1)))` is less than `ceil(log_10 (2^64 - 1)) +</span>
<span class="doccomment">/// ceil(exp * log_10 x)`, which is in turn less than `20 + (1 + exp * log_10 x)`.</span>
<span class="doccomment">/// We use the facts that `log_10 2 &lt; 5/16` and `log_10 5 &lt; 12/16`, which is</span>
<span class="doccomment">/// enough for our purposes.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Why do we need this? `format_exact` functions will fill the entire buffer</span>
<span class="doccomment">/// unless limited by the last digit restriction, but it is possible that</span>
<span class="doccomment">/// the number of digits requested is ridiculously large (say, 30,000 digits).</span>
<span class="doccomment">/// The vast majority of buffer will be filled with zeroes, so we don&#39;t want to</span>
<span class="doccomment">/// allocate all the buffer beforehand. Consequently, for any given arguments,</span>
<span class="doccomment">/// 826 bytes of buffer should be sufficient for `f64`. Compare this with</span>
<span class="doccomment">/// the actual number for the worst case: 770 bytes (when `exp = -1074`).</span>
<span class="kw">fn</span> <span class="ident">estimate_max_buf_len</span>(<span class="ident">exp</span>: <span class="ident">i16</span>) <span class="op">-&gt;</span> <span class="ident">usize</span> {
    <span class="number">21</span> <span class="op">+</span> ((<span class="kw">if</span> <span class="ident">exp</span> <span class="op">&lt;</span> <span class="number">0</span> { <span class="op">-</span><span class="number">12</span> } <span class="kw">else</span> { <span class="number">5</span> } <span class="op">*</span> <span class="ident">exp</span> <span class="kw">as</span> <span class="ident">i32</span>) <span class="kw">as</span> <span class="ident">usize</span> <span class="op">&gt;&gt;</span> <span class="number">4</span>)
}

<span class="doccomment">/// Formats given floating point number into the exponential form with</span>
<span class="doccomment">/// exactly given number of significant digits. The result is stored to</span>
<span class="doccomment">/// the supplied parts array while utilizing given byte buffer as a scratch.</span>
<span class="doccomment">/// `upper` is used to determine the case of the exponent prefix (`e` or `E`).</span>
<span class="doccomment">/// The first part to be rendered is always a `Part::Sign` (which can be</span>
<span class="doccomment">/// an empty string if no sign is rendered).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `format_exact` should be the underlying digit-generation function.</span>
<span class="doccomment">/// You probably would want `strategy::grisu::format_exact` for this.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is</span>
<span class="doccomment">/// so large that only the fixed number of digits will be ever written.</span>
<span class="doccomment">/// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.)</span>
<span class="doccomment">/// There should be at least 6 parts available, due to the worst case like</span>
<span class="doccomment">/// `[+][1][.][2345][e][-][6]`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_exact_exp_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>, <span class="ident">F</span><span class="op">&gt;</span>(<span class="kw-2">mut</span> <span class="ident">format_exact</span>: <span class="ident">F</span>, <span class="ident">v</span>: <span class="ident">T</span>,
                                  <span class="ident">sign</span>: <span class="ident">Sign</span>, <span class="ident">ndigits</span>: <span class="ident">usize</span>, <span class="ident">upper</span>: <span class="ident">bool</span>,
                                  <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>
        <span class="kw">where</span> <span class="ident">T</span>: <span class="ident">DecodableFloat</span>, <span class="ident">F</span>: <span class="ident">FnMut</span>(<span class="kw-2">&amp;</span><span class="ident">Decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">i16</span>) <span class="op">-&gt;</span> (<span class="ident">usize</span>, <span class="ident">i16</span>) {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">6</span>);
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">ndigits</span> <span class="op">&gt;</span> <span class="number">0</span>);

    <span class="kw">let</span> (<span class="ident">negative</span>, <span class="ident">full_decoded</span>) <span class="op">=</span> <span class="ident">decode</span>(<span class="ident">v</span>);
    <span class="kw">let</span> <span class="ident">sign</span> <span class="op">=</span> <span class="ident">determine_sign</span>(<span class="ident">sign</span>, <span class="kw-2">&amp;</span><span class="ident">full_decoded</span>, <span class="ident">negative</span>);
    <span class="kw">match</span> <span class="ident">full_decoded</span> {
        <span class="ident">FullDecoded</span>::<span class="ident">Nan</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;NaN&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Infinite</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;inf&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Zero</span> <span class="op">=&gt;</span> {
            <span class="kw">if</span> <span class="ident">ndigits</span> <span class="op">&gt;</span> <span class="number">1</span> { <span class="comment">// [0.][0000][e0]</span>
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0.&quot;</span>);
                <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">ndigits</span> <span class="op">-</span> <span class="number">1</span>);
                <span class="ident">parts</span>[<span class="number">2</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw">if</span> <span class="ident">upper</span> { <span class="string">b&quot;E0&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;e0&quot;</span> });
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">3</span>] }
            } <span class="kw">else</span> {
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="kw">if</span> <span class="ident">upper</span> { <span class="string">b&quot;0E0&quot;</span> } <span class="kw">else</span> { <span class="string">b&quot;0e0&quot;</span> });
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
            }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Finite</span>(<span class="kw-2">ref</span> <span class="ident">decoded</span>) <span class="op">=&gt;</span> {
            <span class="kw">let</span> <span class="ident">maxlen</span> <span class="op">=</span> <span class="ident">estimate_max_buf_len</span>(<span class="ident">decoded</span>.<span class="ident">exp</span>);
            <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">ndigits</span> <span class="op">||</span> <span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">maxlen</span>);

            <span class="kw">let</span> <span class="ident">trunc</span> <span class="op">=</span> <span class="kw">if</span> <span class="ident">ndigits</span> <span class="op">&lt;</span> <span class="ident">maxlen</span> { <span class="ident">ndigits</span> } <span class="kw">else</span> { <span class="ident">maxlen</span> };
            <span class="kw">let</span> (<span class="ident">len</span>, <span class="ident">exp</span>) <span class="op">=</span> <span class="ident">format_exact</span>(<span class="ident">decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">buf</span>[..<span class="ident">trunc</span>], <span class="ident">i16</span>::<span class="ident">MIN</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>,
                        <span class="ident">parts</span>: <span class="ident">digits_to_exp_str</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">len</span>], <span class="ident">exp</span>, <span class="ident">ndigits</span>, <span class="ident">upper</span>, <span class="ident">parts</span>) }
        }
    }
}

<span class="doccomment">/// Formats given floating point number into the decimal form with exactly</span>
<span class="doccomment">/// given number of fractional digits. The result is stored to the supplied parts</span>
<span class="doccomment">/// array while utilizing given byte buffer as a scratch. `upper` is currently</span>
<span class="doccomment">/// unused but left for the future decision to change the case of non-finite values,</span>
<span class="doccomment">/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign`</span>
<span class="doccomment">/// (which can be an empty string if no sign is rendered).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `format_exact` should be the underlying digit-generation function.</span>
<span class="doccomment">/// You probably would want `strategy::grisu::format_exact` for this.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The byte buffer should be enough for the output unless `frac_digits` is</span>
<span class="doccomment">/// so large that only the fixed number of digits will be ever written.</span>
<span class="doccomment">/// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.)</span>
<span class="doccomment">/// There should be at least 4 parts available, due to the worst case like</span>
<span class="doccomment">/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_exact_fixed_str</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>, <span class="ident">F</span><span class="op">&gt;</span>(<span class="kw-2">mut</span> <span class="ident">format_exact</span>: <span class="ident">F</span>, <span class="ident">v</span>: <span class="ident">T</span>,
                                    <span class="ident">sign</span>: <span class="ident">Sign</span>, <span class="ident">frac_digits</span>: <span class="ident">usize</span>, <span class="ident">_upper</span>: <span class="ident">bool</span>,
                                    <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> [<span class="ident">Part</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>]) <span class="op">-&gt;</span> <span class="ident">Formatted</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>
        <span class="kw">where</span> <span class="ident">T</span>: <span class="ident">DecodableFloat</span>, <span class="ident">F</span>: <span class="ident">FnMut</span>(<span class="kw-2">&amp;</span><span class="ident">Decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">u8</span>], <span class="ident">i16</span>) <span class="op">-&gt;</span> (<span class="ident">usize</span>, <span class="ident">i16</span>) {
    <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">parts</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="number">4</span>);

    <span class="kw">let</span> (<span class="ident">negative</span>, <span class="ident">full_decoded</span>) <span class="op">=</span> <span class="ident">decode</span>(<span class="ident">v</span>);
    <span class="kw">let</span> <span class="ident">sign</span> <span class="op">=</span> <span class="ident">determine_sign</span>(<span class="ident">sign</span>, <span class="kw-2">&amp;</span><span class="ident">full_decoded</span>, <span class="ident">negative</span>);
    <span class="kw">match</span> <span class="ident">full_decoded</span> {
        <span class="ident">FullDecoded</span>::<span class="ident">Nan</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;NaN&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Infinite</span> <span class="op">=&gt;</span> {
            <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;inf&quot;</span>);
            <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Zero</span> <span class="op">=&gt;</span> {
            <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="number">0</span> { <span class="comment">// [0.][0000]</span>
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0.&quot;</span>);
                <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">frac_digits</span>);
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">2</span>] }
            } <span class="kw">else</span> {
                <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0&quot;</span>);
                <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
            }
        }
        <span class="ident">FullDecoded</span>::<span class="ident">Finite</span>(<span class="kw-2">ref</span> <span class="ident">decoded</span>) <span class="op">=&gt;</span> {
            <span class="kw">let</span> <span class="ident">maxlen</span> <span class="op">=</span> <span class="ident">estimate_max_buf_len</span>(<span class="ident">decoded</span>.<span class="ident">exp</span>);
            <span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buf</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">maxlen</span>);

            <span class="comment">// it *is* possible that `frac_digits` is ridiculously large.</span>
            <span class="comment">// `format_exact` will end rendering digits much earlier in this case,</span>
            <span class="comment">// because we are strictly limited by `maxlen`.</span>
            <span class="kw">let</span> <span class="ident">limit</span> <span class="op">=</span> <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&lt;</span> <span class="number">0x8000</span> { <span class="op">-</span>(<span class="ident">frac_digits</span> <span class="kw">as</span> <span class="ident">i16</span>) } <span class="kw">else</span> { <span class="ident">i16</span>::<span class="ident">MIN</span> };
            <span class="kw">let</span> (<span class="ident">len</span>, <span class="ident">exp</span>) <span class="op">=</span> <span class="ident">format_exact</span>(<span class="ident">decoded</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">buf</span>[..<span class="ident">maxlen</span>], <span class="ident">limit</span>);
            <span class="kw">if</span> <span class="ident">exp</span> <span class="op">&lt;=</span> <span class="ident">limit</span> {
                <span class="comment">// the restriction couldn&#39;t been met, so this should render like zero no matter</span>
                <span class="comment">// `exp` was. this does not include the case that the restriction has been met</span>
                <span class="comment">// only after the final rounding-up; it&#39;s a regular case with `exp = limit + 1`.</span>
                <span class="macro">debug_assert_eq</span><span class="macro">!</span>(<span class="ident">len</span>, <span class="number">0</span>);
                <span class="kw">if</span> <span class="ident">frac_digits</span> <span class="op">&gt;</span> <span class="number">0</span> { <span class="comment">// [0.][0000]</span>
                    <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0.&quot;</span>);
                    <span class="ident">parts</span>[<span class="number">1</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Zero</span>(<span class="ident">frac_digits</span>);
                    <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">2</span>] }
                } <span class="kw">else</span> {
                    <span class="ident">parts</span>[<span class="number">0</span>] <span class="op">=</span> <span class="ident">Part</span>::<span class="ident">Copy</span>(<span class="string">b&quot;0&quot;</span>);
                    <span class="ident">Formatted</span> { <span class="ident">sign</span>: <span class="ident">sign</span>, <span class="ident">parts</span>: <span class="kw-2">&amp;</span><span class="ident">parts</span>[..<span class="number">1</span>] }
                }
            } <span class="kw">else</span> {
                <span class="ident">Formatted</span> { <span class="ident">sign</span>,
                            <span class="ident">parts</span>: <span class="ident">digits_to_dec_str</span>(<span class="kw-2">&amp;</span><span class="ident">buf</span>[..<span class="ident">len</span>], <span class="ident">exp</span>, <span class="ident">frac_digits</span>, <span class="ident">parts</span>) }
            }
        }
    }
}

</pre>
</section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd>↑</kbd></dt><dd>Move up in search results</dd><dt><kbd>↓</kbd></dt><dd>Move down in search results</dd><dt><kbd>↹</kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g. <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g. <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g. <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../../../";window.currentCrate = "core";</script><script src="../../../../aliases.js"></script><script src="../../../../main.js"></script><script defer src="../../../../search-index.js"></script></body></html>