source: mainline/uspace/lib/c/generic/double_to_str.c@ 338d54a7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 338d54a7 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 25.0 KB
Line 
1/*
2 * Copyright (c) 2012 Adam Hraska
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <double_to_str.h>
30
31#include "private/power_of_ten.h"
32#include <ieee_double.h>
33
34#include <limits.h>
35#include <stdint.h>
36#include <stdbool.h>
37#include <stddef.h>
38#include <assert.h>
39
40/*
41 * Floating point numbers are converted from their binary representation
42 * into a decimal string using the algorithm described in:
43 * Printing floating-point numbers quickly and accurately with integers
44 * Loitsch, 2010
45 */
46
47/** The computation assumes a significand of 64 bits. */
48static const int significand_width = 64;
49
50/* Scale exponents to interval [alpha, gamma] to simplify conversion. */
51static const int alpha = -59;
52static const int gamma = -32;
53
54
55/** Returns true if the most-significant bit of num.significand is set. */
56static bool is_normalized(fp_num_t num)
57{
58 assert(8*sizeof(num.significand) == significand_width);
59
60 /* Normalized == most significant bit of the significand is set. */
61 return (num.significand & (1ULL << (significand_width - 1))) != 0;
62}
63
64/** Returns a normalized num with the MSbit set. */
65static fp_num_t normalize(fp_num_t num)
66{
67 const uint64_t top10bits = 0xffc0000000000000ULL;
68
69 /* num usually comes from ieee_double with top 10 bits zero. */
70 while (0 == (num.significand & top10bits)) {
71 num.significand <<= 10;
72 num.exponent -= 10;
73 }
74
75 while (!is_normalized(num)) {
76 num.significand <<= 1;
77 --num.exponent;
78 }
79
80 return num;
81}
82
83
84/** Returns x * y with an error of less than 0.5 ulp. */
85static fp_num_t multiply(fp_num_t x, fp_num_t y)
86{
87 assert(/* is_normalized(x) && */ is_normalized(y));
88
89 const uint32_t low_bits = -1;
90
91 uint64_t a, b, c, d;
92 a = x.significand >> 32;
93 b = x.significand & low_bits;
94 c = y.significand >> 32;
95 d = y.significand & low_bits;
96
97 uint64_t bd, ad, bc, ac;
98 bd = b * d;
99 ad = a * d;
100
101 bc = b * c;
102 ac = a * c;
103
104 /* Denote 32 bit parts of x a y as: x == a b, y == c d. Then:
105 * a b
106 * * c d
107 * ----------
108 * ad bd .. multiplication of 32bit parts results in 64bit parts
109 * + ac bc
110 * ----------
111 * [b|d] .. Depicts 64 bit intermediate results and how
112 * [a|d] the 32 bit parts of these results overlap and
113 * [b|c] contribute to the final result.
114 * +[a|c]
115 * ----------
116 * [ret]
117 * [tmp]
118 */
119 uint64_t tmp = (bd >> 32) + (ad & low_bits) + (bc & low_bits);
120
121 /* Round upwards. */
122 tmp += 1U << 31;
123
124 fp_num_t ret;
125 ret.significand = ac + (bc >> 32) + (ad >> 32) + (tmp >> 32);
126 ret.exponent = x.exponent + y.exponent + significand_width;
127
128 return ret;
129}
130
131
132/** Returns a - b. Both must have the same exponent. */
133static fp_num_t subtract(fp_num_t a, fp_num_t b)
134{
135 assert(a.exponent == b.exponent);
136 assert(a.significand >= b.significand);
137
138 fp_num_t result;
139
140 result.significand = a.significand - b.significand;
141 result.exponent = a.exponent;
142
143 return result;
144}
145
146
147/** Returns the interval [low, high] of numbers that convert to binary val. */
148static void get_normalized_bounds(ieee_double_t val, fp_num_t *high,
149 fp_num_t *low, fp_num_t *val_dist)
150{
151 /*
152 * Only works if val comes directly from extract_ieee_double without
153 * being manipulated in any way (eg it must not be normalized).
154 */
155 assert(!is_normalized(val.pos_val));
156
157 high->significand = (val.pos_val.significand << 1) + 1;
158 high->exponent = val.pos_val.exponent - 1;
159
160 /* val_dist = high - val */
161 val_dist->significand = 1;
162 val_dist->exponent = val.pos_val.exponent - 1;
163
164 /* Distance from both lower and upper bound is the same. */
165 if (!val.is_accuracy_step) {
166 low->significand = (val.pos_val.significand << 1) - 1;
167 low->exponent = val.pos_val.exponent - 1;
168 } else {
169 low->significand = (val.pos_val.significand << 2) - 1;
170 low->exponent = val.pos_val.exponent - 2;
171 }
172
173 *high = normalize(*high);
174
175 /*
176 * Lower bound may not be normalized if subtracting 1 unit
177 * reset the most-significant bit to 0.
178 */
179 low->significand = low->significand << (low->exponent - high->exponent);
180 low->exponent = high->exponent;
181
182 val_dist->significand =
183 val_dist->significand << (val_dist->exponent - high->exponent);
184 val_dist->exponent = high->exponent;
185}
186
187/** Determines the interval of numbers that have the binary representation
188 * of val.
189 *
190 * Numbers in the range [scaled_upper_bound - bounds_delta, scaled_upper_bound]
191 * have the same double binary representation as val.
192 *
193 * Bounds are scaled by 10^scale so that alpha <= exponent <= gamma.
194 * Moreover, scaled_upper_bound is normalized.
195 *
196 * val_dist is the scaled distance from val to the upper bound, ie
197 * val_dist == (upper_bound - val) * 10^scale
198 */
199static void calc_scaled_bounds(ieee_double_t val, fp_num_t *scaled_upper_bound,
200 fp_num_t *bounds_delta, fp_num_t *val_dist, int *scale)
201{
202 fp_num_t upper_bound, lower_bound;
203
204 get_normalized_bounds(val, &upper_bound, &lower_bound, val_dist);
205
206 assert(upper_bound.exponent == lower_bound.exponent);
207 assert(is_normalized(upper_bound));
208 assert(normalize(val.pos_val).exponent == upper_bound.exponent);
209
210 /*
211 * Find such a cached normalized power of 10 that if multiplied
212 * by upper_bound the binary exponent of upper_bound almost vanishes,
213 * ie:
214 * upper_scaled := upper_bound * 10^scale
215 * alpha <= upper_scaled.exponent <= gamma
216 * alpha <= upper_bound.exponent + pow_10.exponent + 64 <= gamma
217 */
218 fp_num_t scaling_power_of_10;
219 int lower_bin_exp = alpha - upper_bound.exponent - significand_width;
220
221 get_power_of_ten(lower_bin_exp, &scaling_power_of_10, scale);
222
223 int scale_exp = scaling_power_of_10.exponent;
224 assert(alpha <= upper_bound.exponent + scale_exp + significand_width);
225 assert(upper_bound.exponent + scale_exp + significand_width <= gamma);
226
227 fp_num_t upper_scaled = multiply(upper_bound, scaling_power_of_10);
228 fp_num_t lower_scaled = multiply(lower_bound, scaling_power_of_10);
229 *val_dist = multiply(*val_dist, scaling_power_of_10);
230
231 assert(alpha <= upper_scaled.exponent && upper_scaled.exponent <= gamma);
232
233 /*
234 * Any value between lower and upper bound would be represented
235 * in binary as the double val originated from. The bounds were
236 * however scaled by an imprecise power of 10 (error less than
237 * 1 ulp) so the scaled bounds have an error of less than 1 ulp.
238 * Conservatively round the lower bound up and the upper bound
239 * down by 1 ulp just to be on the safe side. It avoids pronouncing
240 * produced decimal digits as correct if such a decimal number
241 * is close to the bounds to within 1 ulp.
242 */
243 upper_scaled.significand -= 1;
244 lower_scaled.significand += 1;
245
246 *bounds_delta = subtract(upper_scaled, lower_scaled);
247 *scaled_upper_bound = upper_scaled;
248}
249
250
251/** Rounds the last digit of buf so that it is closest to the converted number.*/
252static void round_last_digit(uint64_t rest, uint64_t w_dist, uint64_t delta,
253 uint64_t digit_val_diff, char *buf, int len)
254{
255 /*
256 * | <------- delta -------> |
257 * | | <---- w_dist ----> |
258 * | | | <- rest -> |
259 * | | | |
260 * | | ` buffer |
261 * | ` w ` upper
262 * ` lower
263 *
264 * delta = upper - lower .. conservative/safe interval
265 * w_dist = upper - w
266 * upper = "number represented by digits in buf" + rest
267 *
268 * Changing buf[len - 1] changes the value represented by buf
269 * by digit_val_diff * scaling, where scaling is shared by
270 * all parameters.
271 *
272 */
273
274 /* Current number in buf is greater than the double being converted */
275 bool cur_greater_w = rest < w_dist;
276 /* Rounding down by one would keep buf in between bounds (in safe rng). */
277 bool next_in_val_rng = cur_greater_w && (rest + digit_val_diff < delta);
278 /* Rounding down by one would bring buf closer to the processed number. */
279 bool next_closer = next_in_val_rng
280 && (rest + digit_val_diff < w_dist || rest - w_dist < w_dist - rest);
281
282 /* Of the shortest strings pick the one that is closest to the actual
283 floating point number. */
284 while (next_closer) {
285 assert('0' < buf[len - 1]);
286 assert(0 < digit_val_diff);
287
288 --buf[len - 1];
289 rest += digit_val_diff;
290
291 cur_greater_w = rest < w_dist;
292 next_in_val_rng = cur_greater_w && (rest + digit_val_diff < delta);
293 next_closer = next_in_val_rng
294 && (rest + digit_val_diff < w_dist || rest - w_dist < w_dist - rest);
295 }
296}
297
298
299/** Generates the shortest accurate decimal string representation.
300 *
301 * Outputs (mostly) the shortest accurate string representation
302 * for the number scaled_upper - val_dist. Numbers in the interval
303 * [scaled_upper - delta, scaled_upper] have the same binary
304 * floating point representation and will therefore share the
305 * shortest string representation (up to the rounding of the last
306 * digit to bring the shortest string also the closest to the
307 * actual number).
308 *
309 * @param scaled_upper Scaled upper bound of numbers that have the
310 * same binary representation as the converted number.
311 * Scaled by 10^-scale so that alpha <= exponent <= gamma.
312 * @param delta scaled_upper - delta is the lower bound of numbers
313 * that share the same binary representation in double.
314 * @param val_dist scaled_upper - val_dist is the number whose
315 * decimal string we're generating.
316 * @param scale Decimal scaling of the value to convert (ie scaled_upper).
317 * @param buf Buffer to store the string representation. Must be large
318 * enough to store all digits and a null terminator. At most
319 * MAX_DOUBLE_STR_LEN digits will be written (not counting
320 * the null terminator).
321 * @param buf_size Size of buf in bytes.
322 * @param dec_exponent Will be set to the decimal exponent of the number
323 * string in buf.
324 *
325 * @return Number of digits; negative on failure (eg buffer too small).
326 */
327static int gen_dec_digits(fp_num_t scaled_upper, fp_num_t delta,
328 fp_num_t val_dist, int scale, char *buf, size_t buf_size, int *dec_exponent)
329{
330 /*
331 * The integral part of scaled_upper is 5 to 32 bits long while
332 * the remaining fractional part is 59 to 32 bits long because:
333 * -59 == alpha <= scaled_upper.e <= gamma == -32
334 *
335 * | <------- delta -------> |
336 * | | <--- val_dist ---> |
337 * | | |<- remainder ->|
338 * | | | |
339 * | | ` buffer |
340 * | ` val ` upper
341 * ` lower
342 *
343 */
344 assert(scaled_upper.significand != 0);
345 assert(alpha <= scaled_upper.exponent && scaled_upper.exponent <= gamma);
346 assert(scaled_upper.exponent == delta.exponent);
347 assert(scaled_upper.exponent == val_dist.exponent);
348 assert(val_dist.significand <= delta.significand);
349
350 /* We'll produce at least one digit and a null terminator. */
351 if (buf_size < 2) {
352 return -1;
353 }
354
355 /* one is number 1 encoded with the same exponent as scaled_upper */
356 fp_num_t one;
357 one.significand = ((uint64_t) 1) << (-scaled_upper.exponent);
358 one.exponent = scaled_upper.exponent;
359
360 /*
361 * Extract the integral part of scaled_upper.
362 * upper / one == upper >> -one.e
363 */
364 uint32_t int_part = (uint32_t)(scaled_upper.significand >> (-one.exponent));
365
366 /*
367 * Fractional part of scaled_upper.
368 * upper % one == upper & (one.f - 1)
369 */
370 uint64_t frac_part = scaled_upper.significand & (one.significand - 1);
371
372 /*
373 * The integral part of upper has at least 5 bits (64 + alpha) and
374 * at most 32 bits (64 + gamma). The integral part has at most 10
375 * decimal digits, so kappa <= 10.
376 */
377 int kappa = 10;
378 uint32_t div = 1000000000;
379 size_t len = 0;
380
381 /* Produce decimal digits for the integral part of upper. */
382 while (kappa > 0) {
383 int digit = int_part / div;
384 int_part %= div;
385
386 --kappa;
387
388 /* Skip leading zeros. */
389 if (digit != 0 || len != 0) {
390 /* Current length + new digit + null terminator <= buf_size */
391 if (len + 2 <= buf_size) {
392 buf[len] = '0' + digit;
393 ++len;
394 } else {
395 return -1;
396 }
397 }
398
399 /*
400 * Difference between the so far produced decimal number and upper
401 * is calculated as: remaining_int_part * one + frac_part
402 */
403 uint64_t remainder = (((uint64_t)int_part) << -one.exponent) + frac_part;
404
405 /* The produced decimal number would convert back to upper. */
406 if (remainder <= delta.significand) {
407 assert(0 < len && len < buf_size);
408 *dec_exponent = kappa - scale;
409 buf[len] = '\0';
410
411 /* Of the shortest representations choose the numerically closest. */
412 round_last_digit(remainder, val_dist.significand, delta.significand,
413 (uint64_t)div << (-one.exponent), buf, len);
414 return len;
415 }
416
417 div /= 10;
418 }
419
420 /* Generate decimal digits for the fractional part of upper. */
421 do {
422 /*
423 * Does not overflow because at least 5 upper bits were
424 * taken by the integral part and are now unused in frac_part.
425 */
426 frac_part *= 10;
427 delta.significand *= 10;
428 val_dist.significand *= 10;
429
430 /* frac_part / one */
431 int digit = (int)(frac_part >> (-one.exponent));
432
433 /* frac_part %= one */
434 frac_part &= one.significand - 1;
435
436 --kappa;
437
438 /* Skip leading zeros. */
439 if (digit == 0 && len == 0) {
440 continue;
441 }
442
443 /* Current length + new digit + null terminator <= buf_size */
444 if (len + 2 <= buf_size) {
445 buf[len] = '0' + digit;
446 ++len;
447 } else {
448 return -1;
449 }
450 } while (frac_part > delta.significand);
451
452 assert(0 < len && len < buf_size);
453
454 *dec_exponent = kappa - scale;
455 buf[len] = '\0';
456
457 /* Of the shortest representations choose the numerically closest one. */
458 round_last_digit(frac_part, val_dist.significand, delta.significand,
459 one.significand, buf, len);
460
461 return len;
462}
463
464/** Produce a string for 0.0 */
465static int zero_to_str(char *buf, size_t buf_size, int *dec_exponent)
466{
467 if (2 <= buf_size) {
468 buf[0] = '0';
469 buf[1] = '\0';
470 *dec_exponent = 0;
471 return 1;
472 } else {
473 return -1;
474 }
475}
476
477
478/** Converts a non-special double into its shortest accurate string
479 * representation.
480 *
481 * Produces an accurate string representation, ie the string will
482 * convert back to the same binary double (eg via strtod). In the
483 * vast majority of cases (99%) the string will be the shortest such
484 * string that is also the closest to the value of any shortest
485 * string representations. Therefore, no trailing zeros are ever
486 * produced.
487 *
488 * Conceptually, the value is: buf * 10^dec_exponent
489 *
490 * Never outputs trailing zeros.
491 *
492 * @param ieee_val Binary double description to convert. Must be the product
493 * of extract_ieee_double and it must not be a special number.
494 * @param buf Buffer to store the string representation. Must be large
495 * enough to store all digits and a null terminator. At most
496 * MAX_DOUBLE_STR_LEN digits will be written (not counting
497 * the null terminator).
498 * @param buf_size Size of buf in bytes.
499 * @param dec_exponent Will be set to the decimal exponent of the number
500 * string in buf.
501 *
502 * @return The number of printed digits. A negative value indicates
503 * an error: buf too small (or ieee_val.is_special).
504 */
505int double_to_short_str(ieee_double_t ieee_val, char *buf, size_t buf_size,
506 int *dec_exponent)
507{
508 /* The whole computation assumes 64bit significand. */
509 static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
510
511 if (ieee_val.is_special) {
512 return -1;
513 }
514
515 /* Zero cannot be normalized. Handle it here. */
516 if (0 == ieee_val.pos_val.significand) {
517 return zero_to_str(buf, buf_size, dec_exponent);
518 }
519
520 fp_num_t scaled_upper_bound;
521 fp_num_t delta;
522 fp_num_t val_dist;
523 int scale;
524
525 calc_scaled_bounds(ieee_val, &scaled_upper_bound,
526 &delta, &val_dist, &scale);
527
528 int len = gen_dec_digits(scaled_upper_bound, delta, val_dist, scale,
529 buf, buf_size, dec_exponent);
530
531 assert(len <= MAX_DOUBLE_STR_LEN);
532 return len;
533}
534
535/** Generates a fixed number of decimal digits of w_scaled.
536 *
537 * double == w_scaled * 10^-scale, where alpha <= w_scaled.e <= gamma
538 *
539 * @param w_scaled Scaled number by 10^-scale so that
540 * alpha <= exponent <= gamma
541 * @param scale Decimal scaling of the value to convert (ie w_scaled).
542 * @param signif_d_cnt Maximum number of significant digits to output.
543 * Negative if as many as possible are requested.
544 * @param frac_d_cnt Maximum number of fractional digits to output.
545 * Negative if as many as possible are requested.
546 * Eg. if 2 then 1.234 -> "1.23"; if 2 then 3e-9 -> "0".
547 * @param buf Buffer to store the string representation. Must be large
548 * enough to store all digits and a null terminator. At most
549 * MAX_DOUBLE_STR_LEN digits will be written (not counting
550 * the null terminator).
551 * @param buf_size Size of buf in bytes.
552 *
553 * @return Number of digits; negative on failure (eg buffer too small).
554 */
555static int gen_fixed_dec_digits(fp_num_t w_scaled, int scale, int signif_d_cnt,
556 int frac_d_cnt, char *buf, size_t buf_size, int *dec_exponent)
557{
558 /* We'll produce at least one digit and a null terminator. */
559 if (0 == signif_d_cnt || buf_size < 2) {
560 return -1;
561 }
562
563 /*
564 * The integral part of w_scaled is 5 to 32 bits long while the
565 * remaining fractional part is 59 to 32 bits long because:
566 * -59 == alpha <= w_scaled.e <= gamma == -32
567 *
568 * Therefore:
569 * | 5..32 bits | 32..59 bits | == w_scaled == w * 10^scale
570 * | int_part | frac_part |
571 * |0 0 .. 0 1|0 0 .. 0 0| == one == 1.0
572 * | 0 |0 0 .. 0 1| == w_err == 1 * 2^w_scaled.e
573 */
574 assert(alpha <= w_scaled.exponent && w_scaled.exponent <= gamma);
575 assert(0 != w_scaled.significand);
576
577 /*
578 * Scaling the number being converted by 10^scale introduced
579 * an error of less that 1 ulp. The actual value of w_scaled
580 * could lie anywhere between w_scaled.signif +/- w_err.
581 * Scale the error locally as we scale the fractional part
582 * of w_scaled.
583 */
584 uint64_t w_err = 1;
585
586 /* one is number 1.0 encoded with the same exponent as w_scaled */
587 fp_num_t one;
588 one.significand = ((uint64_t) 1) << (-w_scaled.exponent);
589 one.exponent = w_scaled.exponent;
590
591 /* Extract the integral part of w_scaled.
592 w_scaled / one == w_scaled >> -one.e */
593 uint32_t int_part = (uint32_t)(w_scaled.significand >> (-one.exponent));
594
595 /* Fractional part of w_scaled.
596 w_scaled % one == w_scaled & (one.f - 1) */
597 uint64_t frac_part = w_scaled.significand & (one.significand - 1);
598
599 size_t len = 0;
600 /*
601 * The integral part of w_scaled has at least 5 bits (64 + alpha = 5)
602 * and at most 32 bits (64 + gamma = 32). The integral part has
603 * at most 10 decimal digits, so kappa <= 10.
604 */
605 int kappa = 10;
606 uint32_t div = 1000000000;
607
608 int rem_signif_d_cnt = signif_d_cnt;
609 int rem_frac_d_cnt =
610 (frac_d_cnt >= 0) ? (kappa - scale + frac_d_cnt) : INT_MAX;
611
612 /* Produce decimal digits for the integral part of w_scaled. */
613 while (kappa > 0 && rem_signif_d_cnt != 0 && rem_frac_d_cnt > 0) {
614 int digit = int_part / div;
615 int_part %= div;
616
617 div /= 10;
618 --kappa;
619 --rem_frac_d_cnt;
620
621 /* Skip leading zeros. */
622 if (digit == 0 && len == 0) {
623 continue;
624 }
625
626 /* Current length + new digit + null terminator <= buf_size */
627 if (len + 2 <= buf_size) {
628 buf[len] = '0' + digit;
629 ++len;
630 --rem_signif_d_cnt;
631 } else {
632 return -1;
633 }
634 }
635
636 /* Generate decimal digits for the fractional part of w_scaled. */
637 while (w_err <= frac_part && rem_signif_d_cnt != 0 && rem_frac_d_cnt > 0) {
638 /*
639 * Does not overflow because at least 5 upper bits were
640 * taken by the integral part and are now unused in frac_part.
641 */
642 frac_part *= 10;
643 w_err *= 10;
644
645 /* frac_part / one */
646 int digit = (int)(frac_part >> (-one.exponent));
647
648 /* frac_part %= one */
649 frac_part &= one.significand - 1;
650
651 --kappa;
652 --rem_frac_d_cnt;
653
654 /* Skip leading zeros. */
655 if (digit == 0 && len == 0) {
656 continue;
657 }
658
659 /* Current length + new digit + null terminator <= buf_size */
660 if (len + 2 <= buf_size) {
661 buf[len] = '0' + digit;
662 ++len;
663 --rem_signif_d_cnt;
664 } else {
665 return -1;
666 }
667 };
668
669 assert(/* 0 <= len && */ len < buf_size);
670
671 if (0 < len) {
672 *dec_exponent = kappa - scale;
673 assert(frac_d_cnt < 0 || -frac_d_cnt <= *dec_exponent);
674 } else {
675 /*
676 * The number of fractional digits was too limiting to produce
677 * any digits.
678 */
679 assert(rem_frac_d_cnt <= 0 || w_scaled.significand == 0);
680 *dec_exponent = 0;
681 buf[0] = '0';
682 len = 1;
683 }
684
685 if (len < buf_size) {
686 buf[len] = '\0';
687 assert(signif_d_cnt < 0 || (int)len <= signif_d_cnt);
688 return len;
689 } else {
690 return -1;
691 }
692}
693
694
695/** Converts a non-special double into its string representation.
696 *
697 * Conceptually, the truncated double value is: buf * 10^dec_exponent
698 *
699 * Conversion errors are tracked, so all produced digits except the
700 * last one are accurate. Garbage digits are never produced.
701 * If the requested number of digits cannot be produced accurately
702 * due to conversion errors less digits are produced than requested
703 * and the last digit has an error of +/- 1 (so if '7' is the last
704 * converted digit it might have been converted to any of '6'..'8'
705 * had the conversion been completely precise).
706 *
707 * If no error occurs at least one digit is output.
708 *
709 * The conversion stops once the requested number of significant or
710 * fractional digits is reached or the conversion error is too large
711 * to generate any more digits (whichever happens first).
712 *
713 * Any digits following the first (most-significant) digit (this digit
714 * included) are counted as significant digits; eg:
715 * 1.4, 4 signif -> "1400" * 10^-3, ie 1.400
716 * 1000.3, 1 signif -> "1" * 10^3 ie 1000
717 * 0.003, 2 signif -> "30" * 10^-4 ie 0.003
718 * 9.5 1 signif -> "9" * 10^0, ie 9
719 *
720 * Any digits following the decimal point are counted as fractional digits.
721 * This includes the zeros that would appear between the decimal point
722 * and the first non-zero fractional digit. If fewer fractional digits
723 * are requested than would allow to place the most-significant digit
724 * a "0" is output. Eg:
725 * 1.4, 3 frac -> "1400" * 10^-3, ie 1.400
726 * 12.34 4 frac -> "123400" * 10^-4, ie 12.3400
727 * 3e-99 4 frac -> "0" * 10^0, ie 0
728 * 0.009 2 frac -> "0" * 10^-2, ie 0
729 *
730 * @param ieee_val Binary double description to convert. Must be the product
731 * of extract_ieee_double and it must not be a special number.
732 * @param signif_d_cnt Maximum number of significant digits to produce.
733 * The output is not rounded.
734 * Set to a negative value to generate as many digits
735 * as accurately possible.
736 * @param frac_d_cnt Maximum number of fractional digits to produce including
737 * any zeros immediately trailing the decimal point.
738 * The output is not rounded.
739 * Set to a negative value to generate as many digits
740 * as accurately possible.
741 * @param buf Buffer to store the string representation. Must be large
742 * enough to store all digits and a null terminator. At most
743 * MAX_DOUBLE_STR_LEN digits will be written (not counting
744 * the null terminator).
745 * @param buf_size Size of buf in bytes.
746 * @param dec_exponent Set to the decimal exponent of the number string
747 * in buf.
748 *
749 * @return The number of output digits. A negative value indicates
750 * an error: buf too small (or ieee_val.is_special, or
751 * signif_d_cnt == 0).
752 */
753int double_to_fixed_str(ieee_double_t ieee_val, int signif_d_cnt,
754 int frac_d_cnt, char *buf, size_t buf_size, int *dec_exponent)
755{
756 /* The whole computation assumes 64bit significand. */
757 static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
758
759 if (ieee_val.is_special) {
760 return -1;
761 }
762
763 /* Zero cannot be normalized. Handle it here. */
764 if (0 == ieee_val.pos_val.significand) {
765 return zero_to_str(buf, buf_size, dec_exponent);
766 }
767
768 /* Normalize and scale. */
769 fp_num_t w = normalize(ieee_val.pos_val);
770
771 int lower_bin_exp = alpha - w.exponent - significand_width;
772
773 int scale;
774 fp_num_t scaling_power_of_10;
775
776 get_power_of_ten(lower_bin_exp, &scaling_power_of_10, &scale);
777
778 fp_num_t w_scaled = multiply(w, scaling_power_of_10);
779
780 /* Produce decimal digits from the scaled number. */
781 int len = gen_fixed_dec_digits(w_scaled, scale, signif_d_cnt, frac_d_cnt,
782 buf, buf_size, dec_exponent);
783
784 assert(len <= MAX_DOUBLE_STR_LEN);
785 return len;
786}
787
Note: See TracBrowser for help on using the repository browser.