59 Commits

Author SHA1 Message Date
Daniel Lemire
fda97168f0 casting to avoid warnings 2023-11-27 15:50:47 -05:00
Daniel Lemire
70d8e0ad0e In some cases, Visual Studio, when compiling 32-bit binaries, gets
0*something == -0 even when the 'something' is positive, when the system
is not set to compile to nearest.
2023-11-27 15:44:24 -05:00
Maya Warrier
ce562d9c65 Disallow inf/nan in json mode 2023-09-14 20:51:26 -04:00
Maya Warrier
6ede038789 Apply changes from benchmarked version
- Move parse_truncated_number_string back inside parse_number_string
2023-05-09 22:19:23 -04:00
Daniel Lemire
396a0fc2ae
Merge branch 'main' into main 2023-05-08 16:44:35 -04:00
Maya Warrier
4e7ae339d6 Implement intellisense fix 2023-05-07 00:38:10 -04:00
Maya Warrier
680ccc73ed Merge from upstream/main, fix conflicts 2023-05-01 20:27:29 -04:00
Maya Warrier
e08c55c380 Remove json parse rules/allow inf_nan 2023-05-01 19:45:50 -04:00
Maya Warrier
65bd922e38 Merge remote-tracking branch 'upstream/main'
- Fix conflicts
2023-04-26 16:47:42 -04:00
Maya Warrier
89fc24007a Clean up 2023-04-26 16:25:41 -04:00
Maya Warrier
653790b5f3 fixes 2023-04-16 00:36:52 -04:00
Maya Warrier
c849b7a8ff Option to forbid nan/inf, refactor 2023-04-15 23:16:01 -04:00
Pharago
2bfbe4ca96 cosmetic changes 2023-04-06 00:58:34 +02:00
Pharago
593709f056
Merge branch 'main' into main 2023-04-05 03:31:35 +02:00
Aras Pranckevičius
21fefa5b44
Fix warnings with -Wundef
- FASTFLOAT_ALLOWS_LEADING_PLUS and FASTFLOAT_SKIP_WHITE_SPACE are not defined by default, and compiling with -Wundef is emitting warnigns like "FASTFLOAT_ALLOWS_LEADING_PLUS is not defined, evaluates to 0".
- Likewise for FASTFLOAT_VISUAL_STUDIO, change checks to use #ifdef for that like in other places.
- __cpp_lib_bit_cast and __cpp_lib_is_constant_evaluated are not defined pre-C++20, and are emitting a warning too.
2023-04-04 21:18:57 +03:00
Pharago
bc77f956e2 Initial Unicode release
Added support for the other char types
2023-04-02 22:58:01 +02:00
Maya Warrier
2b118c843a Experimental support for char_t types 2023-03-30 04:48:18 -04:00
Adam Lugowski
bfee511d78 Set errc::result_out_of_range on over/underflow
Best-effort values are still returned, such as 0 for underflow and infinity for overflow, but now the returned ec is set to std::errc::result_out_of_range instead of std::errc().
2023-03-29 10:14:46 -07:00
Maya Warrier
3cafcca2ff Add support for json parsing rules and integers 2023-03-29 02:14:12 -04:00
Maya Warrier
8f94758c78 Expose parsed string (before computation) so it can be reused 2023-03-27 22:50:21 -04:00
Daniel Lemire
b50a729d93
Merge pull request #182 from leni536/constexpr-from_chars
Constexpr from_chars
2023-03-25 17:30:55 -04:00
Lenard Szolnoki
5b8290433c Fix clang workaround for parsing -0 on non-nearest rounding mode 2023-03-25 19:38:44 +00:00
filipecosta90
c8886eb31d Added missing FASTFLOAT_ALLOWS_LEADING_PLUS ifdef check in parse_infnan 2023-03-07 00:31:14 +00:00
Lenard Szolnoki
e4d4e43b21 Constexpr from_chars 2023-03-04 20:53:43 +00:00
Daniel Lemire
252a1c9dce Minor fix. 2023-02-06 17:22:11 -05:00
Daniel Lemire
3e2da540ef Support rccpfastfloat. 2023-01-19 20:28:10 -05:00
Joao Paulo Magalhaes
ca13367ff7 Suppress warning when comparing floats 2022-12-27 01:39:41 +00:00
Daniel Lemire
76537e1695 Fixing issue 154. 2022-11-25 15:58:54 -05:00
Daniel Lemire
003a983188 Simplifying the justification. 2022-11-18 15:38:21 -05:00
Daniel Lemire
8b7a55a03c Minor optimization. 2022-11-18 15:33:44 -05:00
Daniel Lemire
3d0e448940 Added a remark. 2022-11-18 12:27:38 -05:00
Daniel Lemire
39ea41b84a Adopting proposal. 2022-11-18 11:28:34 -05:00
Daniel Lemire
bfc0478feb More tweaks. 2022-11-16 16:45:01 -05:00
Daniel Lemire
fd9d9effda More tweaking around clangcl 2022-11-16 15:25:03 -05:00
Daniel Lemire
d225059873 Fix for Win32+ClangCL 2022-11-16 14:35:31 -05:00
Daniel Lemire
2c8e738950 Cleaning. 2022-11-16 12:06:33 -05:00
Daniel Lemire
6ceb29a7e4 We might reenable clinger. 2022-11-16 16:21:34 +00:00
Daniel Lemire
e958ff4269 Simplified clinger. 2022-11-03 18:51:37 -04:00
Daniel Lemire
d148241404 Removing CXX20 support 2021-09-20 09:49:23 -04:00
Alex Huszagh
fc0c8680a5 Implement the big-integer arithmetic algorithm.
Replaces the existing decimal implementation, for substantial
performance improvements with near-halfway cases. This is especially
fast with a large number of digits.

**Big Integer Implementation**

A small subset of big-integer arithmetic has been added, with the
`bigint` struct. It uses a stack-allocated vector with enough bits to
store the float with the large number of significant digits. This is
log2(10^(769 + 342)), to account for the largest possible magnitude
exponent, and number of digits (3600 bits), and then rounded up to 4k bits.

The limb size is determined by the architecture: most 64-bit
architectures have efficient 128-bit multiplication, either by a single
hardware instruction or 2 native multiplications for the high and low
bits. This includes x86_64, mips64, s390x, aarch64, powerpc64, riscv64,
and the only known exception is sparcv8 and sparcv9. Therefore, we
define a limb size of 64-bits on 64-bit architectures except SPARC,
otherwise we fallback to 32-bit limbs.

A simple stackvector is used, which just has operations to add elements,
index, and truncate the vector.

`bigint` is then just a wrapper around this, with methods for
big-integer arithmetic. For our algorithms, we just need multiplication
by a power (x * b^N), multiplication by a bigint or scalar value, and
addition by a bigint or scalar value. Scalar addition and multiplication
uses compiler extensions when possible (__builtin_add_overflow and
__uint128_t), if not, then we implement simple logic shown to optimize
well on MSVC. Big-integer multiplication is done via grade school
multiplication, which is more efficient than any asymptotically faster
algorithms. Multiplication by a power is then done via bitshifts for
powers-of-two, and by iterative multiplications of a large and then
scalar value for powers-of-5.

**compute_float**

Compute float has been slightly modified so if the algorithm cannot
round correctly, it returns a normalized, extended-precision adjusted
mantissa with the power2 shifted by INT16_MIN so the exponent is always
negative. `compute_error` and `compute_error_scaled` have been added.

**Digit Optimiations**

To improve performance for numbers with many digits,
`parse_eight_digits_unrolled` is used for both integers and fractions,
and uses a while loop than two nested if statements. This adds no
noticeable performance cost for common floats, but dramatically improves
performance for numbers with large digits (without these optimizations,
~65% of the total runtime cost is in parse_number_string).

**Parsed Number**

Two fields have been added to `parsed_number_string`, which contains a
slice of the integer and fraction digits. This is extremely cheap, since
the work is already done, and the strings are pre-tokenized during
parsing. This allows us on overflow to re-parse these tokenized strings,
without checking if each character is an integer. Likewise, for the
big-integer algorithms, we can merely re-parse the pre-tokenized
strings.

**Slow Algorithm**

The new algorithm is `digit_comp`, which takes the parsed number string
and the `adjusted_mantissa` from `compute_float`. The significant digits
are parsed into a big integer, and the exponent relative to the
significant digits is calculated. If the exponent is >= 0, we use
`positive_digit_comp`, otherwise, we use `negative_digit_comp`.

`positive_digit_comp` is quite simple: we scale the significant digits
to the exponent, and then we get the high 64-bits for the native float,
determine if any lower bits were truncated, and use that to direct
rounding.

`negative_digit_comp` is a little more complex, but also quite trivial:
we use the parsed significant digits as the real digits, and calculate
the theoretical digits from `b+h`, the halfway point between `b` and
`b+u`, the next-positive float. To get `b`, we round the adjusted
mantissa down, create an extended-precision representation, and
calculate the halfway point. We now have a base-10 exponent for the real
digits, and a base-2 exponent for the theoretical digits. We scale these
two to the same exponent by multiplying the theoretixal digits by
`5**-real_exp`. We then get the base-2 exponent as `theor_exp -
real_exp`, and if this is positive, we multipy the theoretical digits by
it, otherwise, we multiply the real digits by it. Now, both are scaled
to the same magnitude, and we simply compare the digits in the big
integer, and use that to direct rounding.

**Rust-Isms**

A few Rust-isms have been added, since it simplifies logic assertions.
These can be trivially removed or reworked, as needed.

- a `slice` type has been added, which is a pointer and length.
- `FASTFLOAT_ASSERT`, `FASTFLOAT_DEBUG_ASSERT`, and `FASTFLOAT_TRY` have
  been added
  - `FASTFLOAT_ASSERT` aborts, even in release builds, if the condition
    fails.
  - `FASTFLOAT_DEBUG_ASSERT` defaults to `assert`, for logic errors.
  - `FASTFLOAT_TRY` is like a Rust `Option` type, which propagates
    errors.

Specifically, `FASTFLOAT_TRY` is useful in combination with
`FASTFLOAT_ASSERT` to ensure there are no memory corruption errors
possible in the big-integer arithmetic. Although the `bigint` type
ensures we have enough storage for all valid floats, memory issues are
quite a severe class of vulnerabilities, and due to the low performance
cost of checks, we abort if we would have out-of-bounds writes. This can
only occur when we are adding items to the vector, which is a very small
number of steps. Therefore, we abort if our memory safety guarantees
ever fail. lexical has never aborted, so it's unlikely we will ever fail
these guarantees.
2021-09-10 18:53:53 -05:00
Jonas Rahlf
162a37b25a remove cstdio includes, remove cassert include, add asthetic newlines 2021-09-05 23:13:41 +02:00
Jonas Rahlf
d8ee88e7f6 initial version with working constexpr for c++20 compliant compilers 2021-09-01 00:52:25 +02:00
Antoine Pitrou
3881ea6937 Issue #90: accept custom decimal point 2021-08-03 10:44:24 +02:00
Marcin Wojdyr
f21b2f24cb change anonymous namespace to namespace detail (#54) 2021-04-07 15:17:37 +02:00
Eugene Golushkov
87e5a95585 Prevent fast_float::from_chars from parsing whitespaces and leading '+' sign, similar to MSVC and integer LLVM std::from_chars behavior. See C++17 20.19.3.(7.1) and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r5.html 2021-03-04 20:21:45 +02:00
Eugene Golushkov
76dec80fbd Parse "nan(n-char-seq-opt)" as required by C++17 20.19.3.7 and C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan), and according to https://reviews.llvm.org/D70631 MSVC implementation seems to became LLVM std::to_chars(). 2021-03-01 20:21:33 +02:00
Daniel Lemire
9d76b043c5 Minor typo. 2021-02-26 11:21:20 -05:00
Daniel Lemire
cad8cfdf57 Removing dead code. 2021-01-07 18:01:57 -05:00
Daniel Lemire
a27fcc230d This should be mostly correct. 2021-01-07 17:46:47 -05:00
Daniel Lemire
426dd2a4a6 Merge branch 'main' into dlemire/aqrit_magic 2020-11-23 13:48:06 -05:00