mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Merge branch 'main' into main
This commit is contained in:
commit
396a0fc2ae
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,4 +17,7 @@ Release/
|
|||||||
*.vsp
|
*.vsp
|
||||||
*.diagsession
|
*.diagsession
|
||||||
*.hint
|
*.hint
|
||||||
|
|
||||||
|
# VS CMake
|
||||||
|
/out/
|
||||||
/CMakeSettings.json
|
/CMakeSettings.json
|
||||||
|
|||||||
@ -1,38 +1,10 @@
|
|||||||
|
|
||||||
#ifndef FASTFLOAT_FAST_FLOAT_H
|
#ifndef FASTFLOAT_FAST_FLOAT_H
|
||||||
#define FASTFLOAT_FAST_FLOAT_H
|
#define FASTFLOAT_FAST_FLOAT_H
|
||||||
|
|
||||||
#include <system_error>
|
#include "float_common.h"
|
||||||
|
|
||||||
#include "constexpr_feature_detect.h"
|
|
||||||
|
|
||||||
namespace fast_float {
|
namespace fast_float {
|
||||||
enum chars_format {
|
|
||||||
scientific = 1<<0,
|
|
||||||
fixed = 1<<2,
|
|
||||||
hex = 1<<3,
|
|
||||||
general = fixed | scientific
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename UC>
|
|
||||||
struct from_chars_result_t {
|
|
||||||
UC const * ptr;
|
|
||||||
std::errc ec;
|
|
||||||
};
|
|
||||||
using from_chars_result = from_chars_result_t<char>;
|
|
||||||
|
|
||||||
template <typename UC>
|
|
||||||
struct parse_options_t {
|
|
||||||
constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
|
|
||||||
UC dot = UC('.'))
|
|
||||||
: format(fmt), decimal_point(dot) {}
|
|
||||||
|
|
||||||
/** Which number formats are accepted */
|
|
||||||
chars_format format;
|
|
||||||
/** The character used as decimal point */
|
|
||||||
UC decimal_point;
|
|
||||||
};
|
|
||||||
using parse_options = parse_options_t<char>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting
|
* 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.
|
* a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale.
|
||||||
|
|||||||
@ -6,6 +6,40 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
#include "constexpr_feature_detect.h"
|
||||||
|
|
||||||
|
namespace fast_float {
|
||||||
|
|
||||||
|
enum chars_format {
|
||||||
|
scientific = 1 << 0,
|
||||||
|
fixed = 1 << 2,
|
||||||
|
hex = 1 << 3,
|
||||||
|
general = fixed | scientific
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename UC>
|
||||||
|
struct from_chars_result_t {
|
||||||
|
UC const* ptr;
|
||||||
|
std::errc ec;
|
||||||
|
};
|
||||||
|
using from_chars_result = from_chars_result_t<char>;
|
||||||
|
|
||||||
|
template <typename UC>
|
||||||
|
struct parse_options_t {
|
||||||
|
constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
|
||||||
|
UC dot = UC('.'))
|
||||||
|
: format(fmt), decimal_point(dot) {}
|
||||||
|
|
||||||
|
/** Which number formats are accepted */
|
||||||
|
chars_format format;
|
||||||
|
/** The character used as decimal point */
|
||||||
|
UC decimal_point;
|
||||||
|
};
|
||||||
|
using parse_options = parse_options_t<char>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#if FASTFLOAT_HAS_BIT_CAST
|
#if FASTFLOAT_HAS_BIT_CAST
|
||||||
#include <bit>
|
#include <bit>
|
||||||
@ -291,16 +325,43 @@ struct adjusted_mantissa {
|
|||||||
// Bias so we can get the real exponent with an invalid adjusted_mantissa.
|
// Bias so we can get the real exponent with an invalid adjusted_mantissa.
|
||||||
constexpr static int32_t invalid_am_bias = -0x8000;
|
constexpr static int32_t invalid_am_bias = -0x8000;
|
||||||
|
|
||||||
constexpr static double powers_of_ten_double[] = {
|
// used for binary_format_lookup_tables<T>::max_mantissa
|
||||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
|
|
||||||
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
|
|
||||||
constexpr static float powers_of_ten_float[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
|
|
||||||
1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
|
|
||||||
// used for max_mantissa_double and max_mantissa_float
|
|
||||||
constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
|
constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
|
||||||
// Largest integer value v so that (5**index * v) <= 1<<53.
|
|
||||||
// 0x10000000000000 == 1 << 53
|
template <typename T, typename U = void>
|
||||||
constexpr static uint64_t max_mantissa_double[] = {
|
struct binary_format_lookup_tables;
|
||||||
|
|
||||||
|
template <typename T> struct binary_format : binary_format_lookup_tables<T> {
|
||||||
|
using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
|
||||||
|
|
||||||
|
static inline constexpr int mantissa_explicit_bits();
|
||||||
|
static inline constexpr int minimum_exponent();
|
||||||
|
static inline constexpr int infinite_power();
|
||||||
|
static inline constexpr int sign_index();
|
||||||
|
static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
|
||||||
|
static inline constexpr int max_exponent_fast_path();
|
||||||
|
static inline constexpr int max_exponent_round_to_even();
|
||||||
|
static inline constexpr int min_exponent_round_to_even();
|
||||||
|
static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
|
||||||
|
static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
|
||||||
|
static inline constexpr int largest_power_of_ten();
|
||||||
|
static inline constexpr int smallest_power_of_ten();
|
||||||
|
static inline constexpr T exact_power_of_ten(int64_t power);
|
||||||
|
static inline constexpr size_t max_digits();
|
||||||
|
static inline constexpr equiv_uint exponent_mask();
|
||||||
|
static inline constexpr equiv_uint mantissa_mask();
|
||||||
|
static inline constexpr equiv_uint hidden_bit_mask();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct binary_format_lookup_tables<double, U> {
|
||||||
|
static constexpr double powers_of_ten[] = {
|
||||||
|
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
|
||||||
|
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
|
||||||
|
|
||||||
|
// Largest integer value v so that (5**index * v) <= 1<<53.
|
||||||
|
// 0x10000000000000 == 1 << 53
|
||||||
|
static constexpr uint64_t max_mantissa[] = {
|
||||||
0x10000000000000,
|
0x10000000000000,
|
||||||
0x10000000000000 / 5,
|
0x10000000000000 / 5,
|
||||||
0x10000000000000 / (5 * 5),
|
0x10000000000000 / (5 * 5),
|
||||||
@ -325,44 +386,42 @@ constexpr static uint64_t max_mantissa_double[] = {
|
|||||||
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5),
|
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5),
|
||||||
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
|
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
|
||||||
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
|
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct binary_format_lookup_tables<float, U> {
|
||||||
|
static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
|
||||||
|
1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
|
||||||
|
|
||||||
// Largest integer value v so that (5**index * v) <= 1<<24.
|
// Largest integer value v so that (5**index * v) <= 1<<24.
|
||||||
// 0x1000000 == 1<<24
|
// 0x1000000 == 1<<24
|
||||||
constexpr static uint64_t max_mantissa_float[] = {
|
static constexpr uint64_t max_mantissa[] = {
|
||||||
0x1000000,
|
0x1000000,
|
||||||
0x1000000 / 5,
|
0x1000000 / 5,
|
||||||
0x1000000 / (5 * 5),
|
0x1000000 / (5 * 5),
|
||||||
0x1000000 / (5 * 5 * 5),
|
0x1000000 / (5 * 5 * 5),
|
||||||
0x1000000 / (5 * 5 * 5 * 5),
|
0x1000000 / (5 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555),
|
0x1000000 / (constant_55555),
|
||||||
0x1000000 / (constant_55555 * 5),
|
0x1000000 / (constant_55555 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * constant_55555),
|
0x1000000 / (constant_55555 * constant_55555),
|
||||||
0x1000000 / (constant_55555 * constant_55555 * 5)};
|
0x1000000 / (constant_55555 * constant_55555 * 5)};
|
||||||
|
|
||||||
template <typename T> struct binary_format {
|
|
||||||
using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
|
|
||||||
|
|
||||||
static inline constexpr int mantissa_explicit_bits();
|
|
||||||
static inline constexpr int minimum_exponent();
|
|
||||||
static inline constexpr int infinite_power();
|
|
||||||
static inline constexpr int sign_index();
|
|
||||||
static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
|
|
||||||
static inline constexpr int max_exponent_fast_path();
|
|
||||||
static inline constexpr int max_exponent_round_to_even();
|
|
||||||
static inline constexpr int min_exponent_round_to_even();
|
|
||||||
static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
|
|
||||||
static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
|
|
||||||
static inline constexpr int largest_power_of_ten();
|
|
||||||
static inline constexpr int smallest_power_of_ten();
|
|
||||||
static inline constexpr T exact_power_of_ten(int64_t power);
|
|
||||||
static inline constexpr size_t max_digits();
|
|
||||||
static inline constexpr equiv_uint exponent_mask();
|
|
||||||
static inline constexpr equiv_uint mantissa_mask();
|
|
||||||
static inline constexpr equiv_uint hidden_bit_mask();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
|
||||||
|
|
||||||
template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
|
template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
|
||||||
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -425,6 +484,7 @@ template <> inline constexpr int binary_format<double>::max_exponent_fast_path()
|
|||||||
template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
|
template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
|
template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
|
||||||
return uint64_t(2) << mantissa_explicit_bits();
|
return uint64_t(2) << mantissa_explicit_bits();
|
||||||
}
|
}
|
||||||
@ -432,7 +492,8 @@ template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_p
|
|||||||
// caller is responsible to ensure that
|
// caller is responsible to ensure that
|
||||||
// power >= 0 && power <= 22
|
// power >= 0 && power <= 22
|
||||||
//
|
//
|
||||||
return max_mantissa_double[power];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)max_mantissa[0], max_mantissa[power];
|
||||||
}
|
}
|
||||||
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
|
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
|
||||||
return uint64_t(2) << mantissa_explicit_bits();
|
return uint64_t(2) << mantissa_explicit_bits();
|
||||||
@ -441,17 +502,19 @@ template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_pa
|
|||||||
// caller is responsible to ensure that
|
// caller is responsible to ensure that
|
||||||
// power >= 0 && power <= 10
|
// power >= 0 && power <= 10
|
||||||
//
|
//
|
||||||
return max_mantissa_float[power];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)max_mantissa[0], max_mantissa[power];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
|
inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
|
||||||
return powers_of_ten_double[power];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)powers_of_ten[0], powers_of_ten[power];
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
|
inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
|
||||||
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
return powers_of_ten_float[power];
|
return (void)powers_of_ten[0], powers_of_ten[power];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "ascii_number.h"
|
#include "ascii_number.h"
|
||||||
#include "decimal_to_binary.h"
|
#include "decimal_to_binary.h"
|
||||||
#include "digit_comparison.h"
|
#include "digit_comparison.h"
|
||||||
|
#include "float_common.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@ -31,9 +31,8 @@ for filename in ['LICENSE-MIT', 'LICENSE-APACHE']:
|
|||||||
processed_files[filename] = text
|
processed_files[filename] = text
|
||||||
|
|
||||||
# code
|
# code
|
||||||
for filename in [ 'constexpr_feature_detect.h', 'fast_float.h', 'float_common.h', 'ascii_number.h',
|
for filename in [ 'constexpr_feature_detect.h', 'float_common.h', 'fast_float.h', 'ascii_number.h',
|
||||||
'fast_table.h', 'decimal_to_binary.h', 'bigint.h',
|
'fast_table.h', 'decimal_to_binary.h', 'bigint.h', 'digit_comparison.h', 'parse_number.h']:
|
||||||
'ascii_number.h', 'digit_comparison.h', 'parse_number.h']:
|
|
||||||
with open('include/fast_float/' + filename, encoding='utf8') as f:
|
with open('include/fast_float/' + filename, encoding='utf8') as f:
|
||||||
text = ''
|
text = ''
|
||||||
for line in f:
|
for line in f:
|
||||||
@ -76,11 +75,10 @@ text = ''.join([
|
|||||||
processed_files['AUTHORS'], processed_files['CONTRIBUTORS'],
|
processed_files['AUTHORS'], processed_files['CONTRIBUTORS'],
|
||||||
*license_content(args.license),
|
*license_content(args.license),
|
||||||
processed_files['constexpr_feature_detect.h'],
|
processed_files['constexpr_feature_detect.h'],
|
||||||
processed_files['fast_float.h'], processed_files['float_common.h'],
|
processed_files['float_common.h'], processed_files['fast_float.h'],
|
||||||
processed_files['ascii_number.h'], processed_files['fast_table.h'],
|
processed_files['ascii_number.h'], processed_files['fast_table.h'],
|
||||||
processed_files['decimal_to_binary.h'], processed_files['bigint.h'],
|
processed_files['decimal_to_binary.h'], processed_files['bigint.h'],
|
||||||
processed_files['ascii_number.h'], processed_files['digit_comparison.h'],
|
processed_files['digit_comparison.h'], processed_files['parse_number.h']])
|
||||||
processed_files['parse_number.h']])
|
|
||||||
|
|
||||||
if args.output:
|
if args.output:
|
||||||
with open(args.output, 'wt', encoding='utf8') as f:
|
with open(args.output, 'wt', encoding='utf8') as f:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user