mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
This commit is contained in:
parent
9b102a95ab
commit
741e68ce61
@ -114,9 +114,9 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
|
|
||||||
int32_t digit_count =
|
int32_t digit_count =
|
||||||
int32_t(p - start_digits - 1); // used later to guard against overflows
|
int32_t(p - start_digits - 1); // used later to guard against overflows
|
||||||
|
|
||||||
if ((p != pend) && (('e' == *p) || ('E' == *p))) {
|
if ((fmt & chars_format::scientific) && (p != pend) && (('e' == *p) || ('E' == *p))) {
|
||||||
if((fmt & chars_format::fixed) && !(fmt & chars_format::scientific)) { return answer; }
|
const char * location_of_e = p;
|
||||||
int64_t exp_number = 0; // exponential part
|
int64_t exp_number = 0; // exponential part
|
||||||
++p;
|
++p;
|
||||||
bool neg_exp = false;
|
bool neg_exp = false;
|
||||||
@ -127,18 +127,24 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
if ((p == pend) || !is_integer(*p)) {
|
if ((p == pend) || !is_integer(*p)) {
|
||||||
return answer;
|
if(!(fmt & chars_format::fixed)) {
|
||||||
}
|
// We are in error.
|
||||||
while ((p != pend) && is_integer(*p)) {
|
return answer;
|
||||||
uint8_t digit = uint8_t(*p - '0');
|
|
||||||
if (exp_number < 0x10000) {
|
|
||||||
exp_number = 10 * exp_number + digit;
|
|
||||||
}
|
}
|
||||||
++p;
|
// Otherwise, we will be ignoring the 'e'.
|
||||||
|
} else {
|
||||||
|
while ((p != pend) && is_integer(*p)) {
|
||||||
|
uint8_t digit = uint8_t(*p - '0');
|
||||||
|
if (exp_number < 0x10000) {
|
||||||
|
exp_number = 10 * exp_number + digit;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
exponent += (neg_exp ? -exp_number : exp_number);
|
||||||
}
|
}
|
||||||
exponent += (neg_exp ? -exp_number : exp_number);
|
|
||||||
} else {
|
} else {
|
||||||
if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
|
// If it scientific and not fixed, we have to bail out.
|
||||||
|
if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
|
||||||
}
|
}
|
||||||
answer.lastmatch = p;
|
answer.lastmatch = p;
|
||||||
answer.valid = true;
|
answer.valid = true;
|
||||||
@ -206,7 +212,7 @@ decimal parse_decimal(const char *p, const char *pend) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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)) {
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
::memcpy(&val, p, sizeof(uint64_t));
|
::memcpy(&val, p, sizeof(uint64_t));
|
||||||
@ -240,7 +246,7 @@ decimal parse_decimal(const char *p, const char *pend) noexcept {
|
|||||||
uint8_t digit = uint8_t(*p - '0');
|
uint8_t digit = uint8_t(*p - '0');
|
||||||
if (exp_number < 0x10000) {
|
if (exp_number < 0x10000) {
|
||||||
exp_number = 10 * exp_number + digit;
|
exp_number = 10 * exp_number + digit;
|
||||||
}
|
}
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
answer.decimal_point += (neg_exp ? -exp_number : exp_number);
|
answer.decimal_point += (neg_exp ? -exp_number : exp_number);
|
||||||
|
|||||||
@ -17,18 +17,18 @@ namespace fast_float {
|
|||||||
// This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
|
// This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
|
||||||
// the result, with the "high" part corresponding to the most significant bits and the
|
// the result, with the "high" part corresponding to the most significant bits and the
|
||||||
// low part corresponding to the least significant bits.
|
// low part corresponding to the least significant bits.
|
||||||
//
|
//
|
||||||
template <int bit_precision>
|
template <int bit_precision>
|
||||||
fastfloat_really_inline
|
fastfloat_really_inline
|
||||||
value128 compute_product_approximation(int64_t q, uint64_t w) {
|
value128 compute_product_approximation(int64_t q, uint64_t w) {
|
||||||
const int index = 2 * int(q - smallest_power_of_five);
|
const int index = 2 * int(q - smallest_power_of_five);
|
||||||
// For small values of q, e.g., q in [0,27], the answer is always exact because
|
// For small values of q, e.g., q in [0,27], the answer is always exact because
|
||||||
// The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
|
// The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
|
||||||
// gives the exact answer.
|
// gives the exact answer.
|
||||||
value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
|
value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
|
||||||
static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
|
static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
|
||||||
constexpr uint64_t precision_mask = (bit_precision < 64) ?
|
constexpr uint64_t precision_mask = (bit_precision < 64) ?
|
||||||
(uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
|
(uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
|
||||||
: uint64_t(0xFFFFFFFFFFFFFFFF);
|
: uint64_t(0xFFFFFFFFFFFFFFFF);
|
||||||
if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
|
if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
|
||||||
// regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
|
// regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
|
||||||
@ -58,7 +58,7 @@ namespace {
|
|||||||
|
|
||||||
// w * 10 ** q
|
// w * 10 ** q
|
||||||
// The returned value should be a valid ieee64 number that simply need to be packed.
|
// The returned value should be a valid ieee64 number that simply need to be packed.
|
||||||
// However, in some very rare cases, the computation will fail. In such cases, we
|
// However, in some very rare cases, the computation will fail. In such cases, we
|
||||||
// return an adjusted_mantissa with a negative power of 2: the caller should recompute
|
// return an adjusted_mantissa with a negative power of 2: the caller should recompute
|
||||||
// in such cases.
|
// in such cases.
|
||||||
template <typename binary>
|
template <typename binary>
|
||||||
@ -88,7 +88,7 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
|||||||
// 2. We need an extra bit for rounding purposes
|
// 2. We need an extra bit for rounding purposes
|
||||||
// 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
|
// 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
|
||||||
value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
||||||
if(product.low == 0xFFFFFFFFFFFFFFFF) { // could guard it further
|
if(product.low == 0xFFFFFFFFFFFFFFFF) { // could guard it further
|
||||||
// In some very rare cases, this could happen, in which case we might need a more accurate
|
// In some very rare cases, this could happen, in which case we might need a more accurate
|
||||||
// computation that what we can provide cheaply. This is very, very unlikely.
|
// computation that what we can provide cheaply. This is very, very unlikely.
|
||||||
answer.power2 = -1; // This (a negative value) indicates an error condition.
|
answer.power2 = -1; // This (a negative value) indicates an error condition.
|
||||||
@ -111,7 +111,7 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
|||||||
answer.mantissa = 0;
|
answer.mantissa = 0;
|
||||||
// result should be zero
|
// result should be zero
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
// next line is safe because -answer.power2 + 1 < 64
|
// next line is safe because -answer.power2 + 1 < 64
|
||||||
answer.mantissa >>= -answer.power2 + 1;
|
answer.mantissa >>= -answer.power2 + 1;
|
||||||
// Thankfully, we can't have both "round-to-even" and subnormals because
|
// Thankfully, we can't have both "round-to-even" and subnormals because
|
||||||
@ -132,7 +132,7 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
|||||||
// usually, we round *up*, but if we fall right in between and and we have an
|
// usually, we round *up*, but if we fall right in between and and we have an
|
||||||
// even basis, we need to round down
|
// even basis, we need to round down
|
||||||
// We are only concerned with the cases where 5**q fits in single 64-bit word.
|
// We are only concerned with the cases where 5**q fits in single 64-bit word.
|
||||||
if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
|
if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
|
||||||
((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
|
((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
|
||||||
// To be in-between two floats we need that in doing
|
// To be in-between two floats we need that in doing
|
||||||
// answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
|
// answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
|
||||||
|
|||||||
@ -19,19 +19,19 @@ struct from_chars_result {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* The resulting floating-point value is the closest floating-point values (using either float or double),
|
* 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.
|
* 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.
|
* 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
|
* 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
|
* 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.
|
* `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`).
|
* 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
|
* 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
|
* 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
|
* `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.
|
* 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`.
|
* The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
|
||||||
|
|||||||
@ -19,12 +19,12 @@ namespace fast_float {
|
|||||||
* The smallest non-zero float (binary64) is 2^−1074.
|
* The smallest non-zero float (binary64) is 2^−1074.
|
||||||
* We take as input numbers of the form w x 10^q where w < 2^64.
|
* We take as input numbers of the form w x 10^q where w < 2^64.
|
||||||
* We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076.
|
* We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076.
|
||||||
* However, we have that
|
* However, we have that
|
||||||
* (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^−1074.
|
* (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^−1074.
|
||||||
* Thus it is possible for a number of the form w * 10^-342 where
|
* Thus it is possible for a number of the form w * 10^-342 where
|
||||||
* w is a 64-bit value to be a non-zero floating-point number.
|
* w is a 64-bit value to be a non-zero floating-point number.
|
||||||
*********
|
*********
|
||||||
* Any number of form w * 10^309 where w>= 1 is going to be
|
* Any number of form w * 10^309 where w>= 1 is going to be
|
||||||
* infinite in binary64 so we never need to worry about powers
|
* infinite in binary64 so we never need to worry about powers
|
||||||
* of 5 greater than 308.
|
* of 5 greater than 308.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace fast_float {
|
|||||||
namespace {
|
namespace {
|
||||||
/**
|
/**
|
||||||
* Special case +inf, -inf, nan, infinity, -infinity.
|
* Special case +inf, -inf, nan, infinity, -infinity.
|
||||||
* The case comparisons could be made much faster given that we know that the
|
* The case comparisons could be made much faster given that we know that the
|
||||||
* strings a null-free and fixed.
|
* strings a null-free and fixed.
|
||||||
**/
|
**/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -63,6 +63,7 @@ from_chars_result parse_infnan(const char *first, const char *last, T &value) n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
answer.ec = std::errc::invalid_argument;
|
answer.ec = std::errc::invalid_argument;
|
||||||
|
answer.ptr = first;
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -93,7 +94,7 @@ from_chars_result from_chars(const char *first, const char *last,
|
|||||||
|
|
||||||
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()) {
|
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()) {
|
||||||
value = T(pns.mantissa);
|
value = T(pns.mantissa);
|
||||||
if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
|
if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
|
||||||
else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
|
else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
|
||||||
if (pns.negative) { value = -value; }
|
if (pns.negative) { value = -value; }
|
||||||
return answer;
|
return answer;
|
||||||
@ -104,7 +105,7 @@ from_chars_result from_chars(const char *first, const char *last,
|
|||||||
if(am.power2 < 0) { am = parse_long_mantissa<binary_format<T>>(first,last); }
|
if(am.power2 < 0) { am = parse_long_mantissa<binary_format<T>>(first,last); }
|
||||||
uint64_t word = am.mantissa;
|
uint64_t word = am.mantissa;
|
||||||
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));
|
::memcpy(&value, &word, sizeof(T));
|
||||||
return answer;
|
return answer;
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is meant to handle the case where we have more than 19 digits.
|
* This code is meant to handle the case where we have more than 19 digits.
|
||||||
*
|
*
|
||||||
* It is based on work by Nigel Tao (at https://github.com/google/wuffs/)
|
* It is based on work by Nigel Tao (at https://github.com/google/wuffs/)
|
||||||
* who credits Ken Thompson for the design (via a reference to the Go source
|
* who credits Ken Thompson for the design (via a reference to the Go source
|
||||||
* code).
|
* code).
|
||||||
*
|
*
|
||||||
* Rob Pike suggested that this algorithm be called "Simple Decimal Conversion".
|
* Rob Pike suggested that this algorithm be called "Simple Decimal Conversion".
|
||||||
*
|
*
|
||||||
* It is probably not very fast but it is a fallback that should almost never
|
* It is probably not very fast but it is a fallback that should almost never
|
||||||
* be used in real life. Though it is not fast, it is "easily" understood and debugged.
|
* be used in real life. Though it is not fast, it is "easily" understood and debugged.
|
||||||
**/
|
**/
|
||||||
@ -139,7 +139,7 @@ uint64_t round(decimal &h) {
|
|||||||
}
|
}
|
||||||
bool round_up = false;
|
bool round_up = false;
|
||||||
if (dp < h.num_digits) {
|
if (dp < h.num_digits) {
|
||||||
round_up = h.digits[dp] >= 5; // normally, we round up
|
round_up = h.digits[dp] >= 5; // normally, we round up
|
||||||
// but we may need to round to even!
|
// but we may need to round to even!
|
||||||
if ((h.digits[dp] == 5) && (dp + 1 == h.num_digits)) {
|
if ((h.digits[dp] == 5) && (dp + 1 == h.num_digits)) {
|
||||||
round_up = h.truncated || ((dp > 0) && (1 & h.digits[dp - 1]));
|
round_up = h.truncated || ((dp > 0) && (1 & h.digits[dp - 1]));
|
||||||
@ -253,21 +253,21 @@ adjusted_mantissa compute_float(decimal &d) {
|
|||||||
// At this point, going further, we can assume that d.num_digits > 0.
|
// At this point, going further, we can assume that d.num_digits > 0.
|
||||||
//
|
//
|
||||||
// We want to guard against excessive decimal point values because
|
// We want to guard against excessive decimal point values because
|
||||||
// they can result in long running times. Indeed, we do
|
// they can result in long running times. Indeed, we do
|
||||||
// shifts by at most 60 bits. We have that log(10**400)/log(2**60) ~= 22
|
// shifts by at most 60 bits. We have that log(10**400)/log(2**60) ~= 22
|
||||||
// which is fine, but log(10**299995)/log(2**60) ~= 16609 which is not
|
// which is fine, but log(10**299995)/log(2**60) ~= 16609 which is not
|
||||||
// fine (runs for a long time).
|
// fine (runs for a long time).
|
||||||
//
|
//
|
||||||
if(d.decimal_point < -324) {
|
if(d.decimal_point < -324) {
|
||||||
// We have something smaller than 1e-324 which is always zero
|
// We have something smaller than 1e-324 which is always zero
|
||||||
// in binary64 and binary32.
|
// in binary64 and binary32.
|
||||||
// It should be zero.
|
// It should be zero.
|
||||||
answer.power2 = 0;
|
answer.power2 = 0;
|
||||||
answer.mantissa = 0;
|
answer.mantissa = 0;
|
||||||
return answer;
|
return answer;
|
||||||
} else if(d.decimal_point >= 310) {
|
} else if(d.decimal_point >= 310) {
|
||||||
// We have something at least as large as 0.1e310 which is
|
// We have something at least as large as 0.1e310 which is
|
||||||
// always infinite.
|
// always infinite.
|
||||||
answer.power2 = binary::infinite_power();
|
answer.power2 = binary::infinite_power();
|
||||||
answer.mantissa = 0;
|
answer.mantissa = 0;
|
||||||
return answer;
|
return answer;
|
||||||
|
|||||||
@ -147,9 +147,42 @@ bool issue8() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_behavior() {
|
||||||
|
const std::string input = "abc";
|
||||||
|
double result;
|
||||||
|
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||||
|
if(answer.ec != std::errc()) {
|
||||||
|
std::cerr << "parsing failure as expected\n";
|
||||||
|
// specification says ptr should point at first
|
||||||
|
if(answer.ptr != input.data()) {
|
||||||
|
std::cerr << "If there is no pattern match, we should have ptr equals first\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::cout << "parsed the number " << result << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool issue19() {
|
||||||
|
const std::string input = "3.14e";
|
||||||
|
double result;
|
||||||
|
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||||
|
if(answer.ec != std::errc()) {
|
||||||
|
std::cerr << "We want to parse up to 3.14\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::cout << "parsed the number " << result << std::endl;
|
||||||
|
if(answer.ptr != input.data() + 4) {
|
||||||
|
std::cout << "Parsed the number and stopped at the right character." << result << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Assert(issue19());
|
||||||
|
Assert(check_behavior());
|
||||||
std::cout << "======= 64 bits " << std::endl;
|
std::cout << "======= 64 bits " << std::endl;
|
||||||
Assert(basic_test_64bit("INF",std::numeric_limits<double>::infinity()));
|
Assert(basic_test_64bit("INF",std::numeric_limits<double>::infinity()));
|
||||||
Assert(basic_test_64bit("-INF",-std::numeric_limits<double>::infinity()));
|
Assert(basic_test_64bit("-INF",-std::numeric_limits<double>::infinity()));
|
||||||
@ -167,7 +200,7 @@ int main() {
|
|||||||
Assert(basic_test_64bit("2.2250738585072013e-308",2.2250738585072013e-308));
|
Assert(basic_test_64bit("2.2250738585072013e-308",2.2250738585072013e-308));
|
||||||
Assert(basic_test_64bit("-92666518056446206563E3", -92666518056446206563E3));
|
Assert(basic_test_64bit("-92666518056446206563E3", -92666518056446206563E3));
|
||||||
Assert(basic_test_64bit("-92666518056446206563E3", -92666518056446206563E3));
|
Assert(basic_test_64bit("-92666518056446206563E3", -92666518056446206563E3));
|
||||||
Assert(basic_test_64bit("-42823146028335318693e-128",-42823146028335318693e-128));
|
Assert(basic_test_64bit("-42823146028335318693e-128",-42823146028335318693e-128));
|
||||||
Assert(basic_test_64bit("90054602635948575728E72",90054602635948575728E72));
|
Assert(basic_test_64bit("90054602635948575728E72",90054602635948575728E72));
|
||||||
Assert(basic_test_64bit("1.00000000000000188558920870223463870174566020691753515394643550663070558368373221972569761144603605635692374830246134201063722058e-309", 1.00000000000000188558920870223463870174566020691753515394643550663070558368373221972569761144603605635692374830246134201063722058e-309));
|
Assert(basic_test_64bit("1.00000000000000188558920870223463870174566020691753515394643550663070558368373221972569761144603605635692374830246134201063722058e-309", 1.00000000000000188558920870223463870174566020691753515394643550663070558368373221972569761144603605635692374830246134201063722058e-309));
|
||||||
Assert(basic_test_64bit("0e9999999999999999999999999999", 0));
|
Assert(basic_test_64bit("0e9999999999999999999999999999", 0));
|
||||||
@ -214,7 +247,7 @@ int main() {
|
|||||||
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375));
|
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375));
|
||||||
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375));
|
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375));
|
||||||
Assert(basic_test_64bit("1438456663141390273526118207642235581183227845246331231162636653790368152091394196930365828634687637948157940776599182791387527135353034738357134110310609455693900824193549772792016543182680519740580354365467985440183598701312257624545562331397018329928613196125590274187720073914818062530830316533158098624984118889298281371812288789537310599037529113415438738954894752124724983067241108764488346454376699018673078404751121414804937224240805993123816932326223683090770561597570457793932985826162604255884529134126396282202126526253389383421806727954588525596114379801269094096329805054803089299736996870951258573010877404407451953846698609198213926882692078557033228265259305481198526059813164469187586693257335779522020407645498684263339921905227556616698129967412891282231685504660671277927198290009824680186319750978665734576683784255802269708917361719466043175201158849097881370477111850171579869056016061666173029059588433776015644439705050377554277696143928278093453792803846252715966016733222646442382892123940052441346822429721593884378212558701004356924243030059517489346646577724622498919752597382095222500311124181823512251071356181769376577651390028297796156208815375089159128394945710515861334486267101797497111125909272505194792870889617179758703442608016143343262159998149700606597792535574457560429226974273443630323818747730771316763398572110874959981923732463076884528677392654150010269822239401993427482376513231389212353583573566376915572650916866553612366187378959554983566712767093372906030188976220169058025354973622211666504549316958271880975697143546564469806791358707318873075708383345004090151974068325838177531266954177406661392229801349994695941509935655355652985723782153570084089560139142231.738475042362596875449154552392299548947138162081694168675340677843807613129780449323363759027012972466987370921816813162658754726545121090545507240267000456594786540949605260722461937870630634874991729398208026467698131898691830012167897399682179601734569071423681e-733", std::numeric_limits<double>::infinity()));
|
Assert(basic_test_64bit("1438456663141390273526118207642235581183227845246331231162636653790368152091394196930365828634687637948157940776599182791387527135353034738357134110310609455693900824193549772792016543182680519740580354365467985440183598701312257624545562331397018329928613196125590274187720073914818062530830316533158098624984118889298281371812288789537310599037529113415438738954894752124724983067241108764488346454376699018673078404751121414804937224240805993123816932326223683090770561597570457793932985826162604255884529134126396282202126526253389383421806727954588525596114379801269094096329805054803089299736996870951258573010877404407451953846698609198213926882692078557033228265259305481198526059813164469187586693257335779522020407645498684263339921905227556616698129967412891282231685504660671277927198290009824680186319750978665734576683784255802269708917361719466043175201158849097881370477111850171579869056016061666173029059588433776015644439705050377554277696143928278093453792803846252715966016733222646442382892123940052441346822429721593884378212558701004356924243030059517489346646577724622498919752597382095222500311124181823512251071356181769376577651390028297796156208815375089159128394945710515861334486267101797497111125909272505194792870889617179758703442608016143343262159998149700606597792535574457560429226974273443630323818747730771316763398572110874959981923732463076884528677392654150010269822239401993427482376513231389212353583573566376915572650916866553612366187378959554983566712767093372906030188976220169058025354973622211666504549316958271880975697143546564469806791358707318873075708383345004090151974068325838177531266954177406661392229801349994695941509935655355652985723782153570084089560139142231.738475042362596875449154552392299548947138162081694168675340677843807613129780449323363759027012972466987370921816813162658754726545121090545507240267000456594786540949605260722461937870630634874991729398208026467698131898691830012167897399682179601734569071423681e-733", std::numeric_limits<double>::infinity()));
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "======= 32 bits " << std::endl;
|
std::cout << "======= 32 bits " << std::endl;
|
||||||
@ -230,43 +263,43 @@ int main() {
|
|||||||
Assert(basic_test_32bit("1090544144181609348835077142190",0x1.b877ap+99f));
|
Assert(basic_test_32bit("1090544144181609348835077142190",0x1.b877ap+99f));
|
||||||
Assert(basic_test_32bit("1.1754943508e-38",1.1754943508e-38f));
|
Assert(basic_test_32bit("1.1754943508e-38",1.1754943508e-38f));
|
||||||
Assert(basic_test_32bit("30219.0830078125",30219.0830078125f));
|
Assert(basic_test_32bit("30219.0830078125",30219.0830078125f));
|
||||||
Assert(basic_test_32bit("16252921.5",16252921.5f));
|
Assert(basic_test_32bit("16252921.5",16252921.5f));
|
||||||
Assert(basic_test_32bit("5322519.25",5322519.25f));
|
Assert(basic_test_32bit("5322519.25",5322519.25f));
|
||||||
Assert(basic_test_32bit("3900245.875",3900245.875f));
|
Assert(basic_test_32bit("3900245.875",3900245.875f));
|
||||||
Assert(basic_test_32bit("1510988.3125",1510988.3125f));
|
Assert(basic_test_32bit("1510988.3125",1510988.3125f));
|
||||||
Assert(basic_test_32bit("782262.28125",782262.28125f));
|
Assert(basic_test_32bit("782262.28125",782262.28125f));
|
||||||
Assert(basic_test_32bit("328381.484375",328381.484375f));
|
Assert(basic_test_32bit("328381.484375",328381.484375f));
|
||||||
Assert(basic_test_32bit("156782.0703125",156782.0703125f));
|
Assert(basic_test_32bit("156782.0703125",156782.0703125f));
|
||||||
Assert(basic_test_32bit("85003.24609375",85003.24609375f));
|
Assert(basic_test_32bit("85003.24609375",85003.24609375f));
|
||||||
Assert(basic_test_32bit("43827.048828125",43827.048828125f));
|
Assert(basic_test_32bit("43827.048828125",43827.048828125f));
|
||||||
Assert(basic_test_32bit("17419.6494140625",17419.6494140625f));
|
Assert(basic_test_32bit("17419.6494140625",17419.6494140625f));
|
||||||
Assert(basic_test_32bit("15498.36376953125",15498.36376953125f));
|
Assert(basic_test_32bit("15498.36376953125",15498.36376953125f));
|
||||||
Assert(basic_test_32bit("6318.580322265625",6318.580322265625f));
|
Assert(basic_test_32bit("6318.580322265625",6318.580322265625f));
|
||||||
Assert(basic_test_32bit("2525.2840576171875",2525.2840576171875f));
|
Assert(basic_test_32bit("2525.2840576171875",2525.2840576171875f));
|
||||||
Assert(basic_test_32bit("1370.9265747070312",1370.9265747070312f));
|
Assert(basic_test_32bit("1370.9265747070312",1370.9265747070312f));
|
||||||
Assert(basic_test_32bit("936.3702087402344",936.3702087402344f));
|
Assert(basic_test_32bit("936.3702087402344",936.3702087402344f));
|
||||||
Assert(basic_test_32bit("411.88682556152344",411.88682556152344f));
|
Assert(basic_test_32bit("411.88682556152344",411.88682556152344f));
|
||||||
Assert(basic_test_32bit("206.50310516357422",206.50310516357422f));
|
Assert(basic_test_32bit("206.50310516357422",206.50310516357422f));
|
||||||
Assert(basic_test_32bit("124.16878890991211",124.16878890991211f));
|
Assert(basic_test_32bit("124.16878890991211",124.16878890991211f));
|
||||||
Assert(basic_test_32bit("50.811574935913086",50.811574935913086f));
|
Assert(basic_test_32bit("50.811574935913086",50.811574935913086f));
|
||||||
Assert(basic_test_32bit("17.486443519592285",17.486443519592285f));
|
Assert(basic_test_32bit("17.486443519592285",17.486443519592285f));
|
||||||
Assert(basic_test_32bit("13.91745138168335",13.91745138168335f));
|
Assert(basic_test_32bit("13.91745138168335",13.91745138168335f));
|
||||||
Assert(basic_test_32bit("7.5464513301849365",0x1.e2f90ep+2f));
|
Assert(basic_test_32bit("7.5464513301849365",0x1.e2f90ep+2f));
|
||||||
Assert(basic_test_32bit("2.687217116355896",2.687217116355896f));
|
Assert(basic_test_32bit("2.687217116355896",2.687217116355896f));
|
||||||
Assert(basic_test_32bit("1.1877630352973938",0x1.30113ep+0f));
|
Assert(basic_test_32bit("1.1877630352973938",0x1.30113ep+0f));
|
||||||
Assert(basic_test_32bit("0.7622503340244293",0.7622503340244293f));
|
Assert(basic_test_32bit("0.7622503340244293",0.7622503340244293f));
|
||||||
Assert(basic_test_32bit("0.30531780421733856",0x1.38a53ap-2f));
|
Assert(basic_test_32bit("0.30531780421733856",0x1.38a53ap-2f));
|
||||||
Assert(basic_test_32bit("0.21791061013936996",0x1.be47eap-3f));
|
Assert(basic_test_32bit("0.21791061013936996",0x1.be47eap-3f));
|
||||||
Assert(basic_test_32bit("0.09289376810193062",0x1.7c7e2ep-4f));
|
Assert(basic_test_32bit("0.09289376810193062",0x1.7c7e2ep-4f));
|
||||||
Assert(basic_test_32bit("0.03706067614257336",0.03706067614257336f));
|
Assert(basic_test_32bit("0.03706067614257336",0.03706067614257336f));
|
||||||
Assert(basic_test_32bit("0.028068351559340954",0.028068351559340954f));
|
Assert(basic_test_32bit("0.028068351559340954",0.028068351559340954f));
|
||||||
Assert(basic_test_32bit("0.012114629615098238",0x1.8cf8e2p-7f));
|
Assert(basic_test_32bit("0.012114629615098238",0x1.8cf8e2p-7f));
|
||||||
Assert(basic_test_32bit("0.004221370676532388",0x1.14a6dap-8f));
|
Assert(basic_test_32bit("0.004221370676532388",0x1.14a6dap-8f));
|
||||||
Assert(basic_test_32bit("0.002153817447833717",0.002153817447833717f));
|
Assert(basic_test_32bit("0.002153817447833717",0.002153817447833717f));
|
||||||
Assert(basic_test_32bit("0.0015924838953651488",0x1.a175cap-10f));
|
Assert(basic_test_32bit("0.0015924838953651488",0x1.a175cap-10f));
|
||||||
Assert(basic_test_32bit("0.0008602388261351734",0.0008602388261351734f));
|
Assert(basic_test_32bit("0.0008602388261351734",0.0008602388261351734f));
|
||||||
Assert(basic_test_32bit("0.00036393293703440577",0x1.7d9c82p-12f));
|
Assert(basic_test_32bit("0.00036393293703440577",0x1.7d9c82p-12f));
|
||||||
Assert(basic_test_32bit("0.00013746770127909258",0.00013746770127909258));
|
Assert(basic_test_32bit("0.00013746770127909258",0.00013746770127909258));
|
||||||
Assert(basic_test_32bit("16407.9462890625", 16407.9462890625f));
|
Assert(basic_test_32bit("16407.9462890625", 16407.9462890625f));
|
||||||
Assert(basic_test_32bit("1.1754947011469036e-38", 0x1.000006p-126f));
|
Assert(basic_test_32bit("1.1754947011469036e-38", 0x1.000006p-126f));
|
||||||
Assert(basic_test_32bit("7.0064923216240854e-46", 0x1p-149f));
|
Assert(basic_test_32bit("7.0064923216240854e-46", 0x1p-149f));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user