29 #ifndef XAPIAN_UNITTEST
30 # define UNITTEST_ASSERT_NOTHROW(COND,RET)
40 #include <string_view>
45 # error Code currently assumes FLT_RADIX == 2
54 if (
rare(!isfinite(value))) {
61 memset(buf,
'\xff', 9);
67 double mantissa = frexp(value, &exponent);
77 if (mantissa == 0.0 ||
rare(exponent < -2039)) {
82 if (
rare(exponent > 2055)) {
84 goto handle_as_infinity;
87 bool negative = (mantissa < 0);
88 if (negative) mantissa = -mantissa;
98 unsigned char next = (negative ? 0 : 0xe0);
102 bool exponent_negative = (exponent < 0);
103 if (exponent_negative) {
104 exponent = -exponent;
121 next |=
static_cast<unsigned char>(exponent << 2);
122 if (negative ^ exponent_negative) next ^= 0x1c;
127 next |=
static_cast<unsigned char>(exponent >> 6);
128 if (negative ^ exponent_negative) next ^= 0x1f;
132 next =
static_cast<unsigned char>(exponent << 2);
133 if (negative ^ exponent_negative) next ^= 0xfc;
137 mantissa *= 1 << (negative ? 26 : 27);
138 unsigned word1 =
static_cast<unsigned>(mantissa);
140 unsigned word2 =
static_cast<unsigned>(mantissa * 4294967296.0);
153 if (word2 != 0) ++word1;
158 next |=
static_cast<unsigned char>(word1 >> 24);
160 buf[len++] = char(word1 >> 16);
161 buf[len++] = char(word1 >> 8);
162 buf[len++] = char(word1);
164 buf[len++] = char(word2 >> 24);
165 buf[len++] = char(word2 >> 16);
166 buf[len++] = char(word2 >> 8);
167 buf[len++] = char(word2);
170 while (len > 0 && buf[len - 1] ==
'\0') {
179 static inline unsigned char
182 return (
pos <
str.size()) ?
static_cast<unsigned char>(
str[
pos]) :
'\0';
189 if (value.size() == 1 && value[0] ==
'\x80')
return 0.0;
192 if (value.size() == 9 &&
193 memcmp(value.data(),
"\xff\xff\xff\xff\xff\xff\xff\xff\xff", 9) == 0) {
208 first ^=
static_cast<unsigned char>(first & 0xc0) >> 1;
209 bool negative = !(first & 0x80);
210 bool exponent_negative = (first & 0x40);
211 bool explen = !(first & 0x20);
212 int exponent = first & 0x1f;
215 if (negative ^ exponent_negative) exponent ^= 0x07;
219 exponent |= (first >> 2);
220 if (negative ^ exponent_negative) exponent ^= 0x07ff;
224 word1 = (unsigned(first & 0x03) << 24);
230 if (i < value.size()) {
239 if (word2 != 0) ++word1;
244 if (!negative) word1 |= 1<<26;
247 if (word2) mantissa = word2 / 4294967296.0;
249 mantissa /= 1 << (negative ? 26 : 27);
251 if (exponent_negative) exponent = -exponent;
254 if (negative) mantissa = -mantissa;
261 return scalbn(mantissa, exponent);
string str(int value)
Convert int to std::string.
size_t sortable_serialise_(double value, char *buf) noexcept
double sortable_unserialise(std::string_view serialised) noexcept
Convert a string encoded using sortable_serialise back to a floating point number.
Negate unsigned integer, avoiding compiler warnings.
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > negate_unsigned(T value)
parsing a user query string to build a Xapian::Query object
static unsigned char numfromstr(std::string_view str, std::string::size_type pos)
Get a number from the character at a given position in a string, returning 0 if the string isn't long...
#define UNITTEST_ASSERT_NOTHROW(COND, RET)