Audacity 3.2.0
Namespaces | Classes | Typedefs | Enumerations | Functions | Variables
fast_float Namespace Reference

Namespaces

namespace  detail
 

Classes

struct  adjusted_mantissa
 
struct  bigint
 
struct  binary_format
 
struct  from_chars_result
 
struct  parse_options
 
struct  parsed_number_string
 
struct  powers_template
 
struct  span
 
struct  stackvec
 
struct  value128
 

Typedefs

typedef span< const char > byte_span
 
using powers = powers_template<>
 
typedef uint32_t limb
 
typedef span< limblimb_span
 

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)
 
template<typename T >
fastfloat_really_inline void to_float (bool negative, adjusted_mantissa am, T &value)
 
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
 
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_error_scaled (int64_t q, uint64_t w, int lz) noexcept
 
template<typename binary >
fastfloat_really_inline adjusted_mantissa compute_error (int64_t q, uint64_t w) noexcept
 
template<typename binary >
fastfloat_really_inline adjusted_mantissa compute_float (int64_t q, uint64_t w) noexcept
 
fastfloat_really_inline uint64_t empty_hi64 (bool &truncated) noexcept
 
fastfloat_really_inline uint64_t uint64_hi64 (uint64_t r0, bool &truncated) noexcept
 
fastfloat_really_inline uint64_t uint64_hi64 (uint64_t r0, uint64_t r1, bool &truncated) noexcept
 
fastfloat_really_inline uint64_t uint32_hi64 (uint32_t r0, bool &truncated) noexcept
 
fastfloat_really_inline uint64_t uint32_hi64 (uint32_t r0, uint32_t r1, bool &truncated) noexcept
 
fastfloat_really_inline uint64_t uint32_hi64 (uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept
 
fastfloat_really_inline limb scalar_add (limb x, limb y, bool &overflow) noexcept
 
fastfloat_really_inline limb scalar_mul (limb x, limb y, limb &carry) noexcept
 
template<uint16_t size>
bool small_add_from (stackvec< size > &vec, limb y, size_t start) noexcept
 
template<uint16_t size>
fastfloat_really_inline bool small_add (stackvec< size > &vec, limb y) noexcept
 
template<uint16_t size>
bool small_mul (stackvec< size > &vec, limb y) noexcept
 
template<uint16_t size>
bool large_add_from (stackvec< size > &x, limb_span y, size_t start) noexcept
 
template<uint16_t size>
fastfloat_really_inline bool large_add_from (stackvec< size > &x, limb_span y) noexcept
 
template<uint16_t size>
bool long_mul (stackvec< size > &x, limb_span y) noexcept
 
template<uint16_t size>
bool large_mul (stackvec< size > &x, limb_span y) noexcept
 
fastfloat_really_inline int32_t scientific_exponent (parsed_number_string &num) noexcept
 
template<typename T >
fastfloat_really_inline adjusted_mantissa to_extended (T value) noexcept
 
template<typename T >
fastfloat_really_inline adjusted_mantissa to_extended_halfway (T value) noexcept
 
template<typename T , typename callback >
fastfloat_really_inline void round (adjusted_mantissa &am, callback cb) noexcept
 
template<typename callback >
fastfloat_really_inline void round_nearest_tie_even (adjusted_mantissa &am, int32_t shift, callback cb) noexcept
 
fastfloat_really_inline void round_down (adjusted_mantissa &am, int32_t shift) noexcept
 
fastfloat_really_inline void skip_zeros (const char *&first, const char *last) noexcept
 
fastfloat_really_inline bool is_truncated (const char *first, const char *last) noexcept
 
fastfloat_really_inline bool is_truncated (byte_span s) noexcept
 
fastfloat_really_inline void parse_eight_digits (const char *&p, limb &value, size_t &counter, size_t &count) noexcept
 
fastfloat_really_inline void parse_one_digit (const char *&p, limb &value, size_t &counter, size_t &count) noexcept
 
fastfloat_really_inline void add_native (bigint &big, limb power, limb value) noexcept
 
fastfloat_really_inline void round_up_bigint (bigint &big, size_t &count) noexcept
 
void parse_mantissa (bigint &result, parsed_number_string &num, size_t max_digits, size_t &digits) noexcept
 
template<typename T >
adjusted_mantissa positive_digit_comp (bigint &bigmant, int32_t exponent) noexcept
 
template<typename T >
adjusted_mantissa negative_digit_comp (bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept
 
template<typename T >
adjusted_mantissa digit_comp (parsed_number_string &num, adjusted_mantissa am) noexcept
 

Variables

static constexpr int32_t invalid_am_bias = -0x8000
 
static constexpr double powers_of_ten_double []
 
static constexpr float powers_of_ten_float []
 
constexpr size_t limb_bits = 32
 
constexpr size_t bigint_bits = 4000
 
constexpr size_t bigint_limbs = bigint_bits / limb_bits
 
static constexpr uint64_t powers_of_ten_uint64 []
 

Typedef Documentation

◆ byte_span

typedef span<const char> fast_float::byte_span

Definition at line 535 of file fast_float.h.

◆ limb

typedef uint32_t fast_float::limb

Definition at line 1616 of file fast_float.h.

◆ limb_span

Definition at line 1620 of file fast_float.h.

◆ powers

Definition at line 1392 of file fast_float.h.

Enumeration Type Documentation

◆ chars_format

Enumerator
scientific 
fixed 
hex 
general 

Definition at line 44 of file fast_float.h.

44 {
45 scientific = 1<<0,
46 fixed = 1<<2,
47 hex = 1<<3,
49};

Function Documentation

◆ add_native()

fastfloat_really_inline void fast_float::add_native ( bigint big,
limb  power,
limb  value 
)
noexcept

Definition at line 2639 of file fast_float.h.

2639 {
2640 big.mul(power);
2641 big.add(value);
2642}
constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept
Definition: fast_float.h:1454
bool add(limb y) noexcept
Definition: fast_float.h:2118
bool mul(limb y) noexcept
Definition: fast_float.h:2114

References fast_float::detail::power().

Referenced by parse_mantissa(), and round_up_bigint().

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

◆ byteswap()

fastfloat_really_inline uint64_t fast_float::byteswap ( uint64_t  val)

Definition at line 481 of file fast_float.h.

481 {
482 return (val & 0xFF00000000000000) >> 56
483 | (val & 0x00FF000000000000) >> 40
484 | (val & 0x0000FF0000000000) >> 24
485 | (val & 0x000000FF00000000) >> 8
486 | (val & 0x00000000FF000000) << 8
487 | (val & 0x0000000000FF0000) << 24
488 | (val & 0x000000000000FF00) << 40
489 | (val & 0x00000000000000FF) << 56;
490}

Referenced by read_u64(), and write_u64().

Here is the caller graph for this function:

◆ compute_error()

template<typename binary >
fastfloat_really_inline adjusted_mantissa fast_float::compute_error ( int64_t  q,
uint64_t  w 
)
noexcept

Definition at line 1476 of file fast_float.h.

1476 {
1477 int lz = leading_zeroes(w);
1478 w <<= lz;
1479 value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
1480 return compute_error_scaled<binary>(q, product.high, lz);
1481}
fastfloat_really_inline int leading_zeroes(uint64_t input_num)
Definition: fast_float.h:232

References fast_float::value128::high, and leading_zeroes().

Here is the call graph for this function:

◆ compute_error_scaled()

template<typename binary >
fastfloat_really_inline adjusted_mantissa fast_float::compute_error_scaled ( int64_t  q,
uint64_t  w,
int  lz 
)
noexcept

Definition at line 1463 of file fast_float.h.

1463 {
1464 int hilz = int(w >> 63) ^ 1;
1465 adjusted_mantissa answer;
1466 answer.mantissa = w << hilz;
1467 int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
1468 answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + invalid_am_bias);
1469 return answer;
1470}
static constexpr int32_t invalid_am_bias
Definition: fast_float.h:314

References invalid_am_bias, fast_float::adjusted_mantissa::mantissa, fast_float::detail::power(), and fast_float::adjusted_mantissa::power2.

Here is the call graph for this function:

◆ compute_float()

template<typename binary >
fastfloat_really_inline adjusted_mantissa fast_float::compute_float ( int64_t  q,
uint64_t  w 
)
noexcept

Definition at line 1490 of file fast_float.h.

1490 {
1491 adjusted_mantissa answer;
1492 if ((w == 0) || (q < binary::smallest_power_of_ten())) {
1493 answer.power2 = 0;
1494 answer.mantissa = 0;
1495 // result should be zero
1496 return answer;
1497 }
1498 if (q > binary::largest_power_of_ten()) {
1499 // we want to get infinity:
1500 answer.power2 = binary::infinite_power();
1501 answer.mantissa = 0;
1502 return answer;
1503 }
1504 // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five].
1505
1506 // We want the most significant bit of i to be 1. Shift if needed.
1507 int lz = leading_zeroes(w);
1508 w <<= lz;
1509
1510 // The required precision is binary::mantissa_explicit_bits() + 3 because
1511 // 1. We need the implicit bit
1512 // 2. We need an extra bit for rounding purposes
1513 // 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
1514
1515 value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
1516 if(product.low == 0xFFFFFFFFFFFFFFFF) { // could guard it further
1517 // In some very rare cases, this could happen, in which case we might need a more accurate
1518 // computation that what we can provide cheaply. This is very, very unlikely.
1519 //
1520 const bool inside_safe_exponent = (q >= -27) && (q <= 55); // always good because 5**q <2**128 when q>=0,
1521 // and otherwise, for q<0, we have 5**-q<2**64 and the 128-bit reciprocal allows for exact computation.
1522 if(!inside_safe_exponent) {
1523 return compute_error_scaled<binary>(q, product.high, lz);
1524 }
1525 }
1526 // The "compute_product_approximation" function can be slightly slower than a branchless approach:
1527 // value128 product = compute_product(q, w);
1528 // but in practice, we can win big with the compute_product_approximation if its additional branch
1529 // is easily predicted. Which is best is data specific.
1530 int upperbit = int(product.high >> 63);
1531
1532 answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
1533
1534 answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - binary::minimum_exponent());
1535 if (answer.power2 <= 0) { // we have a subnormal?
1536 // Here have that answer.power2 <= 0 so -answer.power2 >= 0
1537 if(-answer.power2 + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure.
1538 answer.power2 = 0;
1539 answer.mantissa = 0;
1540 // result should be zero
1541 return answer;
1542 }
1543 // next line is safe because -answer.power2 + 1 < 64
1544 answer.mantissa >>= -answer.power2 + 1;
1545 // Thankfully, we can't have both "round-to-even" and subnormals because
1546 // "round-to-even" only occurs for powers close to 0.
1547 answer.mantissa += (answer.mantissa & 1); // round up
1548 answer.mantissa >>= 1;
1549 // There is a weird scenario where we don't have a subnormal but just.
1550 // Suppose we start with 2.2250738585072013e-308, we end up
1551 // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal
1552 // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round
1553 // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
1554 // subnormal, but we can only know this after rounding.
1555 // So we only declare a subnormal if we are smaller than the threshold.
1556 answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
1557 return answer;
1558 }
1559
1560 // usually, we round *up*, but if we fall right in between and and we have an
1561 // even basis, we need to round down
1562 // We are only concerned with the cases where 5**q fits in single 64-bit word.
1563 if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
1564 ((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
1565 // To be in-between two floats we need that in doing
1566 // answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
1567 // ... we dropped out only zeroes. But if this happened, then we can go back!!!
1568 if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
1569 answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
1570 }
1571 }
1572
1573 answer.mantissa += (answer.mantissa & 1); // round up
1574 answer.mantissa >>= 1;
1575 if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
1576 answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
1577 answer.power2++; // undo previous addition
1578 }
1579
1580 answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
1581 if (answer.power2 >= binary::infinite_power()) { // infinity
1582 answer.power2 = binary::infinite_power();
1583 answer.mantissa = 0;
1584 }
1585 return answer;
1586}

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 
)

Definition at line 1417 of file fast_float.h.

1417 {
1418 const int index = 2 * int(q - powers::smallest_power_of_five);
1419 // For small values of q, e.g., q in [0,27], the answer is always exact because
1420 // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
1421 // gives the exact answer.
1422 value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
1423 static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
1424 constexpr uint64_t precision_mask = (bit_precision < 64) ?
1425 (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
1426 : uint64_t(0xFFFFFFFFFFFFFFFF);
1427 if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
1428 // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
1429 value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
1430 firstproduct.low += secondproduct.high;
1431 if(secondproduct.high > firstproduct.low) {
1432 firstproduct.high++;
1433 }
1434 }
1435 return firstproduct;
1436}
fastfloat_really_inline value128 full_multiplication(uint64_t a, uint64_t b)
Definition: fast_float.h:282

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:

◆ digit_comp()

template<typename T >
adjusted_mantissa fast_float::digit_comp ( parsed_number_string num,
adjusted_mantissa  am 
)
inlinenoexcept

Definition at line 2815 of file fast_float.h.

2815 {
2816 // remove the invalid exponent bias
2817 am.power2 -= invalid_am_bias;
2818
2819 int32_t sci_exp = scientific_exponent(num);
2820 size_t max_digits = binary_format<T>::max_digits();
2821 size_t digits = 0;
2822 bigint bigmant;
2823 parse_mantissa(bigmant, num, max_digits, digits);
2824 // can't underflow, since digits is at most max_digits.
2825 int32_t exponent = sci_exp + 1 - int32_t(digits);
2826 if (exponent >= 0) {
2827 return positive_digit_comp<T>(bigmant, exponent);
2828 } else {
2829 return negative_digit_comp<T>(bigmant, am, exponent);
2830 }
2831}
fastfloat_really_inline int32_t scientific_exponent(parsed_number_string &num) noexcept
Definition: fast_float.h:2438
void parse_mantissa(bigint &result, parsed_number_string &num, size_t max_digits, size_t &digits) noexcept
Definition: fast_float.h:2652

References invalid_am_bias, fast_float::binary_format< T >::max_digits(), parse_mantissa(), fast_float::adjusted_mantissa::power2, and scientific_exponent().

Here is the call graph for this function:

◆ empty_hi64()

fastfloat_really_inline uint64_t fast_float::empty_hi64 ( bool &  truncated)
noexcept

Definition at line 1749 of file fast_float.h.

1749 {
1750 truncated = false;
1751 return 0;
1752}

Referenced by fast_float::bigint::hi64().

Here is the caller graph for this function:

◆ fastfloat_strncasecmp()

bool fast_float::fastfloat_strncasecmp ( const char *  input1,
const char *  input2,
size_t  length 
)
inline

Definition at line 193 of file fast_float.h.

194 {
195 char running_diff{0};
196 for (size_t i = 0; i < length; i++) {
197 running_diff |= (input1[i] ^ input2[i]);
198 }
199 return (running_diff == 0) || (running_diff == 32);
200}

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.

Definition at line 2900 of file fast_float.h.

2901 {
2902 return from_chars_advanced(first, last, value, parse_options{fmt});
2903}
from_chars_result from_chars_advanced(const char *first, const char *last, T &value, parse_options options) noexcept
Definition: fast_float.h:2906

References from_chars_advanced().

Referenced by FromChars().

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.

Definition at line 2906 of file fast_float.h.

2907 {
2908
2909 static_assert (std::is_same<T, double>::value || std::is_same<T, float>::value, "only float and double are supported");
2910
2911
2912 from_chars_result answer;
2913 if (first == last) {
2914 answer.ec = std::errc::invalid_argument;
2915 answer.ptr = first;
2916 return answer;
2917 }
2918 parsed_number_string pns = parse_number_string(first, last, options);
2919 if (!pns.valid) {
2920 return detail::parse_infnan(first, last, value);
2921 }
2922 answer.ec = std::errc(); // be optimistic
2923 answer.ptr = pns.lastmatch;
2924 // Next is Clinger's fast path.
2925 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) {
2926 value = T(pns.mantissa);
2927 if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
2928 else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
2929 if (pns.negative) { value = -value; }
2930 return answer;
2931 }
2932 adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
2933 if(pns.too_many_digits && am.power2 >= 0) {
2934 if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
2935 am = compute_error<binary_format<T>>(pns.exponent, pns.mantissa);
2936 }
2937 }
2938 // If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0),
2939 // then we need to go the long way around again. This is very uncommon.
2940 if(am.power2 < 0) { am = digit_comp<T>(pns, am); }
2941 to_float(pns.negative, am, value);
2942 return answer;
2943}
from_chars_result parse_infnan(const char *first, const char *last, T &value) noexcept
Definition: fast_float.h:2857
fastfloat_really_inline void to_float(bool negative, adjusted_mantissa am, T &value)
Definition: fast_float.h:444
fastfloat_really_inline parsed_number_string parse_number_string(const char *p, const char *pend, parse_options options) noexcept
Definition: fast_float.h:552
fastfloat_really_inline adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept
Definition: fast_float.h:1490

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 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 
)

Definition at line 282 of file fast_float.h.

283 {
284 value128 answer;
285#ifdef _M_ARM64
286 // ARM64 has native support for 64-bit multiplications, no need to emulate
287 answer.high = __umulh(a, b);
288 answer.low = a * b;
289#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
290 answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
291#elif defined(FASTFLOAT_64BIT)
292 __uint128_t r = ((__uint128_t)a) * b;
293 answer.low = uint64_t(r);
294 answer.high = uint64_t(r >> 64);
295#else
296 #error Not implemented
297#endif
298 return answer;
299}

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

Referenced by compute_product_approximation(), and scalar_mul().

Here is the caller graph for this function:

◆ is_integer()

fastfloat_really_inline bool fast_float::is_integer ( char  c)
noexcept

Definition at line 479 of file fast_float.h.

479{ return c >= '0' && c <= '9'; }

Referenced by 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

Definition at line 531 of file fast_float.h.

531 {
533}
fastfloat_really_inline bool is_made_of_eight_digits_fast(const char *chars) noexcept
Definition: fast_float.h:531
fastfloat_really_inline uint64_t read_u64(const char *chars)
Definition: fast_float.h:492

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

Definition at line 526 of file fast_float.h.

526 {
527 return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) &
528 0x8080808080808080));
529}

Referenced by is_made_of_eight_digits_fast(), and parse_number_string().

Here is the caller graph for this function:

◆ is_truncated() [1/2]

fastfloat_really_inline bool fast_float::is_truncated ( byte_span  s)
noexcept

Definition at line 2618 of file fast_float.h.

2618 {
2619 return is_truncated(s.ptr, s.ptr + s.len());
2620}
fastfloat_really_inline bool is_truncated(byte_span s) noexcept
Definition: fast_float.h:2618
const T * ptr
Definition: fast_float.h:209
constexpr size_t len() const noexcept
Definition: fast_float.h:214

References is_truncated().

Here is the call graph for this function:

◆ is_truncated() [2/2]

fastfloat_really_inline bool fast_float::is_truncated ( const char *  first,
const char *  last 
)
noexcept

Definition at line 2599 of file fast_float.h.

2599 {
2600 // do 8-bit optimizations, can just compare to 8 literal 0s.
2601 uint64_t val;
2602 while (std::distance(first, last) >= 8) {
2603 ::memcpy(&val, first, sizeof(uint64_t));
2604 if (val != 0x3030303030303030) {
2605 return true;
2606 }
2607 first += 8;
2608 }
2609 while (first != last) {
2610 if (*first != '0') {
2611 return true;
2612 }
2613 first++;
2614 }
2615 return false;
2616}

Referenced by is_truncated(), and parse_mantissa().

Here is the caller graph for this function:

◆ large_add_from() [1/2]

template<uint16_t size>
fastfloat_really_inline bool fast_float::large_add_from ( stackvec< size > &  x,
limb_span  y 
)
noexcept

Definition at line 1912 of file fast_float.h.

1912 {
1913 return large_add_from(x, y, 0);
1914}
fastfloat_really_inline bool large_add_from(stackvec< size > &x, limb_span y) noexcept
Definition: fast_float.h:1912

References large_add_from().

Here is the call graph for this function:

◆ large_add_from() [2/2]

template<uint16_t size>
bool fast_float::large_add_from ( stackvec< size > &  x,
limb_span  y,
size_t  start 
)
noexcept

Definition at line 1882 of file fast_float.h.

1882 {
1883 // the effective x buffer is from `xstart..x.len()`, so exit early
1884 // if we can't get that current range.
1885 if (x.len() < start || y.len() > x.len() - start) {
1886 FASTFLOAT_TRY(x.try_resize(y.len() + start, 0));
1887 }
1888
1889 bool carry = false;
1890 for (size_t index = 0; index < y.len(); index++) {
1891 limb xi = x[index + start];
1892 limb yi = y[index];
1893 bool c1 = false;
1894 bool c2 = false;
1895 xi = scalar_add(xi, yi, c1);
1896 if (carry) {
1897 xi = scalar_add(xi, 1, c2);
1898 }
1899 x[index + start] = xi;
1900 carry = c1 | c2;
1901 }
1902
1903 // handle overflow
1904 if (carry) {
1905 FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start));
1906 }
1907 return true;
1908}
#define FASTFLOAT_TRY(x)
Definition: fast_float.h:188
fastfloat_really_inline limb scalar_add(limb x, limb y, bool &overflow) noexcept
Definition: fast_float.h:1799
bool small_add_from(stackvec< size > &vec, limb y, size_t start) noexcept
Definition: fast_float.h:1845
uint32_t limb
Definition: fast_float.h:1616
constexpr size_t len() const noexcept
Definition: fast_float.h:1667
bool try_resize(size_t new_len, limb value) noexcept
Definition: fast_float.h:1720

References FASTFLOAT_TRY, scalar_add(), and small_add_from().

Referenced by large_add_from(), and long_mul().

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

◆ large_mul()

template<uint16_t size>
bool fast_float::large_mul ( stackvec< size > &  x,
limb_span  y 
)
noexcept

Definition at line 1946 of file fast_float.h.

1946 {
1947 if (y.len() == 1) {
1948 FASTFLOAT_TRY(small_mul(x, y[0]));
1949 } else {
1950 FASTFLOAT_TRY(long_mul(x, y));
1951 }
1952 return true;
1953}
bool long_mul(stackvec< size > &x, limb_span y) noexcept
Definition: fast_float.h:1918
bool small_mul(stackvec< size > &vec, limb y) noexcept
Definition: fast_float.h:1868

References FASTFLOAT_TRY, long_mul(), and small_mul().

Referenced by fast_float::bigint::pow5().

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

◆ leading_zeroes()

fastfloat_really_inline int fast_float::leading_zeroes ( uint64_t  input_num)

Definition at line 232 of file fast_float.h.

232 {
233 assert(input_num > 0);
234#ifdef FASTFLOAT_VISUAL_STUDIO
235 #if defined(_M_X64) || defined(_M_ARM64)
236 unsigned long leading_zero = 0;
237 // Search the mask data from most significant bit (MSB)
238 // to least significant bit (LSB) for a set bit (1).
239 _BitScanReverse64(&leading_zero, input_num);
240 return (int)(63 - leading_zero);
241 #else
242 int last_bit = 0;
243 if(input_num & uint64_t(0xffffffff00000000)) input_num >>= 32, last_bit |= 32;
244 if(input_num & uint64_t( 0xffff0000)) input_num >>= 16, last_bit |= 16;
245 if(input_num & uint64_t( 0xff00)) input_num >>= 8, last_bit |= 8;
246 if(input_num & uint64_t( 0xf0)) input_num >>= 4, last_bit |= 4;
247 if(input_num & uint64_t( 0xc)) input_num >>= 2, last_bit |= 2;
248 if(input_num & uint64_t( 0x2)) input_num >>= 1, last_bit |= 1;
249 return 63 - last_bit;
250 #endif
251#else
252 return __builtin_clzll(input_num);
253#endif
254}

Referenced by compute_error(), compute_float(), fast_float::bigint::ctlz(), and uint64_hi64().

Here is the caller graph for this function:

◆ long_mul()

template<uint16_t size>
bool fast_float::long_mul ( stackvec< size > &  x,
limb_span  y 
)
noexcept

Definition at line 1918 of file fast_float.h.

1918 {
1919 limb_span xs = limb_span(x.data, x.len());
1920 stackvec<size> z(xs);
1921 limb_span zs = limb_span(z.data, z.len());
1922
1923 if (y.len() != 0) {
1924 limb y0 = y[0];
1925 FASTFLOAT_TRY(small_mul(x, y0));
1926 for (size_t index = 1; index < y.len(); index++) {
1927 limb yi = y[index];
1928 stackvec<size> zi;
1929 if (yi != 0) {
1930 // re-use the same buffer throughout
1931 zi.set_len(0);
1932 FASTFLOAT_TRY(zi.try_extend(zs));
1933 FASTFLOAT_TRY(small_mul(zi, yi));
1934 limb_span zis = limb_span(zi.data, zi.len());
1935 FASTFLOAT_TRY(large_add_from(x, zis, index));
1936 }
1937 }
1938 }
1939
1940 x.normalize();
1941 return true;
1942}
span< limb > limb_span
Definition: fast_float.h:1620
void set_len(size_t len) noexcept
Definition: fast_float.h:1664
bool try_extend(limb_span s) noexcept
Definition: fast_float.h:1697
void normalize() noexcept
Definition: fast_float.h:1741

References fast_float::stackvec< size >::data, FASTFLOAT_TRY, large_add_from(), fast_float::stackvec< size >::len(), fast_float::stackvec< size >::set_len(), small_mul(), and fast_float::stackvec< size >::try_extend().

Referenced by large_mul().

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

◆ negative_digit_comp()

template<typename T >
adjusted_mantissa fast_float::negative_digit_comp ( bigint bigmant,
adjusted_mantissa  am,
int32_t  exponent 
)
inlinenoexcept

Definition at line 2755 of file fast_float.h.

2755 {
2756 bigint& real_digits = bigmant;
2757 int32_t real_exp = exponent;
2758
2759 // get the value of `b`, rounded down, and get a bigint representation of b+h
2760 adjusted_mantissa am_b = am;
2761 // gcc7 buf: use a lambda to remove the noexcept qualifier bug with -Wnoexcept-type.
2762 round<T>(am_b, [](adjusted_mantissa&a, int32_t shift) { round_down(a, shift); });
2763 T b;
2764 to_float(false, am_b, b);
2765 adjusted_mantissa theor = to_extended_halfway(b);
2766 bigint theor_digits(theor.mantissa);
2767 int32_t theor_exp = theor.power2;
2768
2769 // scale real digits and theor digits to be same power.
2770 int32_t pow2_exp = theor_exp - real_exp;
2771 uint32_t pow5_exp = uint32_t(-real_exp);
2772 if (pow5_exp != 0) {
2773 FASTFLOAT_ASSERT(theor_digits.pow5(pow5_exp));
2774 }
2775 if (pow2_exp > 0) {
2776 FASTFLOAT_ASSERT(theor_digits.pow2(uint32_t(pow2_exp)));
2777 } else if (pow2_exp < 0) {
2778 FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp)));
2779 }
2780
2781 // compare digits, and use it to director rounding
2782 int ord = real_digits.compare(theor_digits);
2783 adjusted_mantissa answer = am;
2784 round<T>(answer, [ord](adjusted_mantissa& a, int32_t shift) {
2785 round_nearest_tie_even(a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
2786 (void)_; // not needed, since we've done our comparison
2787 (void)__; // not needed, since we've done our comparison
2788 if (ord > 0) {
2789 return true;
2790 } else if (ord < 0) {
2791 return false;
2792 } else {
2793 return is_odd;
2794 }
2795 });
2796 });
2797
2798 return answer;
2799}
#define _(s)
Definition: Internat.h:73
#define FASTFLOAT_ASSERT(x)
Definition: fast_float.h:179
fastfloat_really_inline adjusted_mantissa to_extended_halfway(T value) noexcept
Definition: fast_float.h:2502
fastfloat_really_inline void round_down(adjusted_mantissa &am, int32_t shift) noexcept
Definition: fast_float.h:2571
fastfloat_really_inline void round_nearest_tie_even(adjusted_mantissa &am, int32_t shift, callback cb) noexcept
Definition: fast_float.h:2542
bool pow2(uint32_t exp) noexcept
Definition: fast_float.h:2123
int compare(const bigint &other) const noexcept
Definition: fast_float.h:2013

References _, fast_float::bigint::compare(), FASTFLOAT_ASSERT, fast_float::adjusted_mantissa::mantissa, fast_float::bigint::pow2(), fast_float::bigint::pow5(), fast_float::adjusted_mantissa::power2, round_down(), round_nearest_tie_even(), to_extended_halfway(), and to_float().

Here is the call graph for this function:

◆ parse_eight_digits()

fastfloat_really_inline void fast_float::parse_eight_digits ( const char *&  p,
limb value,
size_t &  counter,
size_t &  count 
)
noexcept

Definition at line 2623 of file fast_float.h.

2623 {
2624 value = value * 100000000 + parse_eight_digits_unrolled(p);
2625 p += 8;
2626 counter += 8;
2627 count += 8;
2628}
fastfloat_really_inline uint32_t parse_eight_digits_unrolled(const char *chars) noexcept
Definition: fast_float.h:521

References parse_eight_digits_unrolled().

Referenced by parse_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

Definition at line 521 of file fast_float.h.

521 {
523}

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)

Definition at line 511 of file fast_float.h.

511 {
512 const uint64_t mask = 0x000000FF000000FF;
513 const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
514 const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
515 val -= 0x3030303030303030;
516 val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
517 val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
518 return uint32_t(val);
519}

Referenced by parse_eight_digits(), parse_eight_digits_unrolled(), and parse_number_string().

Here is the caller graph for this function:

◆ parse_mantissa()

void fast_float::parse_mantissa ( bigint result,
parsed_number_string num,
size_t  max_digits,
size_t &  digits 
)
inlinenoexcept

Definition at line 2652 of file fast_float.h.

2652 {
2653 // try to minimize the number of big integer and scalar multiplication.
2654 // therefore, try to parse 8 digits at a time, and multiply by the largest
2655 // scalar value (9 or 19 digits) for each step.
2656 size_t counter = 0;
2657 digits = 0;
2658 limb value = 0;
2659#ifdef FASTFLOAT_64BIT_LIMB
2660 size_t step = 19;
2661#else
2662 size_t step = 9;
2663#endif
2664
2665 // process all integer digits.
2666 const char* p = num.integer.ptr;
2667 const char* pend = p + num.integer.len();
2668 skip_zeros(p, pend);
2669 // process all digits, in increments of step per loop
2670 while (p != pend) {
2671 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
2672 parse_eight_digits(p, value, counter, digits);
2673 }
2674 while (counter < step && p != pend && digits < max_digits) {
2675 parse_one_digit(p, value, counter, digits);
2676 }
2677 if (digits == max_digits) {
2678 // add the temporary value, then check if we've truncated any digits
2679 add_native(result, limb(powers_of_ten_uint64[counter]), value);
2680 bool truncated = is_truncated(p, pend);
2681 if (num.fraction.ptr != nullptr) {
2682 truncated |= is_truncated(num.fraction);
2683 }
2684 if (truncated) {
2685 round_up_bigint(result, digits);
2686 }
2687 return;
2688 } else {
2689 add_native(result, limb(powers_of_ten_uint64[counter]), value);
2690 counter = 0;
2691 value = 0;
2692 }
2693 }
2694
2695 // add our fraction digits, if they're available.
2696 if (num.fraction.ptr != nullptr) {
2697 p = num.fraction.ptr;
2698 pend = p + num.fraction.len();
2699 if (digits == 0) {
2700 skip_zeros(p, pend);
2701 }
2702 // process all digits, in increments of step per loop
2703 while (p != pend) {
2704 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
2705 parse_eight_digits(p, value, counter, digits);
2706 }
2707 while (counter < step && p != pend && digits < max_digits) {
2708 parse_one_digit(p, value, counter, digits);
2709 }
2710 if (digits == max_digits) {
2711 // add the temporary value, then check if we've truncated any digits
2712 add_native(result, limb(powers_of_ten_uint64[counter]), value);
2713 bool truncated = is_truncated(p, pend);
2714 if (truncated) {
2715 round_up_bigint(result, digits);
2716 }
2717 return;
2718 } else {
2719 add_native(result, limb(powers_of_ten_uint64[counter]), value);
2720 counter = 0;
2721 value = 0;
2722 }
2723 }
2724 }
2725
2726 if (counter != 0) {
2727 add_native(result, limb(powers_of_ten_uint64[counter]), value);
2728 }
2729}
fastfloat_really_inline void parse_one_digit(const char *&p, limb &value, size_t &counter, size_t &count) noexcept
Definition: fast_float.h:2631
fastfloat_really_inline void parse_eight_digits(const char *&p, limb &value, size_t &counter, size_t &count) noexcept
Definition: fast_float.h:2623
fastfloat_really_inline void skip_zeros(const char *&first, const char *last) noexcept
Definition: fast_float.h:2580
fastfloat_really_inline void round_up_bigint(bigint &big, size_t &count) noexcept
Definition: fast_float.h:2644
static constexpr uint64_t powers_of_ten_uint64[]
Definition: fast_float.h:2428
fastfloat_really_inline void add_native(bigint &big, limb power, limb value) noexcept
Definition: fast_float.h:2639

References add_native(), is_truncated(), parse_eight_digits(), parse_one_digit(), powers_of_ten_uint64, round_up_bigint(), and skip_zeros().

Referenced by digit_comp().

Here is the call graph for this function:
Here is the caller 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

Definition at line 552 of file fast_float.h.

552 {
553 const chars_format fmt = options.format;
554 const char decimal_point = options.decimal_point;
555
557 answer.valid = false;
558 answer.too_many_digits = false;
559 answer.negative = (*p == '-');
560 if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
561 ++p;
562 if (p == pend) {
563 return answer;
564 }
565 if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot
566 return answer;
567 }
568 }
569 const char *const start_digits = p;
570
571 uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
572
573 while ((std::distance(p, pend) >= 8) && is_made_of_eight_digits_fast(p)) {
574 i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
575 p += 8;
576 }
577 while ((p != pend) && is_integer(*p)) {
578 // a multiplication by 10 is cheaper than an arbitrary integer
579 // multiplication
580 i = 10 * i +
581 uint64_t(*p - '0'); // might overflow, we will handle the overflow later
582 ++p;
583 }
584 const char *const end_of_integer_part = p;
585 int64_t digit_count = int64_t(end_of_integer_part - start_digits);
586 answer.integer = byte_span(start_digits, size_t(digit_count));
587 int64_t exponent = 0;
588 if ((p != pend) && (*p == decimal_point)) {
589 ++p;
590 const char* before = p;
591 // can occur at most twice without overflowing, but let it occur more, since
592 // for integers with many digits, digit parsing is the primary bottleneck.
593 while ((std::distance(p, pend) >= 8) && is_made_of_eight_digits_fast(p)) {
594 i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
595 p += 8;
596 }
597 while ((p != pend) && is_integer(*p)) {
598 uint8_t digit = uint8_t(*p - '0');
599 ++p;
600 i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
601 }
602 exponent = before - p;
603 answer.fraction = byte_span(before, size_t(p - before));
604 digit_count -= exponent;
605 }
606 // we must have encountered at least one integer!
607 if (digit_count == 0) {
608 return answer;
609 }
610 int64_t exp_number = 0; // explicit exponential part
611 if ((fmt & chars_format::scientific) && (p != pend) && (('e' == *p) || ('E' == *p))) {
612 const char * location_of_e = p;
613 ++p;
614 bool neg_exp = false;
615 if ((p != pend) && ('-' == *p)) {
616 neg_exp = true;
617 ++p;
618 } else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
619 ++p;
620 }
621 if ((p == pend) || !is_integer(*p)) {
622 if(!(fmt & chars_format::fixed)) {
623 // We are in error.
624 return answer;
625 }
626 // Otherwise, we will be ignoring the 'e'.
627 p = location_of_e;
628 } else {
629 while ((p != pend) && is_integer(*p)) {
630 uint8_t digit = uint8_t(*p - '0');
631 if (exp_number < 0x10000000) {
632 exp_number = 10 * exp_number + digit;
633 }
634 ++p;
635 }
636 if(neg_exp) { exp_number = - exp_number; }
637 exponent += exp_number;
638 }
639 } else {
640 // If it scientific and not fixed, we have to bail out.
641 if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
642 }
643 answer.lastmatch = p;
644 answer.valid = true;
645
646 // If we frequently had to deal with long strings of digits,
647 // we could extend our code by using a 128-bit integer instead
648 // of a 64-bit integer. However, this is uncommon.
649 //
650 // We can deal with up to 19 digits.
651 if (digit_count > 19) { // this is uncommon
652 // It is possible that the integer had an overflow.
653 // We have to handle the case where we have 0.0000somenumber.
654 // We need to be mindful of the case where we only have zeroes...
655 // E.g., 0.000000000...000.
656 const char *start = start_digits;
657 while ((start != pend) && (*start == '0' || *start == decimal_point)) {
658 if(*start == '0') { digit_count --; }
659 start++;
660 }
661 if (digit_count > 19) {
662 answer.too_many_digits = true;
663 // Let us start again, this time, avoiding overflows.
664 // We don't need to check if is_integer, since we use the
665 // pre-tokenized spans from above.
666 i = 0;
667 p = answer.integer.ptr;
668 const char* int_end = p + answer.integer.len();
669 const uint64_t minimal_nineteen_digit_integer{1000000000000000000};
670 while((i < minimal_nineteen_digit_integer) && (p != int_end)) {
671 i = i * 10 + uint64_t(*p - '0');
672 ++p;
673 }
674 if (i >= minimal_nineteen_digit_integer) { // We have a big integers
675 exponent = end_of_integer_part - p + exp_number;
676 } else { // We have a value with a fractional component.
677 p = answer.fraction.ptr;
678 const char* frac_end = p + answer.fraction.len();
679 while((i < minimal_nineteen_digit_integer) && (p != frac_end)) {
680 i = i * 10 + uint64_t(*p - '0');
681 ++p;
682 }
683 exponent = answer.fraction.ptr - p + exp_number;
684 }
685 // We have now corrected both exponent and i, to a truncated value
686 }
687 }
688 answer.exponent = exponent;
689 answer.mantissa = i;
690 return answer;
691}
span< const char > byte_span
Definition: fast_float.h:535
fastfloat_really_inline bool is_integer(char c) noexcept
Definition: fast_float.h:479

References fast_float::parsed_number_string::exponent, fixed, fast_float::parsed_number_string::fraction, fast_float::parsed_number_string::integer, is_integer(), is_made_of_eight_digits_fast(), fast_float::parsed_number_string::lastmatch, fast_float::span< T >::len(), fast_float::parsed_number_string::mantissa, fast_float::parsed_number_string::negative, parse_eight_digits_unrolled(), fast_float::span< T >::ptr, 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:

◆ parse_one_digit()

fastfloat_really_inline void fast_float::parse_one_digit ( const char *&  p,
limb value,
size_t &  counter,
size_t &  count 
)
noexcept

Definition at line 2631 of file fast_float.h.

2631 {
2632 value = value * 10 + limb(*p - '0');
2633 p++;
2634 counter++;
2635 count++;
2636}

Referenced by parse_mantissa().

Here is the caller graph for this function:

◆ positive_digit_comp()

template<typename T >
adjusted_mantissa fast_float::positive_digit_comp ( bigint bigmant,
int32_t  exponent 
)
inlinenoexcept

Definition at line 2732 of file fast_float.h.

2732 {
2733 FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
2734 adjusted_mantissa answer;
2735 bool truncated;
2736 answer.mantissa = bigmant.hi64(truncated);
2738 answer.power2 = bigmant.bit_length() - 64 + bias;
2739
2740 round<T>(answer, [truncated](adjusted_mantissa& a, int32_t shift) {
2741 round_nearest_tie_even(a, shift, [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
2742 return is_above || (is_halfway && truncated) || (is_odd && is_halfway);
2743 });
2744 });
2745
2746 return answer;
2747}
uint64_t hi64(bool &truncated) const noexcept
Definition: fast_float.h:1981
bool pow10(uint32_t exp) noexcept
Definition: fast_float.h:2173
int bit_length() const noexcept
Definition: fast_float.h:2109

References FASTFLOAT_ASSERT, fast_float::adjusted_mantissa::mantissa, fast_float::binary_format< T >::mantissa_explicit_bits(), fast_float::binary_format< T >::minimum_exponent(), fast_float::adjusted_mantissa::power2, and round_nearest_tie_even().

Here is the call graph for this function:

◆ read_u64()

fastfloat_really_inline uint64_t fast_float::read_u64 ( const char *  chars)

Definition at line 492 of file fast_float.h.

492 {
493 uint64_t val;
494 ::memcpy(&val, chars, sizeof(uint64_t));
495#if FASTFLOAT_IS_BIG_ENDIAN == 1
496 // Need to read as-if the number was in little-endian order.
497 val = byteswap(val);
498#endif
499 return val;
500}
fastfloat_really_inline uint64_t byteswap(uint64_t val)
Definition: fast_float.h:481

References byteswap().

Referenced by is_made_of_eight_digits_fast(), and parse_eight_digits_unrolled().

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

◆ round()

template<typename T , typename callback >
fastfloat_really_inline void fast_float::round ( adjusted_mantissa am,
callback  cb 
)
noexcept

Definition at line 2512 of file fast_float.h.

2512 {
2513 int32_t mantissa_shift = 64 - binary_format<T>::mantissa_explicit_bits() - 1;
2514 if (-am.power2 >= mantissa_shift) {
2515 // have a denormal float
2516 int32_t shift = -am.power2 + 1;
2517 cb(am, std::min(shift, 64));
2518 // check for round-up: if rounding-nearest carried us to the hidden bit.
2519 am.power2 = (am.mantissa < (uint64_t(1) << binary_format<T>::mantissa_explicit_bits())) ? 0 : 1;
2520 return;
2521 }
2522
2523 // have a normal float, use the default shift.
2524 cb(am, mantissa_shift);
2525
2526 // check for carry
2527 if (am.mantissa >= (uint64_t(2) << binary_format<T>::mantissa_explicit_bits())) {
2528 am.mantissa = (uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
2529 am.power2++;
2530 }
2531
2532 // check for infinite: we could have carried to an infinite power
2533 am.mantissa &= ~(uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
2534 if (am.power2 >= binary_format<T>::infinite_power()) {
2535 am.power2 = binary_format<T>::infinite_power();
2536 am.mantissa = 0;
2537 }
2538}
int min(int a, int b)

References fast_float::binary_format< T >::infinite_power(), fast_float::binary_format< T >::mantissa_explicit_bits(), and min().

Referenced by EBUR128::AddBlockToHistogram(), DynamicRangeProcessorEditor::AddTextboxAndSlider(), ProjectAudioManager::DoRecord(), BrushHandle::Drag(), anonymous_namespace{AudacityMirProject.cpp}::FormatTempo(), ProjectManager::GetEstimatedRecordingMinsLeftOnDisk(), anonymous_namespace{StaffPadTimeAndPitch.cpp}::GetFftSize(), MIR::anonymous_namespace{StftFrameProvider.cpp}::GetFrameSize(), MIR::anonymous_namespace{StftFrameProvider.cpp}::GetHopSize(), MIR::anonymous_namespace{MirDsp.cpp}::GetMovingAverage(), MIR::StftFrameProvider::GetNextFrame(), MIR::anonymous_namespace{GetMeterUsingTatumQuantizationFit.cpp}::GetOnsetLag(), anonymous_namespace{ClipPitchAndSpeedButtonHandle.cpp}::GetPlaybackSpeedText(), MIR::anonymous_namespace{GetMeterUsingTatumQuantizationFit.cpp}::GetPossibleDivHierarchies(), MIR::GetProjectSyncInfo(), anonymous_namespace{WaveChannelUtilities.cpp}::GetSampleAccessArgs(), WaveDataCache::InitializeElement(), EBUR128::IntegrativeLoudness(), LibImportExport::Test::LibsndfileTagger::LibsndfileTagger(), anonymous_namespace{DynamicRangeProcessorEditor.cpp}::MapExponentially(), RegenerateLinearDBValues(), WaveChannelUtilities::SetFloatsWithinTimeRange(), BeatsFormat::SetLabelString(), WaveClip::SnapToTrackSample(), anonymous_namespace{SnapUtils.cpp}::SnapWithMultiplier(), DynamicRangeProcessorEditor::UpdateUI(), and anonymous_namespace{ParsedNumericConverterFormatter.cpp}::ParsedNumericConverterFormatter::ValueToString().

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

◆ round_down()

fastfloat_really_inline void fast_float::round_down ( adjusted_mantissa am,
int32_t  shift 
)
noexcept

Definition at line 2571 of file fast_float.h.

2571 {
2572 if (shift == 64) {
2573 am.mantissa = 0;
2574 } else {
2575 am.mantissa >>= shift;
2576 }
2577 am.power2 += shift;
2578}

Referenced by negative_digit_comp().

Here is the caller graph for this function:

◆ round_nearest_tie_even()

template<typename callback >
fastfloat_really_inline void fast_float::round_nearest_tie_even ( adjusted_mantissa am,
int32_t  shift,
callback  cb 
)
noexcept

Definition at line 2542 of file fast_float.h.

2542 {
2543 uint64_t mask;
2544 uint64_t halfway;
2545 if (shift == 64) {
2546 mask = UINT64_MAX;
2547 } else {
2548 mask = (uint64_t(1) << shift) - 1;
2549 }
2550 if (shift == 0) {
2551 halfway = 0;
2552 } else {
2553 halfway = uint64_t(1) << (shift - 1);
2554 }
2555 uint64_t truncated_bits = am.mantissa & mask;
2556 uint64_t is_above = truncated_bits > halfway;
2557 uint64_t is_halfway = truncated_bits == halfway;
2558
2559 // shift digits into position
2560 if (shift == 64) {
2561 am.mantissa = 0;
2562 } else {
2563 am.mantissa >>= shift;
2564 }
2565 am.power2 += shift;
2566
2567 bool is_odd = (am.mantissa & 1) == 1;
2568 am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above));
2569}

Referenced by negative_digit_comp(), and positive_digit_comp().

Here is the caller graph for this function:

◆ round_up_bigint()

fastfloat_really_inline void fast_float::round_up_bigint ( bigint big,
size_t &  count 
)
noexcept

Definition at line 2644 of file fast_float.h.

2644 {
2645 // need to round-up the digits, but need to avoid rounding
2646 // ....9999 to ...10000, which could cause a false halfway point.
2647 add_native(big, 10, 1);
2648 count++;
2649}

References add_native().

Referenced by parse_mantissa().

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

◆ scalar_add()

fastfloat_really_inline limb fast_float::scalar_add ( limb  x,
limb  y,
bool &  overflow 
)
noexcept

Definition at line 1799 of file fast_float.h.

1799 {
1800 limb z;
1801
1802// gcc and clang
1803#if defined(__has_builtin)
1804 #if __has_builtin(__builtin_add_overflow)
1805 overflow = __builtin_add_overflow(x, y, &z);
1806 return z;
1807 #endif
1808#endif
1809
1810 // generic, this still optimizes correctly on MSVC.
1811 z = x + y;
1812 overflow = z < x;
1813 return z;
1814}

Referenced by large_add_from(), scalar_mul(), and small_add_from().

Here is the caller graph for this function:

◆ scalar_mul()

fastfloat_really_inline limb fast_float::scalar_mul ( limb  x,
limb  y,
limb carry 
)
noexcept

Definition at line 1818 of file fast_float.h.

1818 {
1819#ifdef FASTFLOAT_64BIT_LIMB
1820 #if defined(__SIZEOF_INT128__)
1821 // GCC and clang both define it as an extension.
1822 __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry);
1823 carry = limb(z >> limb_bits);
1824 return limb(z);
1825 #else
1826 // fallback, no native 128-bit integer multiplication with carry.
1827 // on msvc, this optimizes identically, somehow.
1828 value128 z = full_multiplication(x, y);
1829 bool overflow;
1830 z.low = scalar_add(z.low, carry, overflow);
1831 z.high += uint64_t(overflow); // cannot overflow
1832 carry = z.high;
1833 return z.low;
1834 #endif
1835#else
1836 uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry);
1837 carry = limb(z >> limb_bits);
1838 return limb(z);
1839#endif
1840}
constexpr size_t limb_bits
Definition: fast_float.h:1617

References full_multiplication(), limb_bits, and scalar_add().

Referenced by small_mul().

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

◆ scientific_exponent()

fastfloat_really_inline int32_t fast_float::scientific_exponent ( parsed_number_string num)
noexcept

Definition at line 2438 of file fast_float.h.

2438 {
2439 uint64_t mantissa = num.mantissa;
2440 int32_t exponent = int32_t(num.exponent);
2441 while (mantissa >= 10000) {
2442 mantissa /= 10000;
2443 exponent += 4;
2444 }
2445 while (mantissa >= 100) {
2446 mantissa /= 100;
2447 exponent += 2;
2448 }
2449 while (mantissa >= 10) {
2450 mantissa /= 10;
2451 exponent += 1;
2452 }
2453 return exponent;
2454}

Referenced by digit_comp().

Here is the caller graph for this function:

◆ skip_zeros()

fastfloat_really_inline void fast_float::skip_zeros ( const char *&  first,
const char *  last 
)
noexcept

Definition at line 2580 of file fast_float.h.

2580 {
2581 uint64_t val;
2582 while (std::distance(first, last) >= 8) {
2583 ::memcpy(&val, first, sizeof(uint64_t));
2584 if (val != 0x3030303030303030) {
2585 break;
2586 }
2587 first += 8;
2588 }
2589 while (first != last) {
2590 if (*first != '0') {
2591 break;
2592 }
2593 first++;
2594 }
2595}

Referenced by parse_mantissa().

Here is the caller graph for this function:

◆ small_add()

template<uint16_t size>
fastfloat_really_inline bool fast_float::small_add ( stackvec< size > &  vec,
limb  y 
)
noexcept

Definition at line 1862 of file fast_float.h.

1862 {
1863 return small_add_from(vec, y, 0);
1864}

References small_add_from().

Referenced by fast_float::bigint::add().

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

◆ small_add_from()

template<uint16_t size>
bool fast_float::small_add_from ( stackvec< size > &  vec,
limb  y,
size_t  start 
)
inlinenoexcept

Definition at line 1845 of file fast_float.h.

1845 {
1846 size_t index = start;
1847 limb carry = y;
1848 bool overflow;
1849 while (carry != 0 && index < vec.len()) {
1850 vec[index] = scalar_add(vec[index], carry, overflow);
1851 carry = limb(overflow);
1852 index += 1;
1853 }
1854 if (carry != 0) {
1855 FASTFLOAT_TRY(vec.try_push(carry));
1856 }
1857 return true;
1858}
bool try_push(limb value) noexcept
Definition: fast_float.h:1682

References FASTFLOAT_TRY, and scalar_add().

Referenced by large_add_from(), and small_add().

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

◆ small_mul()

template<uint16_t size>
bool fast_float::small_mul ( stackvec< size > &  vec,
limb  y 
)
inlinenoexcept

Definition at line 1868 of file fast_float.h.

1868 {
1869 limb carry = 0;
1870 for (size_t index = 0; index < vec.len(); index++) {
1871 vec[index] = scalar_mul(vec[index], y, carry);
1872 }
1873 if (carry != 0) {
1874 FASTFLOAT_TRY(vec.try_push(carry));
1875 }
1876 return true;
1877}
fastfloat_really_inline limb scalar_mul(limb x, limb y, limb &carry) noexcept
Definition: fast_float.h:1818

References FASTFLOAT_TRY, and scalar_mul().

Referenced by large_mul(), long_mul(), fast_float::bigint::mul(), and fast_float::bigint::pow5().

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

◆ to_extended()

template<typename T >
fastfloat_really_inline adjusted_mantissa fast_float::to_extended ( value)
noexcept

Definition at line 2458 of file fast_float.h.

2458 {
2461 if (std::is_same<T, float>::value) {
2462 constexpr uint32_t exponent_mask = 0x7F800000;
2463 constexpr uint32_t mantissa_mask = 0x007FFFFF;
2464 constexpr uint64_t hidden_bit_mask = 0x00800000;
2465 uint32_t bits;
2466 ::memcpy(&bits, &value, sizeof(T));
2467 if ((bits & exponent_mask) == 0) {
2468 // denormal
2469 am.power2 = 1 - bias;
2470 am.mantissa = bits & mantissa_mask;
2471 } else {
2472 // normal
2473 am.power2 = int32_t((bits & exponent_mask) >> binary_format<T>::mantissa_explicit_bits());
2474 am.power2 -= bias;
2475 am.mantissa = (bits & mantissa_mask) | hidden_bit_mask;
2476 }
2477 } else {
2478 constexpr uint64_t exponent_mask = 0x7FF0000000000000;
2479 constexpr uint64_t mantissa_mask = 0x000FFFFFFFFFFFFF;
2480 constexpr uint64_t hidden_bit_mask = 0x0010000000000000;
2481 uint64_t bits;
2482 ::memcpy(&bits, &value, sizeof(T));
2483 if ((bits & exponent_mask) == 0) {
2484 // denormal
2485 am.power2 = 1 - bias;
2486 am.mantissa = bits & mantissa_mask;
2487 } else {
2488 // normal
2489 am.power2 = int32_t((bits & exponent_mask) >> binary_format<T>::mantissa_explicit_bits());
2490 am.power2 -= bias;
2491 am.mantissa = (bits & mantissa_mask) | hidden_bit_mask;
2492 }
2493 }
2494
2495 return am;
2496}

References fast_float::adjusted_mantissa::mantissa, fast_float::binary_format< T >::mantissa_explicit_bits(), fast_float::binary_format< T >::minimum_exponent(), and fast_float::adjusted_mantissa::power2.

Referenced by to_extended_halfway().

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

◆ to_extended_halfway()

template<typename T >
fastfloat_really_inline adjusted_mantissa fast_float::to_extended_halfway ( value)
noexcept

Definition at line 2502 of file fast_float.h.

2502 {
2503 adjusted_mantissa am = to_extended(value);
2504 am.mantissa <<= 1;
2505 am.mantissa += 1;
2506 am.power2 -= 1;
2507 return am;
2508}
fastfloat_really_inline adjusted_mantissa to_extended(T value) noexcept
Definition: fast_float.h:2458

References fast_float::adjusted_mantissa::mantissa, fast_float::adjusted_mantissa::power2, and to_extended().

Referenced by negative_digit_comp().

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

◆ to_float()

template<typename T >
fastfloat_really_inline void fast_float::to_float ( bool  negative,
adjusted_mantissa  am,
T &  value 
)

Definition at line 444 of file fast_float.h.

444 {
445 uint64_t word = am.mantissa;
446 word |= uint64_t(am.power2) << binary_format<T>::mantissa_explicit_bits();
447 word = negative
448 ? word | (uint64_t(1) << binary_format<T>::sign_index()) : word;
449#if FASTFLOAT_IS_BIG_ENDIAN == 1
450 if (std::is_same<T, float>::value) {
451 ::memcpy(&value, (char *)&word + 4, sizeof(T)); // extract value at offset 4-7 if float on big-endian
452 } else {
453 ::memcpy(&value, &word, sizeof(T));
454 }
455#else
456 // For little-endian systems:
457 ::memcpy(&value, &word, sizeof(T));
458#endif
459}

References fast_float::adjusted_mantissa::mantissa, fast_float::binary_format< T >::mantissa_explicit_bits(), fast_float::adjusted_mantissa::power2, and fast_float::binary_format< T >::sign_index().

Referenced by from_chars_advanced(), and negative_digit_comp().

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

◆ uint32_hi64() [1/3]

fastfloat_really_inline uint64_t fast_float::uint32_hi64 ( uint32_t  r0,
bool &  truncated 
)
noexcept

Definition at line 1775 of file fast_float.h.

1775 {
1776 return uint64_hi64(r0, truncated);
1777}
fastfloat_really_inline uint64_t uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept
Definition: fast_float.h:1762

References uint64_hi64().

Referenced by fast_float::bigint::hi64().

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

◆ uint32_hi64() [2/3]

fastfloat_really_inline uint64_t fast_float::uint32_hi64 ( uint32_t  r0,
uint32_t  r1,
bool &  truncated 
)
noexcept

Definition at line 1780 of file fast_float.h.

1780 {
1781 uint64_t x0 = r0;
1782 uint64_t x1 = r1;
1783 return uint64_hi64((x0 << 32) | x1, truncated);
1784}

References uint64_hi64().

Here is the call graph for this function:

◆ uint32_hi64() [3/3]

fastfloat_really_inline uint64_t fast_float::uint32_hi64 ( uint32_t  r0,
uint32_t  r1,
uint32_t  r2,
bool &  truncated 
)
noexcept

Definition at line 1787 of file fast_float.h.

1787 {
1788 uint64_t x0 = r0;
1789 uint64_t x1 = r1;
1790 uint64_t x2 = r2;
1791 return uint64_hi64(x0, (x1 << 32) | x2, truncated);
1792}

References uint64_hi64().

Here is the call graph for this function:

◆ uint64_hi64() [1/2]

fastfloat_really_inline uint64_t fast_float::uint64_hi64 ( uint64_t  r0,
bool &  truncated 
)
noexcept

Definition at line 1755 of file fast_float.h.

1755 {
1756 truncated = false;
1757 int shl = leading_zeroes(r0);
1758 return r0 << shl;
1759}

References leading_zeroes().

Referenced by fast_float::bigint::hi64(), and uint32_hi64().

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

◆ uint64_hi64() [2/2]

fastfloat_really_inline uint64_t fast_float::uint64_hi64 ( uint64_t  r0,
uint64_t  r1,
bool &  truncated 
)
noexcept

Definition at line 1762 of file fast_float.h.

1762 {
1763 int shl = leading_zeroes(r0);
1764 if (shl == 0) {
1765 truncated = r1 != 0;
1766 return r0;
1767 } else {
1768 int shr = 64 - shl;
1769 truncated = (r1 << shl) != 0;
1770 return (r0 << shl) | (r1 >> shr);
1771 }
1772}

References leading_zeroes().

Here is the call graph for this function:

◆ write_u64()

fastfloat_really_inline void fast_float::write_u64 ( uint8_t *  chars,
uint64_t  val 
)

Definition at line 502 of file fast_float.h.

502 {
503#if FASTFLOAT_IS_BIG_ENDIAN == 1
504 // Need to read as-if the number was in little-endian order.
505 val = byteswap(val);
506#endif
507 ::memcpy(chars, &val, sizeof(uint64_t));
508}

References byteswap().

Here is the call graph for this function:

Variable Documentation

◆ bigint_bits

constexpr size_t fast_float::bigint_bits = 4000
constexpr

Definition at line 1626 of file fast_float.h.

◆ bigint_limbs

constexpr size_t fast_float::bigint_limbs = bigint_bits / limb_bits
constexpr

Definition at line 1627 of file fast_float.h.

◆ invalid_am_bias

constexpr int32_t fast_float::invalid_am_bias = -0x8000
staticconstexpr

Definition at line 314 of file fast_float.h.

Referenced by compute_error_scaled(), and digit_comp().

◆ limb_bits

constexpr size_t fast_float::limb_bits = 32
constexpr

◆ 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}

Definition at line 316 of file fast_float.h.

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}

Definition at line 319 of file fast_float.h.

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

◆ powers_of_ten_uint64

constexpr uint64_t fast_float::powers_of_ten_uint64[]
staticconstexpr
Initial value:
= {
1UL, 10UL, 100UL, 1000UL, 10000UL, 100000UL, 1000000UL, 10000000UL, 100000000UL,
1000000000UL, 10000000000UL, 100000000000UL, 1000000000000UL, 10000000000000UL,
100000000000000UL, 1000000000000000UL, 10000000000000000UL, 100000000000000000UL,
1000000000000000000UL, 10000000000000000000UL}

Definition at line 2428 of file fast_float.h.

Referenced by parse_mantissa().