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 */
| 576 | * 255: - inf |
| 577 | */ |
| 578 | int rdbSaveDoubleValue(rio *rdb, double val) { |
| 579 | unsigned char buf[128]; |
| 580 | int len; |
| 581 | |
| 582 | if (isnan(val)) { |
| 583 | buf[0] = 253; |
| 584 | len = 1; |
| 585 | } else if (!isfinite(val)) { |
| 586 | len = 1; |
| 587 | buf[0] = (val < 0) ? 255 : 254; |
| 588 | } else { |
| 589 | #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL) |
| 590 | /* Check if the float is in a safe range to be casted into a |
| 591 | * long long. We are assuming that long long is 64 bit here. |
| 592 | * Also we are assuming that there are no implementations around where |
| 593 | * double has precision < 52 bit. |
| 594 | * |
| 595 | * Under this assumptions we test if a double is inside an interval |
| 596 | * where casting to long long is safe. Then using two castings we |
| 597 | * make sure the decimal part is zero. If all this is true we use |
| 598 | * integer printing function that is much faster. */ |
| 599 | double min = -4503599627370495; /* (2^52)-1 */ |
| 600 | double max = 4503599627370496; /* -(2^52) */ |
| 601 | if (val > min && val < max && val == ((double)((long long)val))) |
| 602 | ll2string((char*)buf+1,sizeof(buf)-1,(long long)val); |
| 603 | else |
| 604 | #endif |
| 605 | snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val); |
| 606 | buf[0] = strlen((char*)buf+1); |
| 607 | len = buf[0]+1; |
| 608 | } |
| 609 | return rdbWriteRaw(rdb,buf,len); |
| 610 | } |
| 611 | |
| 612 | /* For information about double serialization check rdbSaveDoubleValue() */ |
| 613 | int rdbLoadDoubleValue(rio *rdb, double *val) { |
nothing calls this directly
no test coverage detected