Save a double value. Doubles are saved as strings prefixed by an unsigned * 8 bit integer specifying the length of the representation. * This 8 bit integer has special values in order to specify the following * conditions: * 253: not a number * 254: + inf * 255: - inf */
| 590 | * 255: - inf |
| 591 | */ |
| 592 | int rdbSaveDoubleValue(rio *rdb, double val) { |
| 593 | unsigned char buf[128]; |
| 594 | int len; |
| 595 | |
| 596 | if (std::isnan(val)) { |
| 597 | buf[0] = 253; |
| 598 | len = 1; |
| 599 | } else if (!std::isfinite(val)) { |
| 600 | len = 1; |
| 601 | buf[0] = (val < 0) ? 255 : 254; |
| 602 | } else { |
| 603 | #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL) |
| 604 | /* Check if the float is in a safe range to be casted into a |
| 605 | * long long. We are assuming that long long is 64 bit here. |
| 606 | * Also we are assuming that there are no implementations around where |
| 607 | * double has precision < 52 bit. |
| 608 | * |
| 609 | * Under this assumptions we test if a double is inside an interval |
| 610 | * where casting to long long is safe. Then using two castings we |
| 611 | * make sure the decimal part is zero. If all this is true we use |
| 612 | * integer printing function that is much faster. */ |
| 613 | double min = -4503599627370495; /* (2^52)-1 */ |
| 614 | double max = 4503599627370496; /* -(2^52) */ |
| 615 | if (val > min && val < max && val == ((double)((long long)val))) |
| 616 | ll2string((char*)buf+1,sizeof(buf)-1,(long long)val); |
| 617 | else |
| 618 | #endif |
| 619 | snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val); |
| 620 | buf[0] = strlen((char*)buf+1); |
| 621 | len = buf[0]+1; |
| 622 | } |
| 623 | return rdbWriteRaw(rdb,buf,len); |
| 624 | } |
| 625 | |
| 626 | /* For information about double serialization check rdbSaveDoubleValue() */ |
| 627 | int rdbLoadDoubleValue(rio *rdb, double *val) { |
nothing calls this directly
no test coverage detected