forked from douglascrockford/DEC64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdec64_string.html
338 lines (313 loc) · 11.6 KB
/
dec64_string.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
<!DOCTYPE html>
<html>
<head><title>dec64_string</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
@import url(http://fonts.googleapis.com/css?family=Cousine:700);
@import url(http://fonts.googleapis.com/css?family=Inika:400,700);
body {
background-color: cornsilk;
border-left: 1em solid indianred;
font-family: 'Inika', serif;
margin-left: 1em;
max-width: 50em;
padding: 10%;
}
code, pre, h3 {
font-family: "Courier New", Courier, mono;
font-size: 100%;
font-weight: bold;
}
code var, pre var, h3 var {
font-family: 'Inika', serif;
font-style: italic;
font-weight: normal;
}
pre {
padding-left: 2em;
padding-right: 1em;
padding-bottom: 0.25em;
padding-top: 0.25em;
text-align: left;
}
h3 {
border-top: 1pt solid black;
white-space: pre;
}
a { /* link */
font-size: 100%;
font-variant: normal;
font-weight: normal;
text-decoration: none;
}
a:link {
color: midnightblue;
}
a:visited {
color: purple;
}
a:hover {
border-bottom: 1pt solid blue;
color: blue;
}
a:active {
border-bottom: 1pt dotted red;
color: red;
}
table {
margin-top: -1em;
}
td {
background-color: navajowhite;
border: 2pt solid black;
text-align: center;
}
th {
background-color: inherit;
border: 0;
font-weight: lighter;
padding-left: 3pt;
padding-right: 3pt;
text-align: center;
}
.dec64, h1, h2 {
font-family: 'Cousine', sans-serif;
};
</style>
</head>
<body>
<a href="http://www.DEC64.com/"><img src="dec64.png" alt="DEC64" width="398" height="103" border="0"></a>
<h1>dec64_string.c</h1>
<p>One of the most difficult problems in floating-point systems is the
conversion of numbers to text. This conversion is important because humans
generally cannot use binary representations, and there are not simple, exact
transformations between familiar decimal representations and binary
floating-point. It can be difficult and expensive to find representations
that are accurate, minimal, and unsurprising. </p>
<table>
<tr>
<th scope="col"> </th>
<th align="center" scope="col">0.1 + 0.2</th>
<th align="center" scope="col">10 / 3</th>
</tr>
<tr>
<th>IEEE754</th>
<td><pre>0.30000000000000004</pre></td>
<td><pre>3.3333333333333335</pre></td>
</tr>
<tr>
<th><span class=dec64>DEC64</span></th>
<td align="left"><pre>0.3</pre></td>
<td><pre>3.3333333333333333</pre></td>
</tr>
</table>
<p>One of <span class=dec64>DEC64</span>'s advantages is that it easily and
accurately converts to decimal representations, requiring only slightly
more effort than the conversion of integers.</p>
<p><a href="https://github.com/douglascrockford/DEC64/blob/master/dec64_string.c">
dec64_string.c</a> contains functions for converting
<span class=dec64>DEC64</span> numbers to strings and back again.
<a href="https://github.com/douglascrockford/DEC64/blob/master/dec64_text.h">
dec64_string.h</a> includes C function prototypes for these functions:</p>
<pre>dec64 <a href="#dec64_from_string">dec64_from_string</a>(
dec64_string_state state,
dec64_string_char string[]
)</pre>
<pre>dec64_string_state <a href="#dec64_string_begin">dec64_string_begin</a>()</pre>
<pre>dec64_string_char <a href="#dec64_string_decimal_point">dec64_string_decimal_point</a>(
dec64_string_state state,
dec64_string_char decimal_point
)</pre>
<pre>void <a href="#dec64_string_end">dec64_string_end</a>(
dec64_string_state state
)</pre>
<pre>void <a href="#dec64_string_engineering">dec64_string_engineering</a>(
dec64_string_state state
)</pre>
<pre>int <a href="3dec64_string_places">dec64_string_places</a>(
dec64_string_state state,
dec64_string_char places
)</pre>
<pre>void <a href="#dec64_from_string">dec64_string_scientific</a>(
dec64_string_state state
)</pre>
<pre>int <a href="#dec64_string_separation">dec64_string_separation</a>(
dec64_string_state state,
int separation
)</pre>
<pre>dec64_string_char <a href="#dec64_string_separator">dec64_string_separator</a>(
dec64_string_state state,
dec64_string_char separator
)</pre>
<pre>void <a href="#dec64_string_standard">dec64_string_standard</a>(
dec64_string_state state
)</pre>
<pre>int <a href="#dec64_to_string">dec64_to_string</a>(
dec64_string_state state,
dec64 number,
dec64_string_char string[]
)</pre>
<p>Two types are provided:</p>
<ul>
<li><code>dec64_string_char</code></li>
<li><code> dec64_string_state</code></li>
</ul>
<h2 id="state">String State</h2>
<p>There functions are reentrant and thread safe. This is accomplished by use of
a state object that is created by
<code><a href="#dec64_string_begin">dec64_string_begin</a></code> and
destroyed by <code><a href="#dec64_string_end">dec64_string_end</a></code>.
All of these functions require a state object as the first argument. The
state argument allows for customizing the conversions. Do not attempt to
modify the string state object directly. Use the provided functions instead.
State objects are reusable.</p>
<p>The state object contains the output mode: standard, scientific, or engineering.</p>
<h2 id="creation">Creation</h2>
<h3><span id="dec64_string_state">dec64_string_state</span>
<span id="dec64_string_begin">dec64_string_begin</span>()</h3>
<p><code>dec64_string_begin</code> creates a state object. The object should be
passed to all of the other functions.</p>
<h2 id="destruction">Destruction</h2>
<h3 id="dec64_string_end">void dec64_string_end(
dec64_string_state state
)</h3>
<p><code>dec64_string_end</code> destroys and deallocates a state object.</p>
<h2 id="configuration">Configuration</h2>
<p>The following functions configure or customize a state object.</p>
<h3>dec64_string_char <span id="dec64_string_decimal_point">dec64_string_decimal_point</span>(
dec64_string_state state,
dec64_string_char decimal_point
)</h3>
<p>Specify the decimal point character. This is used by both
<code><a href="#dec64_to_string">dec64_to_string</a></code> and
<code><a href="#dec64_from_string">dec64_from_string</a></code>.
The default is '<code>.</code>'. If it is '<code>\0</code>', then the
decimal point will be suppressed.</p>
<p> It returns the previous value.</p>
<h3>void <span id="dec64_string_engineering">dec64_string_engineering</span>(
dec64_string_state state
)</h3>
<p>Put <a href="#dec64_to_string"><code>dec64_to_string</code></a> into
engineering mode, which is like scientific mode except that the exponent is
constrained to be a multiple of 3. There can be up to three digits before
the decimal point.</p>
<h3>int <span id="dec64_string_places">dec64_string_places</span>(
dec64_string_state state,
dec64_string_char places
)</h3>
<p>Specify the minimum number of decimal places output by
<a href="http://www.DEC64.com/"><code>dec64_to_string</code></a> in standard
mode. This is commonly used to format money values. The default is
<code>0</code>.</p>
<p> It returns the previous value.</p>
<h3>void <span id="dec64_string_scientific">dec64_string_scientific</span>(
dec64_string_state state
)</h3>
<p>Put dec64_to_string into scientific mode, in which the coefficient is
displayed with one digit before the decimal point, and an exponent prefixed
with '<code>e</code>' is appended if necessary.</p>
<h3>int <span id="dec64_string_separation">dec64_string_separation</span>(
dec64_string_state state,
int separation
)</h3>
<p>Specify the number of digits output between separators by
<code><a href="#dec64_to_string">dec64_to_string</a></code> in standard
mode. If separation is <code>1</code> or less, then separation is
suppressed. The default is <code>3</code>.</p>
<p> It returns the previous value.</p>
<h3>dec64_string_char <span id="dec64_string_separator">dec64_string_separator</span>(
dec64_string_state state,
dec64_string_char separator
)</h3>
<p>Specify the separation character, which is used by
<code><a href="http://www.DEC64.com/">dec64_to_string</a></code> in standard
mode to improve the readability of digits before the decimal point. Typical
values include '<code>,</code>', '<code> </code>', '<code>_</code>', and
'<code>.</code>'. If it is '<code>\0</code>', then separation will be
suppressed. The default is '<code>\0</code>'.</p>
<p><code><a href="#dec64_from_string">dec64_from_string</a></code> will ignore
this character.</p>
<p>It returns the previous value.</p>
<h3>void <span id="dec64_string_standard">dec64_string_standard</span>(
dec64_string_state state
)</h3>
<p>Put <code><a href="#dec64_to_string">dec64_to_string</a></code> into standard
mode. Separators can be inserted between some digits if requested. If the
number might be too long, then scientific mode might be used instead.</p>
<p>Standard mode is the default.</p>
<h2 id="action">Action</h2>
<h3>dec64 <span id="dec64_from_string">dec64_from_string</span>(
dec64_string_state state,
dec64_string_char string[]
)</h3>
<p>Convert a zero-delimited string into a <code>dec64</code>. Separator
characters will be ignored. If conversion is not possible for any reason,
the result will be <code>DEC64_NAN</code>.</p>
<h3>int <span id="dec64_to_string">dec64_to_string</span>(
dec64_string_state state,
dec64 number,
dec64_string_char string[]
)</h3>
<p><code>dec64_to_string</code> converts a <code>dec64</code> number into a
string. The caller provides the memory into which to deposit the string. The
provided string must have sufficient capacity to hold 32 characters. It
returns the number of characters actually deposited in the string (not
including the trailing '<code>\0</code>'). If the number is <var>nan</var>,
then it returns <code>0</code> indicating an empty string. If
<code>NULL</code> is passed in as the string, then no characters will be
deposited, but a character count will be returned.</p>
<p>In standard mode, the number will be formatted conventionally unless it
would require more than 17 digits, which would be due to excessive
trailing zeros or zeros immediately after the decimal point. In that
case scientific notation will be used instead.</p>
<h2 id="examples">Examples</h2>
<table>
<tr>
<td><pre>dec64_string_state state = dec64_string_begin();
dec64_to_string(state, dec64_new(10, -128), string);</pre></td>
<td><pre>"1e-127"</pre></td>
</tr>
<tr>
<td><pre>dec64_to_string(state, dec64_new(1024, 0), string);</pre></td>
<td><pre>"1024"</pre></td>
</tr>
<tr>
<td><pre>dec64_separator(state, ',');
dec64_to_string(state, dec64_new(1024, 0), string);</pre></td>
<td><pre>"1,024"</pre></td>
</tr>
<tr>
<td><pre>dec64_separator(state, ' ');
dec64_to_string(state, dec64_new(1024, 0), string);</pre></td>
<td><pre>"1 024"</pre></td>
</tr>
<tr>
<td><pre>dec64_places(state, 4);
dec64_to_string(state, dec64_new(1024, 0), string);</pre></td>
<td><pre>"1 024.0000"</pre></td>
</tr>
<tr>
<td><pre>dec64_scientific(state);
dec64_to_string(state, dec64_new(1024, 0), string);</pre></td>
<td><pre>"1.024e3"</pre></td>
</tr>
<tr>
<td><pre>dec64_from_string(state, "1 024.0000")</pre></td>
<td><pre>1024</pre></td>
</tr>
<tr>
<td><pre>dec64_from_string(state, "1,024.0000")</pre></td>
<td><pre>DEC64_NAN</pre></td>
</tr>
<tr>
<td><pre>dec64_separator(state, ',');
dec64_from_string(state, "1,024.0000")</pre></td>
<td><pre>1024</pre></td>
</tr>
<tr>
<td><pre>dec64_string_end();</pre></td>
<td><pre> </pre></td>
</tr>
</table>
</body>
</html>