48 # ifdef WORDS_BIGENDIAN
50 static_assert(
sizeof(temp) ==
sizeof(v),
51 "Check if size of double and 64 bit int is same");
52 memcpy(&temp, &v,
sizeof(
double));
54 return string(
reinterpret_cast<const char *
>(&temp),
sizeof(
double));
56 return string(
reinterpret_cast<const char *
>(&v),
sizeof(
double));
64 "Bad encoded double: insufficient data");
67 # ifdef WORDS_BIGENDIAN
69 static_assert(
sizeof(temp) ==
sizeof(
double),
70 "Check if size of double and 64 bit int is same");
71 memcpy(&temp, *
p,
sizeof(
double));
73 memcpy(&result, &temp,
sizeof(
double));
75 memcpy(&result, *
p,
sizeof(
double));
100 static_assert(uint64_t(1) << 52 < numeric_limits<double>::max(),
101 "Check if 2^52 can be represented by a double");
107 return string(
reinterpret_cast<const char *
>(&result),
111 if (
rare(!isfinite(v))) {
114 const static char pos_inf[] = {
115 '\x7f',
'\xf0',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00'
117 const static char neg_inf[] = {
118 '\xff',
'\xf0',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00'
120 const static char pos_nan[] = {
121 '\x7f',
'\xf8',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00'
123 const static char neg_nan[] = {
124 '\xff',
'\xf8',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00',
'\x00'
127 return string(v > 0 ? pos_inf : neg_inf, 8);
129 return string(v > 0 ? pos_nan : neg_nan, 8);
132 bool negative = (v < 0.0);
135 result |= uint64_t(1) << 63;
144 result |= uint64_t(exp) << 52;
147 double scaled_v = scalbn(v, 52);
149 double scaled_v = ldexp(v, 52);
152 uint64_t scaled_v_int =
static_cast<uint64_t
>(scaled_v);
153 result |= scaled_v_int;
155 # ifdef WORDS_BIGENDIAN
159 return string(
reinterpret_cast<const char *
>(&result),
sizeof(uint64_t));
165 "Bad encoded double: insufficient data");
167 unsigned char first = *(*
p + 7);
168 unsigned char second = *(*
p + 6);
170 bool negative = (first & (0x80)) != 0;
173 int exp = (first & (0x80 - 1));
175 exp |= (second & (15 << 4)) >> 4;
178 uint64_t mantissa_bp;
179 memcpy(&mantissa_bp, *
p,
sizeof(
double));
180 mantissa_bp &= (uint64_t(1) << 52) - 1;
184 if (exp + 1023 == 0 && mantissa_bp == 0)
return 0.0;
186 if (
rare(exp == 1024)) {
188 if (mantissa_bp != 0) {
191 return negative ? -nan(
"") : nan(
"");
195 return negative ? -HUGE_VAL : HUGE_VAL;
199 double result = scalbn(mantissa_bp, -52);
200 result = scalbn(result + 1.0, exp);
202 double result = ldexp(mantissa_bp, -52);
203 result = ldexp(result + 1.0, exp);
206 if (negative) result = -result;
Indicates an error in the std::string serialisation of an object.
Hierarchy of classes which Xapian can throw as exceptions.
Various assertion macros.
string serialise_double(double v)
Serialise a double to a string.
double unserialise_double(const char **p, const char *end)
Unserialise a double serialised by serialise_double.
functions to serialise and unserialise a double
functions for reading and writing different width words
uint16_t do_bswap(uint16_t value)