Create a string object from a long double. * If mode is humanfriendly it does not use exponential format and trims trailing * zeroes at the end (may result in loss of precision). * If mode is default exp format is used and the output of snprintf() * is not modified (may result in loss of precision). * If mode is hex hexadecimal format is used (no loss of precision) * * The function returns
| 587 | * The function returns the length of the string or zero if there was not |
| 588 | * enough buffer room to store it. */ |
| 589 | int ld2string(char *buf, size_t len, long double value, ld2string_mode mode) { |
| 590 | size_t l = 0; |
| 591 | |
| 592 | if (isinf(value)) { |
| 593 | /* Libc in odd systems (Hi Solaris!) will format infinite in a |
| 594 | * different way, so better to handle it in an explicit way. */ |
| 595 | if (len < 5) return 0; /* No room. 5 is "-inf\0" */ |
| 596 | if (value > 0) { |
| 597 | memcpy(buf,"inf",3); |
| 598 | l = 3; |
| 599 | } else { |
| 600 | memcpy(buf,"-inf",4); |
| 601 | l = 4; |
| 602 | } |
| 603 | } else { |
| 604 | switch (mode) { |
| 605 | case LD_STR_AUTO: |
| 606 | l = snprintf(buf,len,"%.17Lg",value); |
| 607 | if (l+1 > len) return 0; /* No room. */ |
| 608 | break; |
| 609 | case LD_STR_HEX: |
| 610 | l = snprintf(buf,len,"%La",value); |
| 611 | if (l+1 > len) return 0; /* No room. */ |
| 612 | break; |
| 613 | case LD_STR_HUMAN: |
| 614 | /* We use 17 digits precision since with 128 bit floats that precision |
| 615 | * after rounding is able to represent most small decimal numbers in a |
| 616 | * way that is "non surprising" for the user (that is, most small |
| 617 | * decimal numbers will be represented in a way that when converted |
| 618 | * back into a string are exactly the same as what the user typed.) */ |
| 619 | l = snprintf(buf,len,"%.17Lf",value); |
| 620 | if (l+1 > len) return 0; /* No room. */ |
| 621 | /* Now remove trailing zeroes after the '.' */ |
| 622 | if (strchr(buf,'.') != NULL) { |
| 623 | char *p = buf+l-1; |
| 624 | while(*p == '0') { |
| 625 | p--; |
| 626 | l--; |
| 627 | } |
| 628 | if (*p == '.') l--; |
| 629 | } |
| 630 | if (l == 2 && buf[0] == '-' && buf[1] == '0') { |
| 631 | buf[0] = '0'; |
| 632 | l = 1; |
| 633 | } |
| 634 | break; |
| 635 | default: return 0; /* Invalid mode. */ |
| 636 | } |
| 637 | } |
| 638 | buf[l] = '\0'; |
| 639 | return l; |
| 640 | } |
| 641 | |
| 642 | /* Get random bytes, attempts to get an initial seed from /dev/urandom and |
| 643 | * the uses a one way hash function in counter mode to generate a random |
no test coverage detected