Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
fast_float Namespace Reference

Namespaces

namespace  anonymous_namespace{fast_float.h}
 
namespace  detail
 

Classes

struct  adjusted_mantissa
 
struct  binary_format
 
struct  decimal
 
struct  from_chars_result
 
struct  parse_options
 
struct  parsed_number_string
 
struct  powers_template
 
struct  value128
 

Typedefs

using powers = powers_template<>
 

Enumerations

enum  chars_format { scientific = 1<<0 , fixed = 1<<2 , hex = 1<<3 , general = fixed | scientific }
 

Functions

template<typename T >
from_chars_result from_chars (const char *first, const char *last, T &value, chars_format fmt=chars_format::general) noexcept
 
template<typename T >
from_chars_result from_chars_advanced (const char *first, const char *last, T &value, parse_options options) noexcept
 
bool fastfloat_strncasecmp (const char *input1, const char *input2, size_t length)
 
fastfloat_really_inline int leading_zeroes (uint64_t input_num)
 
fastfloat_really_inline value128 full_multiplication (uint64_t a, uint64_t b)
 
fastfloat_really_inline bool is_integer (char c) noexcept
 
fastfloat_really_inline uint64_t byteswap (uint64_t val)
 
fastfloat_really_inline uint64_t read_u64 (const char *chars)
 
fastfloat_really_inline void write_u64 (uint8_t *chars, uint64_t val)
 
fastfloat_really_inline uint32_t parse_eight_digits_unrolled (uint64_t val)
 
fastfloat_really_inline uint32_t parse_eight_digits_unrolled (const char *chars) noexcept
 
fastfloat_really_inline bool is_made_of_eight_digits_fast (uint64_t val) noexcept
 
fastfloat_really_inline bool is_made_of_eight_digits_fast (const char *chars) noexcept
 
fastfloat_really_inline parsed_number_string parse_number_string (const char *p, const char *pend, parse_options options) noexcept
 
fastfloat_really_inline decimal parse_decimal (const char *p, const char *pend, parse_options options) noexcept
 
template<int bit_precision>
fastfloat_really_inline value128 compute_product_approximation (int64_t q, uint64_t w)
 
template<typename binary >
fastfloat_really_inline adjusted_mantissa compute_float (int64_t q, uint64_t w) noexcept
 
template<typename binary >
adjusted_mantissa compute_float (decimal &d)
 
template<typename binary >
adjusted_mantissa parse_long_mantissa (const char *first, const char *last, parse_options options)
 

Variables

static constexpr double powers_of_ten_double []
 
static constexpr float powers_of_ten_float []
 

Detailed Description

This code is meant to handle the case where we have more than 19 digits.

It is based on work by Nigel Tao (at https://github.com/google/wuffs/) who credits Ken Thompson for the design (via a reference to the Go source code).

Rob Pike suggested that this algorithm be called "Simple Decimal Conversion".

It is probably not very fast but it is a fallback that should almost never be used in real life. Though it is not fast, it is "easily" understood and debugged.


Class Documentation

◆ fast_float::from_chars_result

struct fast_float::from_chars_result
Class Members
errc ec
const char * ptr

◆ fast_float::parsed_number_string

struct fast_float::parsed_number_string
Class Members
int64_t exponent
const char * lastmatch
uint64_t mantissa
bool negative
bool too_many_digits
bool valid

Typedef Documentation

◆ powers

Enumeration Type Documentation

◆ chars_format

Enumerator
scientific 
fixed 
hex 
general 
44 {
45 scientific = 1<<0,
46 fixed = 1<<2,
47 hex = 1<<3,
49};
@ hex
Definition fast_float.h:47
@ scientific
Definition fast_float.h:45
@ general
Definition fast_float.h:48
@ fixed
Definition fast_float.h:46

Function Documentation

◆ byteswap()

fastfloat_really_inline uint64_t fast_float::byteswap ( uint64_t  val)
455 {
456 return (val & 0xFF00000000000000) >> 56
457 | (val & 0x00FF000000000000) >> 40
458 | (val & 0x0000FF0000000000) >> 24
459 | (val & 0x000000FF00000000) >> 8
460 | (val & 0x00000000FF000000) << 8
461 | (val & 0x0000000000FF0000) << 24
462 | (val & 0x000000000000FF00) << 40
463 | (val & 0x00000000000000FF) << 56;
464}

Referenced by read_u64(), and write_u64().

+ Here is the caller graph for this function:

◆ compute_float() [1/2]

template<typename binary >
adjusted_mantissa fast_float::compute_float ( decimal d)
2200 {
2201 adjusted_mantissa answer;
2202 if (d.num_digits == 0) {
2203 // should be zero
2204 answer.power2 = 0;
2205 answer.mantissa = 0;
2206 return answer;
2207 }
2208 // At this point, going further, we can assume that d.num_digits > 0.
2209 //
2210 // We want to guard against excessive decimal point values because
2211 // they can result in long running times. Indeed, we do
2212 // shifts by at most 60 bits. We have that log(10**400)/log(2**60) ~= 22
2213 // which is fine, but log(10**299995)/log(2**60) ~= 16609 which is not
2214 // fine (runs for a long time).
2215 //
2216 if(d.decimal_point < -324) {
2217 // We have something smaller than 1e-324 which is always zero
2218 // in binary64 and binary32.
2219 // It should be zero.
2220 answer.power2 = 0;
2221 answer.mantissa = 0;
2222 return answer;
2223 } else if(d.decimal_point >= 310) {
2224 // We have something at least as large as 0.1e310 which is
2225 // always infinite.
2226 answer.power2 = binary::infinite_power();
2227 answer.mantissa = 0;
2228 return answer;
2229 }
2230 static const uint32_t max_shift = 60;
2231 static const uint32_t num_powers = 19;
2232 static const uint8_t decimal_powers[19] = {
2233 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, //
2234 33, 36, 39, 43, 46, 49, 53, 56, 59, //
2235 };
2236 int32_t exp2 = 0;
2237 while (d.decimal_point > 0) {
2238 uint32_t n = uint32_t(d.decimal_point);
2239 uint32_t shift = (n < num_powers) ? decimal_powers[n] : max_shift;
2240 detail::decimal_right_shift(d, shift);
2241 if (d.decimal_point < -decimal_point_range) {
2242 // should be zero
2243 answer.power2 = 0;
2244 answer.mantissa = 0;
2245 return answer;
2246 }
2247 exp2 += int32_t(shift);
2248 }
2249 // We shift left toward [1/2 ... 1].
2250 while (d.decimal_point <= 0) {
2251 uint32_t shift;
2252 if (d.decimal_point == 0) {
2253 if (d.digits[0] >= 5) {
2254 break;
2255 }
2256 shift = (d.digits[0] < 2) ? 2 : 1;
2257 } else {
2258 uint32_t n = uint32_t(-d.decimal_point);
2259 shift = (n < num_powers) ? decimal_powers[n] : max_shift;
2260 }
2261 detail::decimal_left_shift(d, shift);
2262 if (d.decimal_point > decimal_point_range) {
2263 // we want to get infinity:
2264 answer.power2 = binary::infinite_power();
2265 answer.mantissa = 0;
2266 return answer;
2267 }
2268 exp2 -= int32_t(shift);
2269 }
2270 // We are now in the range [1/2 ... 1] but the binary format uses [1 ... 2].
2271 exp2--;
2272 constexpr int32_t minimum_exponent = binary::minimum_exponent();
2273 while ((minimum_exponent + 1) > exp2) {
2274 uint32_t n = uint32_t((minimum_exponent + 1) - exp2);
2275 if (n > max_shift) {
2276 n = max_shift;
2277 }
2278 detail::decimal_right_shift(d, n);
2279 exp2 += int32_t(n);
2280 }
2281 if ((exp2 - minimum_exponent) >= binary::infinite_power()) {
2282 answer.power2 = binary::infinite_power();
2283 answer.mantissa = 0;
2284 return answer;
2285 }
2286
2287 const int mantissa_size_in_bits = binary::mantissa_explicit_bits() + 1;
2288 detail::decimal_left_shift(d, mantissa_size_in_bits);
2289
2290 uint64_t mantissa = detail::round(d);
2291 // It is possible that we have an overflow, in which case we need
2292 // to shift back.
2293 if(mantissa >= (uint64_t(1) << mantissa_size_in_bits)) {
2294 detail::decimal_right_shift(d, 1);
2295 exp2 += 1;
2296 mantissa = detail::round(d);
2297 if ((exp2 - minimum_exponent) >= binary::infinite_power()) {
2298 answer.power2 = binary::infinite_power();
2299 answer.mantissa = 0;
2300 return answer;
2301 }
2302 }
2303 answer.power2 = exp2 - binary::minimum_exponent();
2304 if(mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) { answer.power2--; }
2305 answer.mantissa = mantissa & ((uint64_t(1) << binary::mantissa_explicit_bits()) - 1);
2306 return answer;
2307}
Definition fast_float.h:277
int power2
Definition fast_float.h:279
uint64_t mantissa
Definition fast_float.h:278
__int32 int32_t
Definition unistd.h:75
unsigned __int32 uint32_t
Definition unistd.h:79
unsigned __int8 uint8_t
Definition unistd.h:77
unsigned __int64 uint64_t
Definition unistd.h:80

References fast_float::detail::decimal_left_shift(), fast_float::detail::decimal_right_shift(), fast_float::adjusted_mantissa::mantissa, fast_float::adjusted_mantissa::power2, and fast_float::detail::round().

+ Here is the call graph for this function:

◆ compute_float() [2/2]

template<typename binary >
fastfloat_really_inline adjusted_mantissa fast_float::compute_float ( int64_t  q,
uint64_t  w 
)
noexcept
1531 {
1532 adjusted_mantissa answer;
1533 if ((w == 0) || (q < binary::smallest_power_of_ten())) {
1534 answer.power2 = 0;
1535 answer.mantissa = 0;
1536 // result should be zero
1537 return answer;
1538 }
1539 if (q > binary::largest_power_of_ten()) {
1540 // we want to get infinity:
1541 answer.power2 = binary::infinite_power();
1542 answer.mantissa = 0;
1543 return answer;
1544 }
1545 // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five].
1546
1547 // We want the most significant bit of i to be 1. Shift if needed.
1548 int lz = leading_zeroes(w);
1549 w <<= lz;
1550
1551 // The required precision is binary::mantissa_explicit_bits() + 3 because
1552 // 1. We need the implicit bit
1553 // 2. We need an extra bit for rounding purposes
1554 // 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
1555
1556 value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
1557 if(product.low == 0xFFFFFFFFFFFFFFFF) { // could guard it further
1558 // In some very rare cases, this could happen, in which case we might need a more accurate
1559 // computation that what we can provide cheaply. This is very, very unlikely.
1560 //
1561 const bool inside_safe_exponent = (q >= -27) && (q <= 55); // always good because 5**q <2**128 when q>=0,
1562 // and otherwise, for q<0, we have 5**-q<2**64 and the 128-bit reciprocal allows for exact computation.
1563 if(!inside_safe_exponent) {
1564 answer.power2 = -1; // This (a negative value) indicates an error condition.
1565 return answer;
1566 }
1567 }
1568 // The "compute_product_approximation" function can be slightly slower than a branchless approach:
1569 // value128 product = compute_product(q, w);
1570 // but in practice, we can win big with the compute_product_approximation if its additional branch
1571 // is easily predicted. Which is best is data specific.
1572 int upperbit = int(product.high >> 63);
1573
1574 answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
1575
1576 answer.power2 = int(detail::power(int(q)) + upperbit - lz - binary::minimum_exponent());
1577 if (answer.power2 <= 0) { // we have a subnormal?
1578 // Here have that answer.power2 <= 0 so -answer.power2 >= 0
1579 if(-answer.power2 + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure.
1580 answer.power2 = 0;
1581 answer.mantissa = 0;
1582 // result should be zero
1583 return answer;
1584 }
1585 // next line is safe because -answer.power2 + 1 < 64
1586 answer.mantissa >>= -answer.power2 + 1;
1587 // Thankfully, we can't have both "round-to-even" and subnormals because
1588 // "round-to-even" only occurs for powers close to 0.
1589 answer.mantissa += (answer.mantissa & 1); // round up
1590 answer.mantissa >>= 1;
1591 // There is a weird scenario where we don't have a subnormal but just.
1592 // Suppose we start with 2.2250738585072013e-308, we end up
1593 // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal
1594 // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round
1595 // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
1596 // subnormal, but we can only know this after rounding.
1597 // So we only declare a subnormal if we are smaller than the threshold.
1598 answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
1599 return answer;
1600 }
1601
1602 // usually, we round *up*, but if we fall right in between and and we have an
1603 // even basis, we need to round down
1604 // We are only concerned with the cases where 5**q fits in single 64-bit word.
1605 if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
1606 ((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
1607 // To be in-between two floats we need that in doing
1608 // answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
1609 // ... we dropped out only zeroes. But if this happened, then we can go back!!!
1610 if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
1611 answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
1612 }
1613 }
1614
1615 answer.mantissa += (answer.mantissa & 1); // round up
1616 answer.mantissa >>= 1;
1617 if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
1618 answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
1619 answer.power2++; // undo previous addition
1620 }
1621
1622 answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
1623 if (answer.power2 >= binary::infinite_power()) { // infinity
1624 answer.power2 = binary::infinite_power();
1625 answer.mantissa = 0;
1626 }
1627 return answer;
1628}
fastfloat_really_inline int leading_zeroes(uint64_t input_num)
Definition fast_float.h:207

References fast_float::value128::high, leading_zeroes(), fast_float::value128::low, fast_float::adjusted_mantissa::mantissa, fast_float::detail::power(), and fast_float::adjusted_mantissa::power2.

Referenced by from_chars_advanced().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compute_product_approximation()

template<int bit_precision>
fastfloat_really_inline value128 fast_float::compute_product_approximation ( int64_t  q,
uint64_t  w 
)
1481 {
1482 const int index = 2 * int(q - powers::smallest_power_of_five);
1483 // For small values of q, e.g., q in [0,27], the answer is always exact because
1484 // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
1485 // gives the exact answer.
1486 value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
1487 static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
1488 constexpr uint64_t precision_mask = (bit_precision < 64) ?
1489 (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
1490 : uint64_t(0xFFFFFFFFFFFFFFFF);
1491 if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
1492 // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
1493 value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
1494 firstproduct.low += secondproduct.high;
1495 if(secondproduct.high > firstproduct.low) {
1496 firstproduct.high++;
1497 }
1498 }
1499 return firstproduct;
1500}
fastfloat_really_inline value128 full_multiplication(uint64_t a, uint64_t b)
Definition fast_float.h:257
Definition fast_float.h:199
uint64_t high
Definition fast_float.h:201
uint64_t low
Definition fast_float.h:200

References full_multiplication(), fast_float::value128::high, fast_float::value128::low, fast_float::powers_template< unused >::power_of_five_128, and fast_float::powers_template< unused >::smallest_power_of_five.

+ Here is the call graph for this function:

◆ fastfloat_strncasecmp()

bool fast_float::fastfloat_strncasecmp ( const char *  input1,
const char *  input2,
size_t  length 
)
inline
181 {
182 char running_diff{0};
183 for (size_t i = 0; i < length; i++) {
184 running_diff |= (input1[i] ^ input2[i]);
185 }
186 return (running_diff == 0) || (running_diff == 32);
187}

Referenced by fast_float::detail::parse_infnan().

+ Here is the caller graph for this function:

◆ from_chars()

template<typename T >
from_chars_result fast_float::from_chars ( const char *  first,
const char *  last,
T &  value,
chars_format  fmt = chars_format::general 
)
noexcept

This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale. The resulting floating-point value is the closest floating-point values (using either float or double), using the "round to even" convention for values that would otherwise fall right in-between two values. That is, we provide exact parsing according to the IEEE standard.

Given a successful parse, the pointer (ptr) in the returned value is set to point right after the parsed number, and the value referenced is set to the parsed value. In case of error, the returned ec contains a representative error, otherwise the default (std::errc()) value is stored.

The implementation does not throw and does not allocate memory (e.g., with new or malloc).

Like the C++17 standard, the fast_float::from_chars functions take an optional last argument of the type fast_float::chars_format. It is a bitset value: we check whether fmt & fast_float::chars_format::fixed and fmt & fast_float::chars_format::scientific are set to determine whether we allowe the fixed point and scientific notation respectively. The default is fast_float::chars_format::general which allows both fixed and scientific.

2402 {
2403 return from_chars_advanced(first, last, value, parse_options{fmt});
2404}
from_chars_result from_chars_advanced(const char *first, const char *last, T &value, parse_options options) noexcept
Definition fast_float.h:2407
Definition fast_float.h:57

References from_chars_advanced().

Referenced by get_attribute_value_float(), Slic3r::GCodeReader::GCodeLine::has_value(), Slic3r::CoolingBuffer::parse_layer_gcode(), Slic3r::GCodeReader::parse_line_internal(), Slic3r::GUI::EmbossStylesSerializable::read(), Slic3r::GUI::EmbossStylesSerializable::read(), Slic3r::string_to_float_decimal_point(), and Slic3r::string_to_floating_decimal_point().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ from_chars_advanced()

template<typename T >
from_chars_result fast_float::from_chars_advanced ( const char *  first,
const char *  last,
T &  value,
parse_options  options 
)
noexcept

Like from_chars, but accepts an options argument to govern number parsing.

2408 {
2409
2410 static_assert (std::is_same<T, double>::value || std::is_same<T, float>::value, "only float and double are supported");
2411
2412
2413 from_chars_result answer;
2414 if (first == last) {
2415 answer.ec = std::errc::invalid_argument;
2416 answer.ptr = first;
2417 return answer;
2418 }
2419 parsed_number_string pns = parse_number_string(first, last, options);
2420 if (!pns.valid) {
2421 return detail::parse_infnan(first, last, value);
2422 }
2423 answer.ec = std::errc(); // be optimistic
2424 answer.ptr = pns.lastmatch;
2425 // Next is Clinger's fast path.
2426 if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path() && !pns.too_many_digits) {
2427 value = T(pns.mantissa);
2428 if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
2429 else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
2430 if (pns.negative) { value = -value; }
2431 return answer;
2432 }
2433 adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
2434 if(pns.too_many_digits) {
2435 if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
2436 am.power2 = -1; // value is invalid.
2437 }
2438 }
2439 // If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0),
2440 // then we need to go the long way around again. This is very uncommon.
2441 if(am.power2 < 0) { am = parse_long_mantissa<binary_format<T>>(first, last, options); }
2442 detail::to_float(pns.negative, am, value);
2443 return answer;
2444}
std::errc ec
Definition fast_float.h:54
const char * ptr
Definition fast_float.h:53
Definition fast_float.h:52

References compute_float(), fast_float::from_chars_result::ec, fast_float::binary_format< T >::exact_power_of_ten(), fast_float::detail::parse_infnan(), parse_number_string(), fast_float::adjusted_mantissa::power2, fast_float::from_chars_result::ptr, and fast_float::detail::to_float().

Referenced by from_chars().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_multiplication()

fastfloat_really_inline value128 fast_float::full_multiplication ( uint64_t  a,
uint64_t  b 
)
258 {
259 value128 answer;
260#ifdef _M_ARM64
261 // ARM64 has native support for 64-bit multiplications, no need to emulate
262 answer.high = __umulh(a, b);
263 answer.low = a * b;
264#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
265 answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
266#elif defined(FASTFLOAT_64BIT)
267 __uint128_t r = ((__uint128_t)a) * b;
268 answer.low = uint64_t(r);
269 answer.high = uint64_t(r >> 64);
270#else
271 #error Not implemented
272#endif
273 return answer;
274}

References fast_float::value128::high, and fast_float::value128::low.

Referenced by compute_product_approximation().

+ Here is the caller graph for this function:

◆ is_integer()

fastfloat_really_inline bool fast_float::is_integer ( char  c)
noexcept
453{ return c >= '0' && c <= '9'; }

Referenced by parse_decimal(), and parse_number_string().

+ Here is the caller graph for this function:

◆ is_made_of_eight_digits_fast() [1/2]

fastfloat_really_inline bool fast_float::is_made_of_eight_digits_fast ( const char *  chars)
noexcept
505 {
507}
fastfloat_really_inline uint64_t read_u64(const char *chars)
Definition fast_float.h:466
fastfloat_really_inline bool is_made_of_eight_digits_fast(uint64_t val) noexcept
Definition fast_float.h:500

References is_made_of_eight_digits_fast(), and read_u64().

+ Here is the call graph for this function:

◆ is_made_of_eight_digits_fast() [2/2]

fastfloat_really_inline bool fast_float::is_made_of_eight_digits_fast ( uint64_t  val)
noexcept
500 {
501 return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) &
502 0x8080808080808080));
503}

Referenced by is_made_of_eight_digits_fast(), parse_decimal(), and parse_number_string().

+ Here is the caller graph for this function:

◆ leading_zeroes()

fastfloat_really_inline int fast_float::leading_zeroes ( uint64_t  input_num)
207 {
208 assert(input_num > 0);
209#ifdef FASTFLOAT_VISUAL_STUDIO
210 #if defined(_M_X64) || defined(_M_ARM64)
211 unsigned long leading_zero = 0;
212 // Search the mask data from most significant bit (MSB)
213 // to least significant bit (LSB) for a set bit (1).
214 _BitScanReverse64(&leading_zero, input_num);
215 return (int)(63 - leading_zero);
216 #else
217 int last_bit = 0;
218 if(input_num & uint64_t(0xffffffff00000000)) input_num >>= 32, last_bit |= 32;
219 if(input_num & uint64_t( 0xffff0000)) input_num >>= 16, last_bit |= 16;
220 if(input_num & uint64_t( 0xff00)) input_num >>= 8, last_bit |= 8;
221 if(input_num & uint64_t( 0xf0)) input_num >>= 4, last_bit |= 4;
222 if(input_num & uint64_t( 0xc)) input_num >>= 2, last_bit |= 2;
223 if(input_num & uint64_t( 0x2)) input_num >>= 1, last_bit |= 1;
224 return 63 - last_bit;
225 #endif
226#else
227 return __builtin_clzll(input_num);
228#endif
229}

Referenced by compute_float().

+ Here is the caller graph for this function:

◆ parse_decimal()

fastfloat_really_inline decimal fast_float::parse_decimal ( const char *  p,
const char *  pend,
parse_options  options 
)
noexcept
661 {
662 const char decimal_point = options.decimal_point;
663
664 decimal answer;
665 answer.num_digits = 0;
666 answer.decimal_point = 0;
667 answer.truncated = false;
668 answer.negative = (*p == '-');
669 if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
670 ++p;
671 }
672 // skip leading zeroes
673 while ((p != pend) && (*p == '0')) {
674 ++p;
675 }
676 while ((p != pend) && is_integer(*p)) {
677 if (answer.num_digits < max_digits) {
678 answer.digits[answer.num_digits] = uint8_t(*p - '0');
679 }
680 answer.num_digits++;
681 ++p;
682 }
683 if ((p != pend) && (*p == decimal_point)) {
684 ++p;
685 const char *first_after_period = p;
686 // if we have not yet encountered a zero, we have to skip it as well
687 if(answer.num_digits == 0) {
688 // skip zeros
689 while ((p != pend) && (*p == '0')) {
690 ++p;
691 }
692 }
693 // We expect that this loop will often take the bulk of the running time
694 // because when a value has lots of digits, these digits often
695 while ((p + 8 <= pend) && (answer.num_digits + 8 < max_digits)) {
696 uint64_t val = read_u64(p);
697 if(! is_made_of_eight_digits_fast(val)) { break; }
698 // We have eight digits, process them in one go!
699 val -= 0x3030303030303030;
700 write_u64(answer.digits + answer.num_digits, val);
701 answer.num_digits += 8;
702 p += 8;
703 }
704 while ((p != pend) && is_integer(*p)) {
705 if (answer.num_digits < max_digits) {
706 answer.digits[answer.num_digits] = uint8_t(*p - '0');
707 }
708 answer.num_digits++;
709 ++p;
710 }
711 answer.decimal_point = int32_t(first_after_period - p);
712 }
713 // We want num_digits to be the number of significant digits, excluding
714 // leading *and* trailing zeros! Otherwise the truncated flag later is
715 // going to be misleading.
716 if(answer.num_digits > 0) {
717 // We potentially need the answer.num_digits > 0 guard because we
718 // prune leading zeros. So with answer.num_digits > 0, we know that
719 // we have at least one non-zero digit.
720 const char *preverse = p - 1;
721 int32_t trailing_zeros = 0;
722 while ((*preverse == '0') || (*preverse == decimal_point)) {
723 if(*preverse == '0') { trailing_zeros++; };
724 --preverse;
725 }
726 answer.decimal_point += int32_t(answer.num_digits);
727 answer.num_digits -= uint32_t(trailing_zeros);
728 }
729 if(answer.num_digits > max_digits) {
730 answer.truncated = true;
731 answer.num_digits = max_digits;
732 }
733 if ((p != pend) && (('e' == *p) || ('E' == *p))) {
734 ++p;
735 bool neg_exp = false;
736 if ((p != pend) && ('-' == *p)) {
737 neg_exp = true;
738 ++p;
739 } else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
740 ++p;
741 }
742 int32_t exp_number = 0; // exponential part
743 while ((p != pend) && is_integer(*p)) {
744 uint8_t digit = uint8_t(*p - '0');
745 if (exp_number < 0x10000) {
746 exp_number = 10 * exp_number + digit;
747 }
748 ++p;
749 }
750 answer.decimal_point += (neg_exp ? -exp_number : exp_number);
751 }
752 // In very rare cases, we may have fewer than 19 digits, we want to be able to reliably
753 // assume that all digits up to max_digit_without_overflow have been initialized.
754 for(uint32_t i = answer.num_digits; i < max_digit_without_overflow; i++) { answer.digits[i] = 0; }
755
756 return answer;
757}
EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf &a)
Definition Complex.h:137
constexpr uint32_t max_digit_without_overflow
Definition fast_float.h:195
constexpr uint32_t max_digits
Definition fast_float.h:194
fastfloat_really_inline void write_u64(uint8_t *chars, uint64_t val)
Definition fast_float.h:476
fastfloat_really_inline bool is_integer(char c) noexcept
Definition fast_float.h:453
Definition fast_float.h:289
bool truncated
Definition fast_float.h:293
uint8_t digits[max_digits]
Definition fast_float.h:294
int32_t decimal_point
Definition fast_float.h:291
bool negative
Definition fast_float.h:292
uint32_t num_digits
Definition fast_float.h:290
char decimal_point
Definition fast_float.h:65

References fast_float::decimal::decimal_point, fast_float::decimal::digits, is_integer(), is_made_of_eight_digits_fast(), fast_float::decimal::negative, fast_float::decimal::num_digits, read_u64(), fast_float::decimal::truncated, and write_u64().

Referenced by parse_long_mantissa().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_eight_digits_unrolled() [1/2]

fastfloat_really_inline uint32_t fast_float::parse_eight_digits_unrolled ( const char *  chars)
noexcept
495 {
497}
fastfloat_really_inline uint32_t parse_eight_digits_unrolled(uint64_t val)
Definition fast_float.h:485

References parse_eight_digits_unrolled(), and read_u64().

+ Here is the call graph for this function:

◆ parse_eight_digits_unrolled() [2/2]

fastfloat_really_inline uint32_t fast_float::parse_eight_digits_unrolled ( uint64_t  val)
485 {
486 const uint64_t mask = 0x000000FF000000FF;
487 const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
488 const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
489 val -= 0x3030303030303030;
490 val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
491 val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
492 return uint32_t(val);
493}

Referenced by parse_eight_digits_unrolled(), and parse_number_string().

+ Here is the caller graph for this function:

◆ parse_long_mantissa()

template<typename binary >
adjusted_mantissa fast_float::parse_long_mantissa ( const char *  first,
const char *  last,
parse_options  options 
)
2310 {
2311 decimal d = parse_decimal(first, last, options);
2312 return compute_float<binary>(d);
2313}
fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend, parse_options options) noexcept
Definition fast_float.h:661

References parse_decimal().

+ Here is the call graph for this function:

◆ parse_number_string()

fastfloat_really_inline parsed_number_string fast_float::parse_number_string ( const char *  p,
const char *  pend,
parse_options  options 
)
noexcept
522 {
523 const chars_format fmt = options.format;
524 const char decimal_point = options.decimal_point;
525
527 answer.valid = false;
528 answer.too_many_digits = false;
529 answer.negative = (*p == '-');
530 if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
531 ++p;
532 if (p == pend) {
533 return answer;
534 }
535 if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot
536 return answer;
537 }
538 }
539 const char *const start_digits = p;
540
541 uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
542
543 while ((p != pend) && is_integer(*p)) {
544 // a multiplication by 10 is cheaper than an arbitrary integer
545 // multiplication
546 i = 10 * i +
547 uint64_t(*p - '0'); // might overflow, we will handle the overflow later
548 ++p;
549 }
550 const char *const end_of_integer_part = p;
551 int64_t digit_count = int64_t(end_of_integer_part - start_digits);
552 int64_t exponent = 0;
553 if ((p != pend) && (*p == decimal_point)) {
554 ++p;
555 // Fast approach only tested under little endian systems
556 if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) {
557 i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
558 p += 8;
559 if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) {
560 i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
561 p += 8;
562 }
563 }
564 while ((p != pend) && is_integer(*p)) {
565 uint8_t digit = uint8_t(*p - '0');
566 ++p;
567 i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
568 }
569 exponent = end_of_integer_part + 1 - p;
570 digit_count -= exponent;
571 }
572 // we must have encountered at least one integer!
573 if (digit_count == 0) {
574 return answer;
575 }
576 int64_t exp_number = 0; // explicit exponential part
577 if ((fmt & chars_format::scientific) && (p != pend) && (('e' == *p) || ('E' == *p))) {
578 const char * location_of_e = p;
579 ++p;
580 bool neg_exp = false;
581 if ((p != pend) && ('-' == *p)) {
582 neg_exp = true;
583 ++p;
584 } else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
585 ++p;
586 }
587 if ((p == pend) || !is_integer(*p)) {
588 if(!(fmt & chars_format::fixed)) {
589 // We are in error.
590 return answer;
591 }
592 // Otherwise, we will be ignoring the 'e'.
593 p = location_of_e;
594 } else {
595 while ((p != pend) && is_integer(*p)) {
596 uint8_t digit = uint8_t(*p - '0');
597 if (exp_number < 0x10000) {
598 exp_number = 10 * exp_number + digit;
599 }
600 ++p;
601 }
602 if(neg_exp) { exp_number = - exp_number; }
603 exponent += exp_number;
604 }
605 } else {
606 // If it scientific and not fixed, we have to bail out.
607 if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
608 }
609 answer.lastmatch = p;
610 answer.valid = true;
611
612 // If we frequently had to deal with long strings of digits,
613 // we could extend our code by using a 128-bit integer instead
614 // of a 64-bit integer. However, this is uncommon.
615 //
616 // We can deal with up to 19 digits.
617 if (digit_count > 19) { // this is uncommon
618 // It is possible that the integer had an overflow.
619 // We have to handle the case where we have 0.0000somenumber.
620 // We need to be mindful of the case where we only have zeroes...
621 // E.g., 0.000000000...000.
622 const char *start = start_digits;
623 while ((start != pend) && (*start == '0' || *start == decimal_point)) {
624 if(*start == '0') { digit_count --; }
625 start++;
626 }
627 if (digit_count > 19) {
628 answer.too_many_digits = true;
629 // Let us start again, this time, avoiding overflows.
630 i = 0;
631 p = start_digits;
632 const uint64_t minimal_nineteen_digit_integer{1000000000000000000};
633 while((i < minimal_nineteen_digit_integer) && (p != pend) && is_integer(*p)) {
634 i = i * 10 + uint64_t(*p - '0');
635 ++p;
636 }
637 if (i >= minimal_nineteen_digit_integer) { // We have a big integers
638 exponent = end_of_integer_part - p + exp_number;
639 } else { // We have a value with a fractional component.
640 p++; // skip the dot
641 const char *first_after_period = p;
642 while((i < minimal_nineteen_digit_integer) && (p != pend) && is_integer(*p)) {
643 i = i * 10 + uint64_t(*p - '0');
644 ++p;
645 }
646 exponent = first_after_period - p + exp_number;
647 }
648 // We have now corrected both exponent and i, to a truncated value
649 }
650 }
651 answer.exponent = exponent;
652 answer.mantissa = i;
653 return answer;
654}
uint64_t mantissa
Definition fast_float.h:511
chars_format
Definition fast_float.h:44
const char * lastmatch
Definition fast_float.h:512
bool valid
Definition fast_float.h:514
bool too_many_digits
Definition fast_float.h:515
bool negative
Definition fast_float.h:513
int64_t exponent
Definition fast_float.h:510
Definition fast_float.h:509
chars_format format
Definition fast_float.h:63
__int64 int64_t
Definition unistd.h:76

References fast_float::parsed_number_string::exponent, fixed, is_integer(), is_made_of_eight_digits_fast(), fast_float::parsed_number_string::lastmatch, fast_float::parsed_number_string::mantissa, fast_float::parsed_number_string::negative, parse_eight_digits_unrolled(), scientific, fast_float::parsed_number_string::too_many_digits, and fast_float::parsed_number_string::valid.

Referenced by from_chars_advanced().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ read_u64()

fastfloat_really_inline uint64_t fast_float::read_u64 ( const char *  chars)
466 {
467 uint64_t val;
468 ::memcpy(&val, chars, sizeof(uint64_t));
469#if FASTFLOAT_IS_BIG_ENDIAN == 1
470 // Need to read as-if the number was in little-endian order.
471 val = byteswap(val);
472#endif
473 return val;
474}
fastfloat_really_inline uint64_t byteswap(uint64_t val)
Definition fast_float.h:455

References byteswap().

Referenced by is_made_of_eight_digits_fast(), parse_decimal(), and parse_eight_digits_unrolled().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ write_u64()

fastfloat_really_inline void fast_float::write_u64 ( uint8_t chars,
uint64_t  val 
)
476 {
477#if FASTFLOAT_IS_BIG_ENDIAN == 1
478 // Need to read as-if the number was in little-endian order.
479 val = byteswap(val);
480#endif
481 ::memcpy(chars, &val, sizeof(uint64_t));
482}

References byteswap().

Referenced by parse_decimal().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ powers_of_ten_double

constexpr double fast_float::powers_of_ten_double[]
staticconstexpr
Initial value:
= {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}

Referenced by fast_float::binary_format< T >::exact_power_of_ten().

◆ powers_of_ten_float

constexpr float fast_float::powers_of_ten_float[]
staticconstexpr
Initial value:
= {1e0, 1e1, 1e2, 1e3, 1e4, 1e5,
1e6, 1e7, 1e8, 1e9, 1e10}

Referenced by fast_float::binary_format< T >::exact_power_of_ten().