mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-02-07 18:26:45 +08:00
This might add support for big endian systems (untested).
This commit is contained in:
parent
db539b211c
commit
7ff364b59a
@ -78,6 +78,8 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
if ((p != pend) && (*p == '.')) {
|
if ((p != pend) && (*p == '.')) {
|
||||||
++p;
|
++p;
|
||||||
const char *first_after_period = p;
|
const char *first_after_period = p;
|
||||||
|
#if FASTFLOAT_IS_BIG_ENDIAN == 0
|
||||||
|
// Fast approach only tested under little endian systems
|
||||||
if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) {
|
if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) {
|
||||||
i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
|
i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
|
||||||
p += 8;
|
p += 8;
|
||||||
@ -86,6 +88,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
p += 8;
|
p += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
while ((p != pend) && is_integer(*p)) {
|
while ((p != pend) && is_integer(*p)) {
|
||||||
uint8_t digit = uint8_t(*p - '0');
|
uint8_t digit = uint8_t(*p - '0');
|
||||||
++p;
|
++p;
|
||||||
@ -196,6 +199,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if FASTFLOAT_IS_BIG_ENDIAN == 0
|
||||||
// We expect that this loop will often take the bulk of the running time
|
// We expect that this loop will often take the bulk of the running time
|
||||||
// because when a value has lots of digits, these digits often
|
// because when a value has lots of digits, these digits often
|
||||||
while ((p + 8 <= pend) && (answer.num_digits + 8 < max_digits)) {
|
while ((p + 8 <= pend) && (answer.num_digits + 8 < max_digits)) {
|
||||||
@ -208,6 +212,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
|
|||||||
answer.num_digits += 8;
|
answer.num_digits += 8;
|
||||||
p += 8;
|
p += 8;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
while ((p != pend) && is_integer(*p)) {
|
while ((p != pend) && is_integer(*p)) {
|
||||||
if (answer.num_digits < max_digits) {
|
if (answer.num_digits < max_digits) {
|
||||||
answer.digits[answer.num_digits] = uint8_t(*p - '0');
|
answer.digits[answer.num_digits] = uint8_t(*p - '0');
|
||||||
|
|||||||
@ -8,6 +8,34 @@
|
|||||||
#define FASTFLOAT_VISUAL_STUDIO 1
|
#define FASTFLOAT_VISUAL_STUDIO 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define FASTFLOAT_IS_BIG_ENDIAN 0
|
||||||
|
#else
|
||||||
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
|
#include <machine/endian.h>
|
||||||
|
#else
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
#
|
||||||
|
#ifndef __BYTE_ORDER__
|
||||||
|
// safe choice
|
||||||
|
#define FASTFLOAT_IS_BIG_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
#
|
||||||
|
#ifndef __ORDER_LITTLE_ENDIAN__
|
||||||
|
// safe choice
|
||||||
|
#define FASTFLOAT_IS_BIG_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
#
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
#define FASTFLOAT_IS_BIG_ENDIAN 0
|
||||||
|
#else
|
||||||
|
#define FASTFLOAT_IS_BIG_ENDIAN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||||
#define fastfloat_really_inline __forceinline
|
#define fastfloat_really_inline __forceinline
|
||||||
#else
|
#else
|
||||||
@ -154,6 +182,13 @@ struct decimal {
|
|||||||
// Note that the user is responsible to ensure that digits are
|
// Note that the user is responsible to ensure that digits are
|
||||||
// initialized to zero when there are fewer than 19.
|
// initialized to zero when there are fewer than 19.
|
||||||
inline uint64_t to_truncated_mantissa() {
|
inline uint64_t to_truncated_mantissa() {
|
||||||
|
#if FASTFLOAT_IS_BIG_ENDIAN == 1
|
||||||
|
for (uint32_t i = 0; i < max_digit_without_overflow;
|
||||||
|
i++) {
|
||||||
|
mantissa = mantissa * 10 + digits[i]; // can be accelerated
|
||||||
|
}
|
||||||
|
return mantissa;
|
||||||
|
#else
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
// 8 first digits
|
// 8 first digits
|
||||||
::memcpy(&val, digits, sizeof(uint64_t));
|
::memcpy(&val, digits, sizeof(uint64_t));
|
||||||
@ -173,6 +208,7 @@ struct decimal {
|
|||||||
mantissa = mantissa * 10 + digits[i]; // can be accelerated
|
mantissa = mantissa * 10 + digits[i]; // can be accelerated
|
||||||
}
|
}
|
||||||
return mantissa;
|
return mantissa;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// Generate san exponent matching to_truncated_mantissa()
|
// Generate san exponent matching to_truncated_mantissa()
|
||||||
inline int32_t to_truncated_exponent() {
|
inline int32_t to_truncated_exponent() {
|
||||||
|
|||||||
@ -107,7 +107,16 @@ from_chars_result from_chars(const char *first, const char *last,
|
|||||||
word |= uint64_t(am.power2) << binary_format<T>::mantissa_explicit_bits();
|
word |= uint64_t(am.power2) << binary_format<T>::mantissa_explicit_bits();
|
||||||
word = pns.negative
|
word = pns.negative
|
||||||
? word | (uint64_t(1) << binary_format<T>::sign_index()) : word;
|
? word | (uint64_t(1) << binary_format<T>::sign_index()) : word;
|
||||||
::memcpy(&value, &word, sizeof(T));
|
#if FASTFLOAT_IS_BIG_ENDIAN == 1
|
||||||
|
if (std::is_same<T, float>::value) {
|
||||||
|
::memcpy(&value, (char *)&word + 4, sizeof(T)); // extract value at offset 4-7 if float on big-endian
|
||||||
|
} else {
|
||||||
|
::memcpy(&value, &word, sizeof(T));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// For little-endian systems:
|
||||||
|
::memcpy(&value, &word, sizeof(T));
|
||||||
|
#endif
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user