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

Functions

fastfloat_really_inline int power (int q) noexcept
 
void trim (decimal &h)
 
uint32_t number_of_digits_decimal_left_shift (const decimal &h, uint32_t shift)
 
uint64_t round (decimal &h)
 
void decimal_left_shift (decimal &h, uint32_t shift)
 
void decimal_right_shift (decimal &h, uint32_t shift)
 
template<typename T >
from_chars_result parse_infnan (const char *first, const char *last, T &value) noexcept
 
template<typename T >
fastfloat_really_inline void to_float (bool negative, adjusted_mantissa am, T &value)
 

Function Documentation

◆ decimal_left_shift()

void fast_float::detail::decimal_left_shift ( decimal h,
uint32_t  shift 
)
inline
2109 {
2110 if (h.num_digits == 0) {
2111 return;
2112 }
2113 uint32_t num_new_digits = number_of_digits_decimal_left_shift(h, shift);
2114 int32_t read_index = int32_t(h.num_digits - 1);
2115 uint32_t write_index = h.num_digits - 1 + num_new_digits;
2116 uint64_t n = 0;
2117
2118 while (read_index >= 0) {
2119 n += uint64_t(h.digits[read_index]) << shift;
2120 uint64_t quotient = n / 10;
2121 uint64_t remainder = n - (10 * quotient);
2122 if (write_index < max_digits) {
2123 h.digits[write_index] = uint8_t(remainder);
2124 } else if (remainder > 0) {
2125 h.truncated = true;
2126 }
2127 n = quotient;
2128 write_index--;
2129 read_index--;
2130 }
2131 while (n > 0) {
2132 uint64_t quotient = n / 10;
2133 uint64_t remainder = n - (10 * quotient);
2134 if (write_index < max_digits) {
2135 h.digits[write_index] = uint8_t(remainder);
2136 } else if (remainder > 0) {
2137 h.truncated = true;
2138 }
2139 n = quotient;
2140 write_index--;
2141 }
2142 h.num_digits += num_new_digits;
2143 if (h.num_digits > max_digits) {
2145 }
2146 h.decimal_point += int32_t(num_new_digits);
2147 trim(h);
2148}
constexpr uint32_t max_digits
Definition fast_float.h:194
void trim(decimal &h)
Definition fast_float.h:1981
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
uint32_t num_digits
Definition fast_float.h:290
__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::decimal::decimal_point, fast_float::decimal::digits, fast_float::decimal::num_digits, number_of_digits_decimal_left_shift(), trim(), and fast_float::decimal::truncated.

Referenced by fast_float::compute_float().

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

◆ decimal_right_shift()

void fast_float::detail::decimal_right_shift ( decimal h,
uint32_t  shift 
)
inline
2151 {
2152 uint32_t read_index = 0;
2153 uint32_t write_index = 0;
2154
2155 uint64_t n = 0;
2156
2157 while ((n >> shift) == 0) {
2158 if (read_index < h.num_digits) {
2159 n = (10 * n) + h.digits[read_index++];
2160 } else if (n == 0) {
2161 return;
2162 } else {
2163 while ((n >> shift) == 0) {
2164 n = 10 * n;
2165 read_index++;
2166 }
2167 break;
2168 }
2169 }
2170 h.decimal_point -= int32_t(read_index - 1);
2171 if (h.decimal_point < -decimal_point_range) { // it is zero
2172 h.num_digits = 0;
2173 h.decimal_point = 0;
2174 h.negative = false;
2175 h.truncated = false;
2176 return;
2177 }
2178 uint64_t mask = (uint64_t(1) << shift) - 1;
2179 while (read_index < h.num_digits) {
2180 uint8_t new_digit = uint8_t(n >> shift);
2181 n = (10 * (n & mask)) + h.digits[read_index++];
2182 h.digits[write_index++] = new_digit;
2183 }
2184 while (n > 0) {
2185 uint8_t new_digit = uint8_t(n >> shift);
2186 n = 10 * (n & mask);
2187 if (write_index < max_digits) {
2188 h.digits[write_index++] = new_digit;
2189 } else if (new_digit > 0) {
2190 h.truncated = true;
2191 }
2192 }
2193 h.num_digits = write_index;
2194 trim(h);
2195}
bool negative
Definition fast_float.h:292

References fast_float::decimal::decimal_point, fast_float::decimal::digits, fast_float::decimal::negative, fast_float::decimal::num_digits, trim(), and fast_float::decimal::truncated.

Referenced by fast_float::compute_float().

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

◆ number_of_digits_decimal_left_shift()

uint32_t fast_float::detail::number_of_digits_decimal_left_shift ( const decimal h,
uint32_t  shift 
)
inline
1989 {
1990 shift &= 63;
1991 const static uint16_t number_of_digits_decimal_left_shift_table[65] = {
1992 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
1993 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
1994 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
1995 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
1996 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
1997 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
1998 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
1999 0x051C, 0x051C,
2000 };
2001 uint32_t x_a = number_of_digits_decimal_left_shift_table[shift];
2002 uint32_t x_b = number_of_digits_decimal_left_shift_table[shift + 1];
2003 uint32_t num_new_digits = x_a >> 11;
2004 uint32_t pow5_a = 0x7FF & x_a;
2005 uint32_t pow5_b = 0x7FF & x_b;
2006 const static uint8_t
2007 number_of_digits_decimal_left_shift_table_powers_of_5[0x051C] = {
2008 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3,
2009 9, 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8,
2010 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1,
2011 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8,
2012 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6,
2013 9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5,
2014 3, 6, 7, 4, 3, 1, 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3,
2015 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0,
2016 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3,
2017 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1,
2018 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8,
2019 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4,
2020 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6, 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5,
2021 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5,
2022 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2,
2023 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5,
2024 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5,
2025 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5,
2026 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, 1, 3, 2, 8, 1, 2,
2027 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0,
2028 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2,
2029 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1,
2030 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6,
2031 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, 2,
2032 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
2033 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7,
2034 3, 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5,
2035 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9,
2036 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8,
2037 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0,
2038 9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2,
2039 5, 1, 4, 2, 1, 0, 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2,
2040 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0,
2041 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7,
2042 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8,
2043 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4,
2044 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1,
2045 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3, 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5,
2046 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9,
2047 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4,
2048 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4,
2049 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4,
2050 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1,
2051 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5,
2052 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1,
2053 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1,
2054 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9,
2055 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0,
2056 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6, 2,
2057 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
2058 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5,
2059 1, 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2,
2060 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1,
2061 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5,
2062 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5,
2063 };
2064 const uint8_t *pow5 =
2065 &number_of_digits_decimal_left_shift_table_powers_of_5[pow5_a];
2066 uint32_t i = 0;
2067 uint32_t n = pow5_b - pow5_a;
2068 for (; i < n; i++) {
2069 if (i >= h.num_digits) {
2070 return num_new_digits - 1;
2071 } else if (h.digits[i] == pow5[i]) {
2072 continue;
2073 } else if (h.digits[i] < pow5[i]) {
2074 return num_new_digits - 1;
2075 } else {
2076 return num_new_digits;
2077 }
2078 }
2079 return num_new_digits;
2080}
unsigned __int16 uint16_t
Definition unistd.h:78

References fast_float::decimal::digits, and fast_float::decimal::num_digits.

Referenced by decimal_left_shift().

+ Here is the caller graph for this function:

◆ parse_infnan()

template<typename T >
from_chars_result fast_float::detail::parse_infnan ( const char *  first,
const char *  last,
T &  value 
)
noexcept

Special case +inf, -inf, nan, infinity, -infinity. The case comparisons could be made much faster given that we know that the strings a null-free and fixed.

2338 {
2339 from_chars_result answer;
2340 answer.ptr = first;
2341 answer.ec = std::errc(); // be optimistic
2342 bool minusSign = false;
2343 if (*first == '-') { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here
2344 minusSign = true;
2345 ++first;
2346 }
2347 if (last - first >= 3) {
2348 if (fastfloat_strncasecmp(first, "nan", 3)) {
2349 answer.ptr = (first += 3);
2350 value = minusSign ? -std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN();
2351 // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
2352 if(first != last && *first == '(') {
2353 for(const char* ptr = first + 1; ptr != last; ++ptr) {
2354 if (*ptr == ')') {
2355 answer.ptr = ptr + 1; // valid nan(n-char-seq-opt)
2356 break;
2357 }
2358 else if(!(('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z') || ('0' <= *ptr && *ptr <= '9') || *ptr == '_'))
2359 break; // forbidden char, not nan(n-char-seq-opt)
2360 }
2361 }
2362 return answer;
2363 }
2364 if (fastfloat_strncasecmp(first, "inf", 3)) {
2365 if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, "inity", 5)) {
2366 answer.ptr = first + 8;
2367 } else {
2368 answer.ptr = first + 3;
2369 }
2370 value = minusSign ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
2371 return answer;
2372 }
2373 }
2374 answer.ec = std::errc::invalid_argument;
2375 return answer;
2376}
std::errc ec
Definition fast_float.h:54
bool fastfloat_strncasecmp(const char *input1, const char *input2, size_t length)
Definition fast_float.h:180
const char * ptr
Definition fast_float.h:53
Definition fast_float.h:52
STL namespace.

References fast_float::from_chars_result::ec, fast_float::fastfloat_strncasecmp(), and fast_float::from_chars_result::ptr.

Referenced by fast_float::from_chars_advanced().

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

◆ power()

fastfloat_really_inline int fast_float::detail::power ( int  q)
noexcept

For q in (0,350), we have that f = (((152170 + 65536) * q ) >> 16); is equal to floor(p) + q where p = log(5**q)/log(2) = q * log(5)/log(2)

For negative values of q in (-400,0), we have that f = (((152170 + 65536) * q ) >> 16); is equal to -ceil(p) + q where p = log(5**-q)/log(2) = -q * log(5)/log(2)

1518 {
1519 return (((152170 + 65536) * q) >> 16) + 63;
1520 }

Referenced by fast_float::compute_float().

+ Here is the caller graph for this function:

◆ round()

uint64_t fast_float::detail::round ( decimal h)
inline
2082 {
2083 if ((h.num_digits == 0) || (h.decimal_point < 0)) {
2084 return 0;
2085 } else if (h.decimal_point > 18) {
2086 return UINT64_MAX;
2087 }
2088 // at this point, we know that h.decimal_point >= 0
2090 uint64_t n = 0;
2091 for (uint32_t i = 0; i < dp; i++) {
2092 n = (10 * n) + ((i < h.num_digits) ? h.digits[i] : 0);
2093 }
2094 bool round_up = false;
2095 if (dp < h.num_digits) {
2096 round_up = h.digits[dp] >= 5; // normally, we round up
2097 // but we may need to round to even!
2098 if ((h.digits[dp] == 5) && (dp + 1 == h.num_digits)) {
2099 round_up = h.truncated || ((dp > 0) && (1 & h.digits[dp - 1]));
2100 }
2101 }
2102 if (round_up) {
2103 n++;
2104 }
2105 return n;
2106}

References fast_float::decimal::decimal_point, fast_float::decimal::digits, fast_float::decimal::num_digits, and fast_float::decimal::truncated.

Referenced by fast_float::compute_float().

+ Here is the caller graph for this function:

◆ to_float()

template<typename T >
fastfloat_really_inline void fast_float::detail::to_float ( bool  negative,
adjusted_mantissa  am,
T &  value 
)
2379 {
2380 uint64_t word = am.mantissa;
2382 word = negative
2383 ? word | (uint64_t(1) << binary_format<T>::sign_index()) : word;
2384#if FASTFLOAT_IS_BIG_ENDIAN == 1
2385 if (std::is_same<T, float>::value) {
2386 ::memcpy(&value, (char *)&word + 4, sizeof(T)); // extract value at offset 4-7 if float on big-endian
2387 } else {
2388 ::memcpy(&value, &word, sizeof(T));
2389 }
2390#else
2391 // For little-endian systems:
2392 ::memcpy(&value, &word, sizeof(T));
2393#endif
2394}
int power2
Definition fast_float.h:279
uint64_t mantissa
Definition fast_float.h:278
Definition fast_float.h:311

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 fast_float::from_chars_advanced().

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

◆ trim()

void fast_float::detail::trim ( decimal h)
inline
1981 {
1982 while ((h.num_digits > 0) && (h.digits[h.num_digits - 1] == 0)) {
1983 h.num_digits--;
1984 }
1985}

References fast_float::decimal::digits, and fast_float::decimal::num_digits.

Referenced by decimal_left_shift(), and decimal_right_shift().

+ Here is the caller graph for this function: