forked from OSchip/llvm-project
Revert "Microsoft's floating-point to_chars powered by Ryu and Ryu Printf"
This reverts commit a8025e06fc
since
it triggers PR52584 with debug info enabled.
This commit is contained in:
parent
2ccab2ecbf
commit
ae53d02f55
|
@ -12,9 +12,6 @@ N: Saleem Abdulrasool
|
|||
E: compnerd@compnerd.org
|
||||
D: Minor patches and Linux fixes.
|
||||
|
||||
N: Ulf Adams
|
||||
D: Invented the Ryu and Ryu Printf algorithms used in floating-point to_chars, and wrote the initial code.
|
||||
|
||||
N: Muiez Ahmed
|
||||
E: muiez@ibm.com
|
||||
D: z/OS port.
|
||||
|
@ -31,9 +28,6 @@ N: Holger Arnold
|
|||
E: holgerar@gmail.com
|
||||
D: Minor fix.
|
||||
|
||||
N: Jorg Brown
|
||||
D: Ported floating-point to_chars from MSVC to libc++.
|
||||
|
||||
N: David Chisnall
|
||||
E: theraven at theravensnest dot org
|
||||
D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.
|
||||
|
@ -87,14 +81,6 @@ N: Argyrios Kyrtzidis
|
|||
E: kyrtzidis@apple.com
|
||||
D: Bug fixes.
|
||||
|
||||
N: Stephan T. Lavavej
|
||||
E: stl@microsoft.com
|
||||
E: stl@nuwen.net
|
||||
D: Implemented floating-point to_chars.
|
||||
|
||||
N: Microsoft Corporation
|
||||
D: Contributed floating-point to_chars.
|
||||
|
||||
N: Bruce Mitchener, Jr.
|
||||
E: bruce.mitchener@gmail.com
|
||||
D: Emscripten-related changes.
|
||||
|
@ -166,7 +152,6 @@ D: Minor bug fix.
|
|||
N: Mark de Wever
|
||||
E: koraq at xs4all dot nl
|
||||
D: Format library support.
|
||||
D: Finalized the porting of MSVC's to_chars to libc++.
|
||||
|
||||
N: Zhang Xiongpang
|
||||
E: zhangxiongpang@gmail.com
|
||||
|
|
|
@ -55,10 +55,6 @@ New Features
|
|||
behavior of standard algorithms (e.g. equal elements in ``std::sort`` or
|
||||
randomization of both sides of partition for ``std::nth_element``)
|
||||
|
||||
- Floating-point support for ``std::to_chars`` support has been added.
|
||||
Thanks to Stephan T. Lavavej and Microsoft for providing their implemention
|
||||
to libc++.
|
||||
|
||||
API Changes
|
||||
-----------
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ Paper Status
|
|||
|
||||
.. note::
|
||||
|
||||
.. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``.
|
||||
.. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.
|
||||
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
"`P0394r4 <https://wg21.link/P0394r4>`__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","",""
|
||||
"","","","","",""
|
||||
"`P0003R5 <https://wg21.link/P0003R5>`__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0"
|
||||
"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial| [#note-P0067]",""
|
||||
"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial|",""
|
||||
"`P0403R1 <https://wg21.link/P0403R1>`__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0"
|
||||
"`P0414R2 <https://wg21.link/P0414R2>`__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0"
|
||||
"`P0418R2 <https://wg21.link/P0418R2>`__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","",""
|
||||
|
|
|
|
@ -129,10 +129,6 @@
|
|||
// This controls the availability of std::to_chars.
|
||||
# define _LIBCPP_AVAILABILITY_TO_CHARS
|
||||
|
||||
// This controls the availability of floating-point std::to_chars functions.
|
||||
// These overloads were added later than the integer overloads.
|
||||
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
|
||||
|
||||
// This controls the availability of the C++20 synchronization library,
|
||||
// which requires shared library support for various operations
|
||||
// (see libcxx/src/atomic.cpp).
|
||||
|
@ -226,9 +222,6 @@
|
|||
# define _LIBCPP_AVAILABILITY_TO_CHARS \
|
||||
_LIBCPP_AVAILABILITY_FILESYSTEM
|
||||
|
||||
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
|
||||
__attribute__((unavailable))
|
||||
|
||||
# define _LIBCPP_AVAILABILITY_SYNC \
|
||||
__attribute__((availability(macosx,strict,introduced=11.0))) \
|
||||
__attribute__((availability(ios,strict,introduced=14.0))) \
|
||||
|
|
|
@ -598,38 +598,6 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
|
|||
return __from_chars_integral(__first, __last, __value, __base);
|
||||
}
|
||||
|
||||
// Floating-point implementation starts here.
|
||||
// Unlike the other parts of charconv this is only available in C++17 and newer.
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
|
||||
|
||||
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
|
||||
|
||||
# endif // _LIBCPP_STD_VER > 14
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
|
@ -16,48 +16,6 @@ New entries should be added directly below the "Version" header.
|
|||
Version 14.0
|
||||
------------
|
||||
|
||||
* [libc++] `to_chars` for floating point.
|
||||
|
||||
This commit added the `to_chars` implementation for floating point values.
|
||||
The entire implementation resides in the dylib and the functions specified
|
||||
in the Standard are now part of the ABI.
|
||||
|
||||
arm64-apple-darwin
|
||||
------------------
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_d
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_e
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_f
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
|
||||
|
||||
x86_64-apple-darwin
|
||||
-------------------
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_d
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_e
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_f
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
|
||||
|
||||
x86_64-unknown-linux-gnu
|
||||
------------------------
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_d
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_e
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_f
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
|
||||
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
|
||||
|
||||
* [libc++] Resolve missing table_size symbol
|
||||
|
||||
This commit added an out-of-line definition for `table_size` in the library.
|
||||
|
|
|
@ -1879,15 +1879,6 @@
|
|||
{'is_defined': True, 'name': '__ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}
|
||||
|
|
|
@ -1879,15 +1879,6 @@
|
|||
{'is_defined': True, 'name': '__ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}
|
||||
|
|
|
@ -1573,15 +1573,6 @@
|
|||
{'is_defined': True, 'name': '_ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}
|
||||
|
|
|
@ -19,16 +19,6 @@ set(LIBCXX_SOURCES
|
|||
include/atomic_support.h
|
||||
include/config_elast.h
|
||||
include/refstring.h
|
||||
include/ryu/common.h
|
||||
include/ryu/d2fixed.h
|
||||
include/ryu/d2fixed_full_table.h
|
||||
include/ryu/d2s.h
|
||||
include/ryu/d2s_full_table.h
|
||||
include/ryu/d2s_intrinsics.h
|
||||
include/ryu/digit_table.h
|
||||
include/ryu/f2s.h
|
||||
include/ryu/ryu.h
|
||||
include/to_chars_floating_point.h
|
||||
legacy_pointer_safety.cpp
|
||||
memory.cpp
|
||||
mutex.cpp
|
||||
|
@ -36,9 +26,6 @@ set(LIBCXX_SOURCES
|
|||
new.cpp
|
||||
optional.cpp
|
||||
random_shuffle.cpp
|
||||
ryu/d2fixed.cpp
|
||||
ryu/d2s.cpp
|
||||
ryu/f2s.cpp
|
||||
shared_mutex.cpp
|
||||
stdexcept.cpp
|
||||
string.cpp
|
||||
|
|
|
@ -9,14 +9,27 @@
|
|||
#include "charconv"
|
||||
#include <string.h>
|
||||
|
||||
#include "include/ryu/digit_table.h"
|
||||
#include "include/to_chars_floating_point.h"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace __itoa
|
||||
{
|
||||
|
||||
static constexpr char cDigitsLut[200] = {
|
||||
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0',
|
||||
'7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',
|
||||
'1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2',
|
||||
'2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
|
||||
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3',
|
||||
'7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
|
||||
'4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5',
|
||||
'2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
|
||||
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
|
||||
'7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',
|
||||
'7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8',
|
||||
'2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
|
||||
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9',
|
||||
'7', '9', '8', '9', '9'};
|
||||
|
||||
template <typename T>
|
||||
inline _LIBCPP_INLINE_VISIBILITY char*
|
||||
append1(char* buffer, T i) noexcept
|
||||
|
@ -29,7 +42,7 @@ template <typename T>
|
|||
inline _LIBCPP_INLINE_VISIBILITY char*
|
||||
append2(char* buffer, T i) noexcept
|
||||
{
|
||||
memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2);
|
||||
memcpy(buffer, &cDigitsLut[(i)*2], 2);
|
||||
return buffer + 2;
|
||||
}
|
||||
|
||||
|
@ -144,53 +157,4 @@ __u64toa(uint64_t value, char* buffer) noexcept
|
|||
|
||||
} // namespace __itoa
|
||||
|
||||
// The original version of floating-point to_chars was written by Microsoft and
|
||||
// contributed with the following license.
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// This implementation is dedicated to the memory of Mary and Thavatchai.
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, static_cast<double>(__value),
|
||||
chars_format{}, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, static_cast<double>(__value),
|
||||
__fmt, 0);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt,
|
||||
__precision);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt,
|
||||
__precision);
|
||||
}
|
||||
|
||||
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision) {
|
||||
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(
|
||||
__first, __last, static_cast<double>(__value), __fmt, __precision);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_COMMON_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_COMMON_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __decimalLength9(const uint32_t __v) {
|
||||
// Function precondition: __v is not a 10-digit number.
|
||||
// (f2s: 9 digits are sufficient for round-tripping.)
|
||||
// (d2fixed: We print 9-digit blocks.)
|
||||
_LIBCPP_ASSERT(__v < 1000000000, "");
|
||||
if (__v >= 100000000) { return 9; }
|
||||
if (__v >= 10000000) { return 8; }
|
||||
if (__v >= 1000000) { return 7; }
|
||||
if (__v >= 100000) { return 6; }
|
||||
if (__v >= 10000) { return 5; }
|
||||
if (__v >= 1000) { return 4; }
|
||||
if (__v >= 100) { return 3; }
|
||||
if (__v >= 10) { return 2; }
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns __e == 0 ? 1 : ceil(log_2(5^__e)).
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline int32_t __pow5bits(const int32_t __e) {
|
||||
// This approximation works up to the point that the multiplication overflows at __e = 3529.
|
||||
// If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
|
||||
// than 2^9297.
|
||||
_LIBCPP_ASSERT(__e >= 0, "");
|
||||
_LIBCPP_ASSERT(__e <= 3528, "");
|
||||
return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1);
|
||||
}
|
||||
|
||||
// Returns floor(log_10(2^__e)).
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) {
|
||||
// The first value this approximation fails for is 2^1651 which is just greater than 10^297.
|
||||
_LIBCPP_ASSERT(__e >= 0, "");
|
||||
_LIBCPP_ASSERT(__e <= 1650, "");
|
||||
return (static_cast<uint32_t>(__e) * 78913) >> 18;
|
||||
}
|
||||
|
||||
// Returns floor(log_10(5^__e)).
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) {
|
||||
// The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
|
||||
_LIBCPP_ASSERT(__e >= 0, "");
|
||||
_LIBCPP_ASSERT(__e <= 2620, "");
|
||||
return (static_cast<uint32_t>(__e) * 732923) >> 20;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) {
|
||||
uint32_t __bits = 0;
|
||||
_VSTD::memcpy(&__bits, &__f, sizeof(float));
|
||||
return __bits;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) {
|
||||
uint64_t __bits = 0;
|
||||
_VSTD::memcpy(&__bits, &__d, sizeof(double));
|
||||
return __bits;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_COMMON_H
|
|
@ -1,60 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_D2FIXED_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_D2FIXED_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
#include "cstdint"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const __result);
|
||||
void __append_nine_digits(uint32_t __digits, char* const __result);
|
||||
|
||||
[[nodiscard]] to_chars_result __d2fixed_buffered_n(char* _First, char* const _Last, const double __d, const uint32_t __precision);
|
||||
[[nodiscard]] to_chars_result __d2exp_buffered_n(char* _First, char* const _Last, const double __d, uint32_t __precision);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_D2FIXED_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,62 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_DS2_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_DS2_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline constexpr int __DOUBLE_MANTISSA_BITS = 52;
|
||||
inline constexpr int __DOUBLE_EXPONENT_BITS = 11;
|
||||
inline constexpr int __DOUBLE_BIAS = 1023;
|
||||
|
||||
inline constexpr int __DOUBLE_POW5_INV_BITCOUNT = 122;
|
||||
inline constexpr int __DOUBLE_POW5_BITCOUNT = 121;
|
||||
|
||||
[[nodiscard]] to_chars_result __d2s_buffered_n(char* const _First, char* const _Last, const double __f, const chars_format _Fmt);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_DS2_H
|
|
@ -1,368 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_D2S_FULL_TABLE_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_D2S_FULL_TABLE_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline constexpr uint64_t __DOUBLE_POW5_INV_SPLIT[292][2] = {
|
||||
{ 1u, 288230376151711744u }, { 3689348814741910324u, 230584300921369395u },
|
||||
{ 2951479051793528259u, 184467440737095516u }, { 17118578500402463900u, 147573952589676412u },
|
||||
{ 12632330341676300947u, 236118324143482260u }, { 10105864273341040758u, 188894659314785808u },
|
||||
{ 15463389048156653253u, 151115727451828646u }, { 17362724847566824558u, 241785163922925834u },
|
||||
{ 17579528692795369969u, 193428131138340667u }, { 6684925324752475329u, 154742504910672534u },
|
||||
{ 18074578149087781173u, 247588007857076054u }, { 18149011334012135262u, 198070406285660843u },
|
||||
{ 3451162622983977240u, 158456325028528675u }, { 5521860196774363583u, 253530120045645880u },
|
||||
{ 4417488157419490867u, 202824096036516704u }, { 7223339340677503017u, 162259276829213363u },
|
||||
{ 7867994130342094503u, 259614842926741381u }, { 2605046489531765280u, 207691874341393105u },
|
||||
{ 2084037191625412224u, 166153499473114484u }, { 10713157136084480204u, 265845599156983174u },
|
||||
{ 12259874523609494487u, 212676479325586539u }, { 13497248433629505913u, 170141183460469231u },
|
||||
{ 14216899864323388813u, 272225893536750770u }, { 11373519891458711051u, 217780714829400616u },
|
||||
{ 5409467098425058518u, 174224571863520493u }, { 4965798542738183305u, 278759314981632789u },
|
||||
{ 7661987648932456967u, 223007451985306231u }, { 2440241304404055250u, 178405961588244985u },
|
||||
{ 3904386087046488400u, 285449538541191976u }, { 17880904128604832013u, 228359630832953580u },
|
||||
{ 14304723302883865611u, 182687704666362864u }, { 15133127457049002812u, 146150163733090291u },
|
||||
{ 16834306301794583852u, 233840261972944466u }, { 9778096226693756759u, 187072209578355573u },
|
||||
{ 15201174610838826053u, 149657767662684458u }, { 2185786488890659746u, 239452428260295134u },
|
||||
{ 5437978005854438120u, 191561942608236107u }, { 15418428848909281466u, 153249554086588885u },
|
||||
{ 6222742084545298729u, 245199286538542217u }, { 16046240111861969953u, 196159429230833773u },
|
||||
{ 1768945645263844993u, 156927543384667019u }, { 10209010661905972635u, 251084069415467230u },
|
||||
{ 8167208529524778108u, 200867255532373784u }, { 10223115638361732810u, 160693804425899027u },
|
||||
{ 1599589762411131202u, 257110087081438444u }, { 4969020624670815285u, 205688069665150755u },
|
||||
{ 3975216499736652228u, 164550455732120604u }, { 13739044029062464211u, 263280729171392966u },
|
||||
{ 7301886408508061046u, 210624583337114373u }, { 13220206756290269483u, 168499666669691498u },
|
||||
{ 17462981995322520850u, 269599466671506397u }, { 6591687966774196033u, 215679573337205118u },
|
||||
{ 12652048002903177473u, 172543658669764094u }, { 9175230360419352987u, 276069853871622551u },
|
||||
{ 3650835473593572067u, 220855883097298041u }, { 17678063637842498946u, 176684706477838432u },
|
||||
{ 13527506561580357021u, 282695530364541492u }, { 3443307619780464970u, 226156424291633194u },
|
||||
{ 6443994910566282300u, 180925139433306555u }, { 5155195928453025840u, 144740111546645244u },
|
||||
{ 15627011115008661990u, 231584178474632390u }, { 12501608892006929592u, 185267342779705912u },
|
||||
{ 2622589484121723027u, 148213874223764730u }, { 4196143174594756843u, 237142198758023568u },
|
||||
{ 10735612169159626121u, 189713759006418854u }, { 12277838550069611220u, 151771007205135083u },
|
||||
{ 15955192865369467629u, 242833611528216133u }, { 1696107848069843133u, 194266889222572907u },
|
||||
{ 12424932722681605476u, 155413511378058325u }, { 1433148282581017146u, 248661618204893321u },
|
||||
{ 15903913885032455010u, 198929294563914656u }, { 9033782293284053685u, 159143435651131725u },
|
||||
{ 14454051669254485895u, 254629497041810760u }, { 11563241335403588716u, 203703597633448608u },
|
||||
{ 16629290697806691620u, 162962878106758886u }, { 781423413297334329u, 260740604970814219u },
|
||||
{ 4314487545379777786u, 208592483976651375u }, { 3451590036303822229u, 166873987181321100u },
|
||||
{ 5522544058086115566u, 266998379490113760u }, { 4418035246468892453u, 213598703592091008u },
|
||||
{ 10913125826658934609u, 170878962873672806u }, { 10082303693170474728u, 273406340597876490u },
|
||||
{ 8065842954536379782u, 218725072478301192u }, { 17520720807854834795u, 174980057982640953u },
|
||||
{ 5897060404116273733u, 279968092772225526u }, { 1028299508551108663u, 223974474217780421u },
|
||||
{ 15580034865808528224u, 179179579374224336u }, { 17549358155809824511u, 286687326998758938u },
|
||||
{ 2971440080422128639u, 229349861599007151u }, { 17134547323305344204u, 183479889279205720u },
|
||||
{ 13707637858644275364u, 146783911423364576u }, { 14553522944347019935u, 234854258277383322u },
|
||||
{ 4264120725993795302u, 187883406621906658u }, { 10789994210278856888u, 150306725297525326u },
|
||||
{ 9885293106962350374u, 240490760476040522u }, { 529536856086059653u, 192392608380832418u },
|
||||
{ 7802327114352668369u, 153914086704665934u }, { 1415676938738538420u, 246262538727465495u },
|
||||
{ 1132541550990830736u, 197010030981972396u }, { 15663428499760305882u, 157608024785577916u },
|
||||
{ 17682787970132668764u, 252172839656924666u }, { 10456881561364224688u, 201738271725539733u },
|
||||
{ 15744202878575200397u, 161390617380431786u }, { 17812026976236499989u, 258224987808690858u },
|
||||
{ 3181575136763469022u, 206579990246952687u }, { 13613306553636506187u, 165263992197562149u },
|
||||
{ 10713244041592678929u, 264422387516099439u }, { 12259944048016053467u, 211537910012879551u },
|
||||
{ 6118606423670932450u, 169230328010303641u }, { 2411072648389671274u, 270768524816485826u },
|
||||
{ 16686253377679378312u, 216614819853188660u }, { 13349002702143502650u, 173291855882550928u },
|
||||
{ 17669055508687693916u, 277266969412081485u }, { 14135244406950155133u, 221813575529665188u },
|
||||
{ 240149081334393137u, 177450860423732151u }, { 11452284974360759988u, 283921376677971441u },
|
||||
{ 5472479164746697667u, 227137101342377153u }, { 11756680961281178780u, 181709681073901722u },
|
||||
{ 2026647139541122378u, 145367744859121378u }, { 18000030682233437097u, 232588391774594204u },
|
||||
{ 18089373360528660001u, 186070713419675363u }, { 3403452244197197031u, 148856570735740291u },
|
||||
{ 16513570034941246220u, 238170513177184465u }, { 13210856027952996976u, 190536410541747572u },
|
||||
{ 3189987192878576934u, 152429128433398058u }, { 1414630693863812771u, 243886605493436893u },
|
||||
{ 8510402184574870864u, 195109284394749514u }, { 10497670562401807014u, 156087427515799611u },
|
||||
{ 9417575270359070576u, 249739884025279378u }, { 14912757845771077107u, 199791907220223502u },
|
||||
{ 4551508647133041040u, 159833525776178802u }, { 10971762650154775986u, 255733641241886083u },
|
||||
{ 16156107749607641435u, 204586912993508866u }, { 9235537384944202825u, 163669530394807093u },
|
||||
{ 11087511001168814197u, 261871248631691349u }, { 12559357615676961681u, 209496998905353079u },
|
||||
{ 13736834907283479668u, 167597599124282463u }, { 18289587036911657145u, 268156158598851941u },
|
||||
{ 10942320814787415393u, 214524926879081553u }, { 16132554281313752961u, 171619941503265242u },
|
||||
{ 11054691591134363444u, 274591906405224388u }, { 16222450902391311402u, 219673525124179510u },
|
||||
{ 12977960721913049122u, 175738820099343608u }, { 17075388340318968271u, 281182112158949773u },
|
||||
{ 2592264228029443648u, 224945689727159819u }, { 5763160197165465241u, 179956551781727855u },
|
||||
{ 9221056315464744386u, 287930482850764568u }, { 14755542681855616155u, 230344386280611654u },
|
||||
{ 15493782960226403247u, 184275509024489323u }, { 1326979923955391628u, 147420407219591459u },
|
||||
{ 9501865507812447252u, 235872651551346334u }, { 11290841220991868125u, 188698121241077067u },
|
||||
{ 1653975347309673853u, 150958496992861654u }, { 10025058185179298811u, 241533595188578646u },
|
||||
{ 4330697733401528726u, 193226876150862917u }, { 14532604630946953951u, 154581500920690333u },
|
||||
{ 1116074521063664381u, 247330401473104534u }, { 4582208431592841828u, 197864321178483627u },
|
||||
{ 14733813189500004432u, 158291456942786901u }, { 16195403473716186445u, 253266331108459042u },
|
||||
{ 5577625149489128510u, 202613064886767234u }, { 8151448934333213131u, 162090451909413787u },
|
||||
{ 16731667109675051333u, 259344723055062059u }, { 17074682502481951390u, 207475778444049647u },
|
||||
{ 6281048372501740465u, 165980622755239718u }, { 6360328581260874421u, 265568996408383549u },
|
||||
{ 8777611679750609860u, 212455197126706839u }, { 10711438158542398211u, 169964157701365471u },
|
||||
{ 9759603424184016492u, 271942652322184754u }, { 11497031554089123517u, 217554121857747803u },
|
||||
{ 16576322872755119460u, 174043297486198242u }, { 11764721337440549842u, 278469275977917188u },
|
||||
{ 16790474699436260520u, 222775420782333750u }, { 13432379759549008416u, 178220336625867000u },
|
||||
{ 3045063541568861850u, 285152538601387201u }, { 17193446092222730773u, 228122030881109760u },
|
||||
{ 13754756873778184618u, 182497624704887808u }, { 18382503128506368341u, 145998099763910246u },
|
||||
{ 3586563302416817083u, 233596959622256395u }, { 2869250641933453667u, 186877567697805116u },
|
||||
{ 17052795772514404226u, 149502054158244092u }, { 12527077977055405469u, 239203286653190548u },
|
||||
{ 17400360011128145022u, 191362629322552438u }, { 2852241564676785048u, 153090103458041951u },
|
||||
{ 15631632947708587046u, 244944165532867121u }, { 8815957543424959314u, 195955332426293697u },
|
||||
{ 18120812478965698421u, 156764265941034957u }, { 14235904707377476180u, 250822825505655932u },
|
||||
{ 4010026136418160298u, 200658260404524746u }, { 17965416168102169531u, 160526608323619796u },
|
||||
{ 2919224165770098987u, 256842573317791675u }, { 2335379332616079190u, 205474058654233340u },
|
||||
{ 1868303466092863352u, 164379246923386672u }, { 6678634360490491686u, 263006795077418675u },
|
||||
{ 5342907488392393349u, 210405436061934940u }, { 4274325990713914679u, 168324348849547952u },
|
||||
{ 10528270399884173809u, 269318958159276723u }, { 15801313949391159694u, 215455166527421378u },
|
||||
{ 1573004715287196786u, 172364133221937103u }, { 17274202803427156150u, 275782613155099364u },
|
||||
{ 17508711057483635243u, 220626090524079491u }, { 10317620031244997871u, 176500872419263593u },
|
||||
{ 12818843235250086271u, 282401395870821749u }, { 13944423402941979340u, 225921116696657399u },
|
||||
{ 14844887537095493795u, 180736893357325919u }, { 15565258844418305359u, 144589514685860735u },
|
||||
{ 6457670077359736959u, 231343223497377177u }, { 16234182506113520537u, 185074578797901741u },
|
||||
{ 9297997190148906106u, 148059663038321393u }, { 11187446689496339446u, 236895460861314229u },
|
||||
{ 12639306166338981880u, 189516368689051383u }, { 17490142562555006151u, 151613094951241106u },
|
||||
{ 2158786396894637579u, 242580951921985771u }, { 16484424376483351356u, 194064761537588616u },
|
||||
{ 9498190686444770762u, 155251809230070893u }, { 11507756283569722895u, 248402894768113429u },
|
||||
{ 12895553841597688639u, 198722315814490743u }, { 17695140702761971558u, 158977852651592594u },
|
||||
{ 17244178680193423523u, 254364564242548151u }, { 10105994129412828495u, 203491651394038521u },
|
||||
{ 4395446488788352473u, 162793321115230817u }, { 10722063196803274280u, 260469313784369307u },
|
||||
{ 1198952927958798777u, 208375451027495446u }, { 15716557601334680315u, 166700360821996356u },
|
||||
{ 17767794532651667857u, 266720577315194170u }, { 14214235626121334286u, 213376461852155336u },
|
||||
{ 7682039686155157106u, 170701169481724269u }, { 1223217053622520399u, 273121871170758831u },
|
||||
{ 15735968901865657612u, 218497496936607064u }, { 16278123936234436413u, 174797997549285651u },
|
||||
{ 219556594781725998u, 279676796078857043u }, { 7554342905309201445u, 223741436863085634u },
|
||||
{ 9732823138989271479u, 178993149490468507u }, { 815121763415193074u, 286389039184749612u },
|
||||
{ 11720143854957885429u, 229111231347799689u }, { 13065463898708218666u, 183288985078239751u },
|
||||
{ 6763022304224664610u, 146631188062591801u }, { 3442138057275642729u, 234609900900146882u },
|
||||
{ 13821756890046245153u, 187687920720117505u }, { 11057405512036996122u, 150150336576094004u },
|
||||
{ 6623802375033462826u, 240240538521750407u }, { 16367088344252501231u, 192192430817400325u },
|
||||
{ 13093670675402000985u, 153753944653920260u }, { 2503129006933649959u, 246006311446272417u },
|
||||
{ 13070549649772650937u, 196805049157017933u }, { 17835137349301941396u, 157444039325614346u },
|
||||
{ 2710778055689733971u, 251910462920982955u }, { 2168622444551787177u, 201528370336786364u },
|
||||
{ 5424246770383340065u, 161222696269429091u }, { 1300097203129523457u, 257956314031086546u },
|
||||
{ 15797473021471260058u, 206365051224869236u }, { 8948629602435097724u, 165092040979895389u },
|
||||
{ 3249760919670425388u, 264147265567832623u }, { 9978506365220160957u, 211317812454266098u },
|
||||
{ 15361502721659949412u, 169054249963412878u }, { 2442311466204457120u, 270486799941460606u },
|
||||
{ 16711244431931206989u, 216389439953168484u }, { 17058344360286875914u, 173111551962534787u },
|
||||
{ 12535955717491360170u, 276978483140055660u }, { 10028764573993088136u, 221582786512044528u },
|
||||
{ 15401709288678291155u, 177266229209635622u }, { 9885339602917624555u, 283625966735416996u },
|
||||
{ 4218922867592189321u, 226900773388333597u }, { 14443184738299482427u, 181520618710666877u },
|
||||
{ 4175850161155765295u, 145216494968533502u }, { 10370709072591134795u, 232346391949653603u },
|
||||
{ 15675264887556728482u, 185877113559722882u }, { 5161514280561562140u, 148701690847778306u },
|
||||
{ 879725219414678777u, 237922705356445290u }, { 703780175531743021u, 190338164285156232u },
|
||||
{ 11631070584651125387u, 152270531428124985u }, { 162968861732249003u, 243632850284999977u },
|
||||
{ 11198421533611530172u, 194906280227999981u }, { 5269388412147313814u, 155925024182399985u },
|
||||
{ 8431021459435702103u, 249480038691839976u }, { 3055468352806651359u, 199584030953471981u },
|
||||
{ 17201769941212962380u, 159667224762777584u }, { 16454785461715008838u, 255467559620444135u },
|
||||
{ 13163828369372007071u, 204374047696355308u }, { 17909760324981426303u, 163499238157084246u },
|
||||
{ 2830174816776909822u, 261598781051334795u }, { 2264139853421527858u, 209279024841067836u },
|
||||
{ 16568707141704863579u, 167423219872854268u }, { 4373838538276319787u, 267877151796566830u },
|
||||
{ 3499070830621055830u, 214301721437253464u }, { 6488605479238754987u, 171441377149802771u },
|
||||
{ 3003071137298187333u, 274306203439684434u }, { 6091805724580460189u, 219444962751747547u },
|
||||
{ 15941491023890099121u, 175555970201398037u }, { 10748990379256517301u, 280889552322236860u },
|
||||
{ 8599192303405213841u, 224711641857789488u }, { 14258051472207991719u, 179769313486231590u }
|
||||
};
|
||||
|
||||
inline constexpr uint64_t __DOUBLE_POW5_SPLIT[326][2] = {
|
||||
{ 0u, 72057594037927936u }, { 0u, 90071992547409920u },
|
||||
{ 0u, 112589990684262400u }, { 0u, 140737488355328000u },
|
||||
{ 0u, 87960930222080000u }, { 0u, 109951162777600000u },
|
||||
{ 0u, 137438953472000000u }, { 0u, 85899345920000000u },
|
||||
{ 0u, 107374182400000000u }, { 0u, 134217728000000000u },
|
||||
{ 0u, 83886080000000000u }, { 0u, 104857600000000000u },
|
||||
{ 0u, 131072000000000000u }, { 0u, 81920000000000000u },
|
||||
{ 0u, 102400000000000000u }, { 0u, 128000000000000000u },
|
||||
{ 0u, 80000000000000000u }, { 0u, 100000000000000000u },
|
||||
{ 0u, 125000000000000000u }, { 0u, 78125000000000000u },
|
||||
{ 0u, 97656250000000000u }, { 0u, 122070312500000000u },
|
||||
{ 0u, 76293945312500000u }, { 0u, 95367431640625000u },
|
||||
{ 0u, 119209289550781250u }, { 4611686018427387904u, 74505805969238281u },
|
||||
{ 10376293541461622784u, 93132257461547851u }, { 8358680908399640576u, 116415321826934814u },
|
||||
{ 612489549322387456u, 72759576141834259u }, { 14600669991935148032u, 90949470177292823u },
|
||||
{ 13639151471491547136u, 113686837721616029u }, { 3213881284082270208u, 142108547152020037u },
|
||||
{ 4314518811765112832u, 88817841970012523u }, { 781462496279003136u, 111022302462515654u },
|
||||
{ 10200200157203529728u, 138777878078144567u }, { 13292654125893287936u, 86736173798840354u },
|
||||
{ 7392445620511834112u, 108420217248550443u }, { 4628871007212404736u, 135525271560688054u },
|
||||
{ 16728102434789916672u, 84703294725430033u }, { 7075069988205232128u, 105879118406787542u },
|
||||
{ 18067209522111315968u, 132348898008484427u }, { 8986162942105878528u, 82718061255302767u },
|
||||
{ 6621017659204960256u, 103397576569128459u }, { 3664586055578812416u, 129246970711410574u },
|
||||
{ 16125424340018921472u, 80779356694631608u }, { 1710036351314100224u, 100974195868289511u },
|
||||
{ 15972603494424788992u, 126217744835361888u }, { 9982877184015493120u, 78886090522101180u },
|
||||
{ 12478596480019366400u, 98607613152626475u }, { 10986559581596820096u, 123259516440783094u },
|
||||
{ 2254913720070624656u, 77037197775489434u }, { 12042014186943056628u, 96296497219361792u },
|
||||
{ 15052517733678820785u, 120370621524202240u }, { 9407823583549262990u, 75231638452626400u },
|
||||
{ 11759779479436578738u, 94039548065783000u }, { 14699724349295723422u, 117549435082228750u },
|
||||
{ 4575641699882439235u, 73468396926392969u }, { 10331238143280436948u, 91835496157991211u },
|
||||
{ 8302361660673158281u, 114794370197489014u }, { 1154580038986672043u, 143492962746861268u },
|
||||
{ 9944984561221445835u, 89683101716788292u }, { 12431230701526807293u, 112103877145985365u },
|
||||
{ 1703980321626345405u, 140129846432481707u }, { 17205888765512323542u, 87581154020301066u },
|
||||
{ 12283988920035628619u, 109476442525376333u }, { 1519928094762372062u, 136845553156720417u },
|
||||
{ 12479170105294952299u, 85528470722950260u }, { 15598962631618690374u, 106910588403687825u },
|
||||
{ 5663645234241199255u, 133638235504609782u }, { 17374836326682913246u, 83523897190381113u },
|
||||
{ 7883487353071477846u, 104404871487976392u }, { 9854359191339347308u, 130506089359970490u },
|
||||
{ 10770660513014479971u, 81566305849981556u }, { 13463325641268099964u, 101957882312476945u },
|
||||
{ 2994098996302961243u, 127447352890596182u }, { 15706369927971514489u, 79654595556622613u },
|
||||
{ 5797904354682229399u, 99568244445778267u }, { 2635694424925398845u, 124460305557222834u },
|
||||
{ 6258995034005762182u, 77787690973264271u }, { 3212057774079814824u, 97234613716580339u },
|
||||
{ 17850130272881932242u, 121543267145725423u }, { 18073860448192289507u, 75964541966078389u },
|
||||
{ 8757267504958198172u, 94955677457597987u }, { 6334898362770359811u, 118694596821997484u },
|
||||
{ 13182683513586250689u, 74184123013748427u }, { 11866668373555425458u, 92730153767185534u },
|
||||
{ 5609963430089506015u, 115912692208981918u }, { 17341285199088104971u, 72445432630613698u },
|
||||
{ 12453234462005355406u, 90556790788267123u }, { 10954857059079306353u, 113195988485333904u },
|
||||
{ 13693571323849132942u, 141494985606667380u }, { 17781854114260483896u, 88434366004167112u },
|
||||
{ 3780573569116053255u, 110542957505208891u }, { 114030942967678664u, 138178696881511114u },
|
||||
{ 4682955357782187069u, 86361685550944446u }, { 15077066234082509644u, 107952106938680557u },
|
||||
{ 5011274737320973344u, 134940133673350697u }, { 14661261756894078100u, 84337583545844185u },
|
||||
{ 4491519140835433913u, 105421979432305232u }, { 5614398926044292391u, 131777474290381540u },
|
||||
{ 12732371365632458552u, 82360921431488462u }, { 6692092170185797382u, 102951151789360578u },
|
||||
{ 17588487249587022536u, 128688939736700722u }, { 15604490549419276989u, 80430587335437951u },
|
||||
{ 14893927168346708332u, 100538234169297439u }, { 14005722942005997511u, 125672792711621799u },
|
||||
{ 15671105866394830300u, 78545495444763624u }, { 1142138259283986260u, 98181869305954531u },
|
||||
{ 15262730879387146537u, 122727336632443163u }, { 7233363790403272633u, 76704585395276977u },
|
||||
{ 13653390756431478696u, 95880731744096221u }, { 3231680390257184658u, 119850914680120277u },
|
||||
{ 4325643253124434363u, 74906821675075173u }, { 10018740084832930858u, 93633527093843966u },
|
||||
{ 3300053069186387764u, 117041908867304958u }, { 15897591223523656064u, 73151193042065598u },
|
||||
{ 10648616992549794273u, 91438991302581998u }, { 4087399203832467033u, 114298739128227498u },
|
||||
{ 14332621041645359599u, 142873423910284372u }, { 18181260187883125557u, 89295889943927732u },
|
||||
{ 4279831161144355331u, 111619862429909666u }, { 14573160988285219972u, 139524828037387082u },
|
||||
{ 13719911636105650386u, 87203017523366926u }, { 7926517508277287175u, 109003771904208658u },
|
||||
{ 684774848491833161u, 136254714880260823u }, { 7345513307948477581u, 85159196800163014u },
|
||||
{ 18405263671790372785u, 106448996000203767u }, { 18394893571310578077u, 133061245000254709u },
|
||||
{ 13802651491282805250u, 83163278125159193u }, { 3418256308821342851u, 103954097656448992u },
|
||||
{ 4272820386026678563u, 129942622070561240u }, { 2670512741266674102u, 81214138794100775u },
|
||||
{ 17173198981865506339u, 101517673492625968u }, { 3019754653622331308u, 126897091865782461u },
|
||||
{ 4193189667727651020u, 79310682416114038u }, { 14464859121514339583u, 99138353020142547u },
|
||||
{ 13469387883465536574u, 123922941275178184u }, { 8418367427165960359u, 77451838296986365u },
|
||||
{ 15134645302384838353u, 96814797871232956u }, { 471562554271496325u, 121018497339041196u },
|
||||
{ 9518098633274461011u, 75636560836900747u }, { 7285937273165688360u, 94545701046125934u },
|
||||
{ 18330793628311886258u, 118182126307657417u }, { 4539216990053847055u, 73863828942285886u },
|
||||
{ 14897393274422084627u, 92329786177857357u }, { 4786683537745442072u, 115412232722321697u },
|
||||
{ 14520892257159371055u, 72132645451451060u }, { 18151115321449213818u, 90165806814313825u },
|
||||
{ 8853836096529353561u, 112707258517892282u }, { 1843923083806916143u, 140884073147365353u },
|
||||
{ 12681666973447792349u, 88052545717103345u }, { 2017025661527576725u, 110065682146379182u },
|
||||
{ 11744654113764246714u, 137582102682973977u }, { 422879793461572340u, 85988814176858736u },
|
||||
{ 528599741826965425u, 107486017721073420u }, { 660749677283706782u, 134357522151341775u },
|
||||
{ 7330497575943398595u, 83973451344588609u }, { 13774807988356636147u, 104966814180735761u },
|
||||
{ 3383451930163631472u, 131208517725919702u }, { 15949715511634433382u, 82005323578699813u },
|
||||
{ 6102086334260878016u, 102506654473374767u }, { 3015921899398709616u, 128133318091718459u },
|
||||
{ 18025852251620051174u, 80083323807324036u }, { 4085571240815512351u, 100104154759155046u },
|
||||
{ 14330336087874166247u, 125130193448943807u }, { 15873989082562435760u, 78206370905589879u },
|
||||
{ 15230800334775656796u, 97757963631987349u }, { 5203442363187407284u, 122197454539984187u },
|
||||
{ 946308467778435600u, 76373409087490117u }, { 5794571603150432404u, 95466761359362646u },
|
||||
{ 16466586540792816313u, 119333451699203307u }, { 7985773578781816244u, 74583407312002067u },
|
||||
{ 5370530955049882401u, 93229259140002584u }, { 6713163693812353001u, 116536573925003230u },
|
||||
{ 18030785363914884337u, 72835358703127018u }, { 13315109668038829614u, 91044198378908773u },
|
||||
{ 2808829029766373305u, 113805247973635967u }, { 17346094342490130344u, 142256559967044958u },
|
||||
{ 6229622945628943561u, 88910349979403099u }, { 3175342663608791547u, 111137937474253874u },
|
||||
{ 13192550366365765242u, 138922421842817342u }, { 3633657960551215372u, 86826513651760839u },
|
||||
{ 18377130505971182927u, 108533142064701048u }, { 4524669058754427043u, 135666427580876311u },
|
||||
{ 9745447189362598758u, 84791517238047694u }, { 2958436949848472639u, 105989396547559618u },
|
||||
{ 12921418224165366607u, 132486745684449522u }, { 12687572408530742033u, 82804216052780951u },
|
||||
{ 11247779492236039638u, 103505270065976189u }, { 224666310012885835u, 129381587582470237u },
|
||||
{ 2446259452971747599u, 80863492239043898u }, { 12281196353069460307u, 101079365298804872u },
|
||||
{ 15351495441336825384u, 126349206623506090u }, { 14206370669262903769u, 78968254139691306u },
|
||||
{ 8534591299723853903u, 98710317674614133u }, { 15279925143082205283u, 123387897093267666u },
|
||||
{ 14161639232853766206u, 77117435683292291u }, { 13090363022639819853u, 96396794604115364u },
|
||||
{ 16362953778299774816u, 120495993255144205u }, { 12532689120651053212u, 75309995784465128u },
|
||||
{ 15665861400813816515u, 94137494730581410u }, { 10358954714162494836u, 117671868413226763u },
|
||||
{ 4168503687137865320u, 73544917758266727u }, { 598943590494943747u, 91931147197833409u },
|
||||
{ 5360365506546067587u, 114913933997291761u }, { 11312142901609972388u, 143642417496614701u },
|
||||
{ 9375932322719926695u, 89776510935384188u }, { 11719915403399908368u, 112220638669230235u },
|
||||
{ 10038208235822497557u, 140275798336537794u }, { 10885566165816448877u, 87672373960336121u },
|
||||
{ 18218643725697949000u, 109590467450420151u }, { 18161618638695048346u, 136988084313025189u },
|
||||
{ 13656854658398099168u, 85617552695640743u }, { 12459382304570236056u, 107021940869550929u },
|
||||
{ 1739169825430631358u, 133777426086938662u }, { 14922039196176308311u, 83610891304336663u },
|
||||
{ 14040862976792997485u, 104513614130420829u }, { 3716020665709083144u, 130642017663026037u },
|
||||
{ 4628355925281870917u, 81651261039391273u }, { 10397130925029726550u, 102064076299239091u },
|
||||
{ 8384727637859770284u, 127580095374048864u }, { 5240454773662356427u, 79737559608780540u },
|
||||
{ 6550568467077945534u, 99671949510975675u }, { 3576524565420044014u, 124589936888719594u },
|
||||
{ 6847013871814915412u, 77868710555449746u }, { 17782139376623420074u, 97335888194312182u },
|
||||
{ 13004302183924499284u, 121669860242890228u }, { 17351060901807587860u, 76043662651806392u },
|
||||
{ 3242082053549933210u, 95054578314757991u }, { 17887660622219580224u, 118818222893447488u },
|
||||
{ 11179787888887237640u, 74261389308404680u }, { 13974734861109047050u, 92826736635505850u },
|
||||
{ 8245046539531533005u, 116033420794382313u }, { 16682369133275677888u, 72520887996488945u },
|
||||
{ 7017903361312433648u, 90651109995611182u }, { 17995751238495317868u, 113313887494513977u },
|
||||
{ 8659630992836983623u, 141642359368142472u }, { 5412269370523114764u, 88526474605089045u },
|
||||
{ 11377022731581281359u, 110658093256361306u }, { 4997906377621825891u, 138322616570451633u },
|
||||
{ 14652906532082110942u, 86451635356532270u }, { 9092761128247862869u, 108064544195665338u },
|
||||
{ 2142579373455052779u, 135080680244581673u }, { 12868327154477877747u, 84425425152863545u },
|
||||
{ 2250350887815183471u, 105531781441079432u }, { 2812938609768979339u, 131914726801349290u },
|
||||
{ 6369772649532999991u, 82446704250843306u }, { 17185587848771025797u, 103058380313554132u },
|
||||
{ 3035240737254230630u, 128822975391942666u }, { 6508711479211282048u, 80514359619964166u },
|
||||
{ 17359261385868878368u, 100642949524955207u }, { 17087390713908710056u, 125803686906194009u },
|
||||
{ 3762090168551861929u, 78627304316371256u }, { 4702612710689827411u, 98284130395464070u },
|
||||
{ 15101637925217060072u, 122855162994330087u }, { 16356052730901744401u, 76784476871456304u },
|
||||
{ 1998321839917628885u, 95980596089320381u }, { 7109588318324424010u, 119975745111650476u },
|
||||
{ 13666864735807540814u, 74984840694781547u }, { 12471894901332038114u, 93731050868476934u },
|
||||
{ 6366496589810271835u, 117163813585596168u }, { 3979060368631419896u, 73227383490997605u },
|
||||
{ 9585511479216662775u, 91534229363747006u }, { 2758517312166052660u, 114417786704683758u },
|
||||
{ 12671518677062341634u, 143022233380854697u }, { 1002170145522881665u, 89388895863034186u },
|
||||
{ 10476084718758377889u, 111736119828792732u }, { 13095105898447972362u, 139670149785990915u },
|
||||
{ 5878598177316288774u, 87293843616244322u }, { 16571619758500136775u, 109117304520305402u },
|
||||
{ 11491152661270395161u, 136396630650381753u }, { 264441385652915120u, 85247894156488596u },
|
||||
{ 330551732066143900u, 106559867695610745u }, { 5024875683510067779u, 133199834619513431u },
|
||||
{ 10058076329834874218u, 83249896637195894u }, { 3349223375438816964u, 104062370796494868u },
|
||||
{ 4186529219298521205u, 130077963495618585u }, { 14145795808130045513u, 81298727184761615u },
|
||||
{ 13070558741735168987u, 101623408980952019u }, { 11726512408741573330u, 127029261226190024u },
|
||||
{ 7329070255463483331u, 79393288266368765u }, { 13773023837756742068u, 99241610332960956u },
|
||||
{ 17216279797195927585u, 124052012916201195u }, { 8454331864033760789u, 77532508072625747u },
|
||||
{ 5956228811614813082u, 96915635090782184u }, { 7445286014518516353u, 121144543863477730u },
|
||||
{ 9264989777501460624u, 75715339914673581u }, { 16192923240304213684u, 94644174893341976u },
|
||||
{ 1794409976670715490u, 118305218616677471u }, { 8039035263060279037u, 73940761635423419u },
|
||||
{ 5437108060397960892u, 92425952044279274u }, { 16019757112352226923u, 115532440055349092u },
|
||||
{ 788976158365366019u, 72207775034593183u }, { 14821278253238871236u, 90259718793241478u },
|
||||
{ 9303225779693813237u, 112824648491551848u }, { 11629032224617266546u, 141030810614439810u },
|
||||
{ 11879831158813179495u, 88144256634024881u }, { 1014730893234310657u, 110180320792531102u },
|
||||
{ 10491785653397664129u, 137725400990663877u }, { 8863209042587234033u, 86078375619164923u },
|
||||
{ 6467325284806654637u, 107597969523956154u }, { 17307528642863094104u, 134497461904945192u },
|
||||
{ 10817205401789433815u, 84060913690590745u }, { 18133192770664180173u, 105076142113238431u },
|
||||
{ 18054804944902837312u, 131345177641548039u }, { 18201782118205355176u, 82090736025967524u },
|
||||
{ 4305483574047142354u, 102613420032459406u }, { 14605226504413703751u, 128266775040574257u },
|
||||
{ 2210737537617482988u, 80166734400358911u }, { 16598479977304017447u, 100208418000448638u },
|
||||
{ 11524727934775246001u, 125260522500560798u }, { 2591268940807140847u, 78287826562850499u },
|
||||
{ 17074144231291089770u, 97859783203563123u }, { 16730994270686474309u, 122324729004453904u },
|
||||
{ 10456871419179046443u, 76452955627783690u }, { 3847717237119032246u, 95566194534729613u },
|
||||
{ 9421332564826178211u, 119457743168412016u }, { 5888332853016361382u, 74661089480257510u },
|
||||
{ 16583788103125227536u, 93326361850321887u }, { 16118049110479146516u, 116657952312902359u },
|
||||
{ 16991309721690548428u, 72911220195563974u }, { 12015765115258409727u, 91139025244454968u },
|
||||
{ 15019706394073012159u, 113923781555568710u }, { 9551260955736489391u, 142404726944460888u },
|
||||
{ 5969538097335305869u, 89002954340288055u }, { 2850236603241744433u, 111253692925360069u }
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_D2S_FULL_TABLE_H
|
|
@ -1,257 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_DS2_INTRINSICS_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_DS2_INTRINSICS_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(_M_X64) && defined(_MSC_VER)
|
||||
#define _LIBCPP_INTRINSIC128 1
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_umul128(const uint64_t __a, const uint64_t __b, uint64_t* const __productHi) {
|
||||
return _umul128(__a, __b, __productHi);
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
|
||||
// For the __shiftright128 intrinsic, the shift value is always
|
||||
// modulo 64.
|
||||
// In the current implementation of the double-precision version
|
||||
// of Ryu, the shift value is always < 64.
|
||||
// (The shift value is in the range [49, 58].)
|
||||
// Check this here in case a future change requires larger shift
|
||||
// values. In this case this function needs to be adjusted.
|
||||
_LIBCPP_ASSERT(__dist < 64, "");
|
||||
return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist));
|
||||
}
|
||||
|
||||
// ^^^ intrinsics available ^^^ / vvv __int128 available vvv
|
||||
#elif defined(__SIZEOF_INT128__) && ( \
|
||||
(defined(__clang__) && !defined(_MSC_VER)) || \
|
||||
(defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)))
|
||||
#define _LIBCPP_INTRINSIC128 1
|
||||
// We have __uint128 support in clang or gcc
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_umul128(const uint64_t __a, const uint64_t __b, uint64_t* const __productHi) {
|
||||
auto __temp = __a * (unsigned __int128)__b;
|
||||
*__productHi = __temp >> 64;
|
||||
return static_cast<uint64_t>(__temp);
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
|
||||
// In the current implementation of the double-precision version
|
||||
// of Ryu, the shift value is always < 64.
|
||||
// (The shift value is in the range [49, 58].)
|
||||
// Check this here in case a future change requires larger shift
|
||||
// values. In this case this function needs to be adjusted.
|
||||
_LIBCPP_ASSERT(__dist < 64, "");
|
||||
auto __temp = __lo | ((unsigned __int128)__hi << 64);
|
||||
// For x64 128-bit shfits using the `shrd` instruction and two 64-bit
|
||||
// registers, the shift value is modulo 64. Thus the `& 63` is free.
|
||||
return static_cast<uint64_t>(__temp >> (__dist & 63));
|
||||
}
|
||||
#else // ^^^ __int128 available ^^^ / vvv intrinsics unavailable vvv
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ALWAYS_INLINE uint64_t __ryu_umul128(const uint64_t __a, const uint64_t __b, uint64_t* const __productHi) {
|
||||
// TRANSITION, VSO-634761
|
||||
// The casts here help MSVC to avoid calls to the __allmul library function.
|
||||
const uint32_t __aLo = static_cast<uint32_t>(__a);
|
||||
const uint32_t __aHi = static_cast<uint32_t>(__a >> 32);
|
||||
const uint32_t __bLo = static_cast<uint32_t>(__b);
|
||||
const uint32_t __bHi = static_cast<uint32_t>(__b >> 32);
|
||||
|
||||
const uint64_t __b00 = static_cast<uint64_t>(__aLo) * __bLo;
|
||||
const uint64_t __b01 = static_cast<uint64_t>(__aLo) * __bHi;
|
||||
const uint64_t __b10 = static_cast<uint64_t>(__aHi) * __bLo;
|
||||
const uint64_t __b11 = static_cast<uint64_t>(__aHi) * __bHi;
|
||||
|
||||
const uint32_t __b00Lo = static_cast<uint32_t>(__b00);
|
||||
const uint32_t __b00Hi = static_cast<uint32_t>(__b00 >> 32);
|
||||
|
||||
const uint64_t __mid1 = __b10 + __b00Hi;
|
||||
const uint32_t __mid1Lo = static_cast<uint32_t>(__mid1);
|
||||
const uint32_t __mid1Hi = static_cast<uint32_t>(__mid1 >> 32);
|
||||
|
||||
const uint64_t __mid2 = __b01 + __mid1Lo;
|
||||
const uint32_t __mid2Lo = static_cast<uint32_t>(__mid2);
|
||||
const uint32_t __mid2Hi = static_cast<uint32_t>(__mid2 >> 32);
|
||||
|
||||
const uint64_t __pHi = __b11 + __mid1Hi + __mid2Hi;
|
||||
const uint64_t __pLo = (static_cast<uint64_t>(__mid2Lo) << 32) | __b00Lo;
|
||||
|
||||
*__productHi = __pHi;
|
||||
return __pLo;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
|
||||
// We don't need to handle the case __dist >= 64 here (see above).
|
||||
_LIBCPP_ASSERT(__dist < 64, "");
|
||||
#ifdef _LIBCPP_64_BIT
|
||||
_LIBCPP_ASSERT(__dist > 0, "");
|
||||
return (__hi << (64 - __dist)) | (__lo >> __dist);
|
||||
#else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
|
||||
// Avoid a 64-bit shift by taking advantage of the range of shift values.
|
||||
_LIBCPP_ASSERT(__dist >= 32, "");
|
||||
return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32));
|
||||
#endif // ^^^ 32-bit ^^^
|
||||
}
|
||||
|
||||
#endif // ^^^ intrinsics unavailable ^^^
|
||||
|
||||
#ifndef _LIBCPP_64_BIT
|
||||
|
||||
// Returns the high 64 bits of the 128-bit product of __a and __b.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __umulh(const uint64_t __a, const uint64_t __b) {
|
||||
// Reuse the __ryu_umul128 implementation.
|
||||
// Optimizers will likely eliminate the instructions used to compute the
|
||||
// low part of the product.
|
||||
uint64_t __hi;
|
||||
(void) __ryu_umul128(__a, __b, &__hi);
|
||||
return __hi;
|
||||
}
|
||||
|
||||
// On 32-bit platforms, compilers typically generate calls to library
|
||||
// functions for 64-bit divisions, even if the divisor is a constant.
|
||||
//
|
||||
// TRANSITION, LLVM-37932
|
||||
//
|
||||
// The functions here perform division-by-constant using multiplications
|
||||
// in the same way as 64-bit compilers would do.
|
||||
//
|
||||
// NB:
|
||||
// The multipliers and shift values are the ones generated by clang x64
|
||||
// for expressions like x/5, x/10, etc.
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div5(const uint64_t __x) {
|
||||
return __umulh(__x, 0xCCCCCCCCCCCCCCCDu) >> 2;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div10(const uint64_t __x) {
|
||||
return __umulh(__x, 0xCCCCCCCCCCCCCCCDu) >> 3;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div100(const uint64_t __x) {
|
||||
return __umulh(__x >> 2, 0x28F5C28F5C28F5C3u) >> 2;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div1e8(const uint64_t __x) {
|
||||
return __umulh(__x, 0xABCC77118461CEFDu) >> 26;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div1e9(const uint64_t __x) {
|
||||
return __umulh(__x >> 9, 0x44B82FA09B5A53u) >> 11;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mod1e9(const uint64_t __x) {
|
||||
// Avoid 64-bit math as much as possible.
|
||||
// Returning static_cast<uint32_t>(__x - 1000000000 * __div1e9(__x)) would
|
||||
// perform 32x64-bit multiplication and 64-bit subtraction.
|
||||
// __x and 1000000000 * __div1e9(__x) are guaranteed to differ by
|
||||
// less than 10^9, so their highest 32 bits must be identical,
|
||||
// so we can truncate both sides to uint32_t before subtracting.
|
||||
// We can also simplify static_cast<uint32_t>(1000000000 * __div1e9(__x)).
|
||||
// We can truncate before multiplying instead of after, as multiplying
|
||||
// the highest 32 bits of __div1e9(__x) can't affect the lowest 32 bits.
|
||||
return static_cast<uint32_t>(__x) - 1000000000 * static_cast<uint32_t>(__div1e9(__x));
|
||||
}
|
||||
|
||||
#else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div5(const uint64_t __x) {
|
||||
return __x / 5;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div10(const uint64_t __x) {
|
||||
return __x / 10;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div100(const uint64_t __x) {
|
||||
return __x / 100;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div1e8(const uint64_t __x) {
|
||||
return __x / 100000000;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __div1e9(const uint64_t __x) {
|
||||
return __x / 1000000000;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mod1e9(const uint64_t __x) {
|
||||
return static_cast<uint32_t>(__x - 1000000000 * __div1e9(__x));
|
||||
}
|
||||
|
||||
#endif // ^^^ 64-bit ^^^
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) {
|
||||
uint32_t __count = 0;
|
||||
for (;;) {
|
||||
_LIBCPP_ASSERT(__value != 0, "");
|
||||
const uint64_t __q = __div5(__value);
|
||||
const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q);
|
||||
if (__r != 0) {
|
||||
break;
|
||||
}
|
||||
__value = __q;
|
||||
++__count;
|
||||
}
|
||||
return __count;
|
||||
}
|
||||
|
||||
// Returns true if __value is divisible by 5^__p.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf5(const uint64_t __value, const uint32_t __p) {
|
||||
// I tried a case distinction on __p, but there was no performance difference.
|
||||
return __pow5Factor(__value) >= __p;
|
||||
}
|
||||
|
||||
// Returns true if __value is divisible by 2^__p.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) {
|
||||
_LIBCPP_ASSERT(__value != 0, "");
|
||||
_LIBCPP_ASSERT(__p < 64, "");
|
||||
// __builtin_ctzll doesn't appear to be faster here.
|
||||
return (__value & ((1ull << __p) - 1)) == 0;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_DS2_INTRINSICS_H
|
|
@ -1,68 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// A table of all two-digit numbers. This is used to speed up decimal digit
|
||||
// generation by copying pairs of digits into the final output.
|
||||
inline constexpr char __DIGIT_TABLE[200] = {
|
||||
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
||||
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
||||
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
||||
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
|
||||
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
|
||||
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
|
||||
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
|
||||
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
|
||||
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
|
||||
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H
|
|
@ -1,55 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_FS2_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_FS2_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
[[nodiscard]] to_chars_result __f2s_buffered_n(char* const _First, char* const _Last, const float __f, const chars_format _Fmt);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_FS2_H
|
|
@ -1,148 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _LIBCPP_SRC_INCLUDE_RYU_RYU_H
|
||||
#define _LIBCPP_SRC_INCLUDE_RYU_RYU_H
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__charconv/chars_format.h"
|
||||
#include "__charconv/to_chars_result.h"
|
||||
#include "__config"
|
||||
#include "__debug"
|
||||
#include "__errc"
|
||||
#include "cstdint"
|
||||
#include "cstring"
|
||||
#include "type_traits"
|
||||
#include "include/ryu/f2s.h"
|
||||
#include "include/ryu/d2s.h"
|
||||
#include "include/ryu/d2fixed.h"
|
||||
|
||||
#if defined(_M_X64) && defined(_LIBCPP_COMPILER_MSVC)
|
||||
#include <intrin0.h> // for _umul128() and __shiftright128()
|
||||
#endif // defined(_M_X64) && defined(_LIBCPP_COMPILER_MSVC)
|
||||
|
||||
#if defined(_WIN64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__aarch64__)
|
||||
#define _LIBCPP_64_BIT
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// https://github.com/ulfjack/ryu/tree/59661c3/ryu
|
||||
|
||||
#if !defined(_LIBCPP_COMPILER_MSVC)
|
||||
_LIBCPP_HIDE_FROM_ABI inline unsigned char _BitScanForward64(unsigned long* __index, unsigned long long __mask) {
|
||||
if (__mask == 0) {
|
||||
return false;
|
||||
}
|
||||
*__index = __builtin_ctzll(__mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline unsigned char _BitScanForward(unsigned long* __index, unsigned int __mask) {
|
||||
if (__mask == 0) {
|
||||
return false;
|
||||
}
|
||||
*__index = __builtin_ctz(__mask);
|
||||
return true;
|
||||
}
|
||||
#endif // _LIBCPP_COMPILER_MSVC
|
||||
|
||||
template <class _Floating>
|
||||
[[nodiscard]] to_chars_result _Floating_to_chars_ryu(
|
||||
char* const _First, char* const _Last, const _Floating _Value, const chars_format _Fmt) noexcept {
|
||||
if constexpr (_IsSame<_Floating, float>::value) {
|
||||
return __f2s_buffered_n(_First, _Last, _Value, _Fmt);
|
||||
} else {
|
||||
return __d2s_buffered_n(_First, _Last, _Value, _Fmt);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Floating>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI to_chars_result _Floating_to_chars_scientific_precision(
|
||||
char* const _First, char* const _Last, const _Floating _Value, int _Precision) noexcept {
|
||||
|
||||
// C11 7.21.6.1 "The fprintf function"/5:
|
||||
// "A negative precision argument is taken as if the precision were omitted."
|
||||
// /8: "e,E [...] if the precision is missing, it is taken as 6"
|
||||
|
||||
if (_Precision < 0) {
|
||||
_Precision = 6;
|
||||
} else if (_Precision < 1'000'000'000) { // Match ' to fix compilation with GCC in C++11 mode
|
||||
// _Precision is ok.
|
||||
} else {
|
||||
// Avoid integer overflow.
|
||||
// (This defensive check is slightly nonconformant; it can be carefully improved in the future.)
|
||||
return {_Last, errc::value_too_large};
|
||||
}
|
||||
|
||||
return __d2exp_buffered_n(_First, _Last, _Value, static_cast<uint32_t>(_Precision));
|
||||
}
|
||||
|
||||
template <class _Floating>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI to_chars_result _Floating_to_chars_fixed_precision(
|
||||
char* const _First, char* const _Last, const _Floating _Value, int _Precision) noexcept {
|
||||
|
||||
// C11 7.21.6.1 "The fprintf function"/5:
|
||||
// "A negative precision argument is taken as if the precision were omitted."
|
||||
// /8: "f,F [...] If the precision is missing, it is taken as 6"
|
||||
|
||||
if (_Precision < 0) {
|
||||
_Precision = 6;
|
||||
} else if (_Precision < 1'000'000'000) { // Match ' to fix compilation with GCC in C++11 mode
|
||||
// _Precision is ok.
|
||||
} else {
|
||||
// Avoid integer overflow.
|
||||
// (This defensive check is slightly nonconformant; it can be carefully improved in the future.)
|
||||
return {_Last, errc::value_too_large};
|
||||
}
|
||||
|
||||
return __d2fixed_buffered_n(_First, _Last, _Value, static_cast<uint32_t>(_Precision));
|
||||
}
|
||||
|
||||
#undef _LIBCPP_64_BIT
|
||||
#undef _LIBCPP_INTRINSIC128
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // _LIBCPP_SRC_INCLUDE_RYU_RYU_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +0,0 @@
|
|||
The code in this directory is based on Ulf Adams's work. The upstream for the
|
||||
code is:
|
||||
|
||||
https://github.com/ulfjack/ryu/tree/59661c3/ryu
|
||||
|
||||
The code has been adapted by Stephan T. Lavavej of Microsoft for usage in
|
||||
std::to_chars. This code has been contributed by Microsoft for inclusion in
|
||||
libc++.
|
||||
|
||||
The code in this directory has a different coding style than other parts to
|
||||
minimize the number of changes by both upstream sources.
|
|
@ -1,669 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
#include "charconv"
|
||||
#include "cstring"
|
||||
#include "system_error"
|
||||
|
||||
#include "include/ryu/common.h"
|
||||
#include "include/ryu/d2fixed.h"
|
||||
#include "include/ryu/d2fixed_full_table.h"
|
||||
#include "include/ryu/d2s.h"
|
||||
#include "include/ryu/d2s_intrinsics.h"
|
||||
#include "include/ryu/digit_table.h"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline constexpr int __POW10_ADDITIONAL_BITS = 120;
|
||||
|
||||
#ifdef _LIBCPP_INTRINSIC128
|
||||
// Returns the low 64 bits of the high 128 bits of the 256-bit product of a and b.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __umul256_hi128_lo64(
|
||||
const uint64_t __aHi, const uint64_t __aLo, const uint64_t __bHi, const uint64_t __bLo) {
|
||||
uint64_t __b00Hi;
|
||||
const uint64_t __b00Lo = __ryu_umul128(__aLo, __bLo, &__b00Hi);
|
||||
uint64_t __b01Hi;
|
||||
const uint64_t __b01Lo = __ryu_umul128(__aLo, __bHi, &__b01Hi);
|
||||
uint64_t __b10Hi;
|
||||
const uint64_t __b10Lo = __ryu_umul128(__aHi, __bLo, &__b10Hi);
|
||||
uint64_t __b11Hi;
|
||||
const uint64_t __b11Lo = __ryu_umul128(__aHi, __bHi, &__b11Hi);
|
||||
(void) __b00Lo; // unused
|
||||
(void) __b11Hi; // unused
|
||||
const uint64_t __temp1Lo = __b10Lo + __b00Hi;
|
||||
const uint64_t __temp1Hi = __b10Hi + (__temp1Lo < __b10Lo);
|
||||
const uint64_t __temp2Lo = __b01Lo + __temp1Lo;
|
||||
const uint64_t __temp2Hi = __b01Hi + (__temp2Lo < __b01Lo);
|
||||
return __b11Lo + __temp1Hi + __temp2Hi;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __uint128_mod1e9(const uint64_t __vHi, const uint64_t __vLo) {
|
||||
// After multiplying, we're going to shift right by 29, then truncate to uint32_t.
|
||||
// This means that we need only 29 + 32 = 61 bits, so we can truncate to uint64_t before shifting.
|
||||
const uint64_t __multiplied = __umul256_hi128_lo64(__vHi, __vLo, 0x89705F4136B4A597u, 0x31680A88F8953031u);
|
||||
|
||||
// For uint32_t truncation, see the __mod1e9() comment in d2s_intrinsics.h.
|
||||
const uint32_t __shifted = static_cast<uint32_t>(__multiplied >> 29);
|
||||
|
||||
return static_cast<uint32_t>(__vLo) - 1000000000 * __shifted;
|
||||
}
|
||||
#endif // ^^^ intrinsics available ^^^
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift_mod1e9(const uint64_t __m, const uint64_t* const __mul, const int32_t __j) {
|
||||
uint64_t __high0; // 64
|
||||
const uint64_t __low0 = __ryu_umul128(__m, __mul[0], &__high0); // 0
|
||||
uint64_t __high1; // 128
|
||||
const uint64_t __low1 = __ryu_umul128(__m, __mul[1], &__high1); // 64
|
||||
uint64_t __high2; // 192
|
||||
const uint64_t __low2 = __ryu_umul128(__m, __mul[2], &__high2); // 128
|
||||
const uint64_t __s0low = __low0; // 0
|
||||
(void) __s0low; // unused
|
||||
const uint64_t __s0high = __low1 + __high0; // 64
|
||||
const uint32_t __c1 = __s0high < __low1;
|
||||
const uint64_t __s1low = __low2 + __high1 + __c1; // 128
|
||||
const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
|
||||
const uint64_t __s1high = __high2 + __c2; // 192
|
||||
_LIBCPP_ASSERT(__j >= 128, "");
|
||||
_LIBCPP_ASSERT(__j <= 180, "");
|
||||
#ifdef _LIBCPP_INTRINSIC128
|
||||
const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
|
||||
const uint64_t __shiftedhigh = __s1high >> __dist;
|
||||
const uint64_t __shiftedlow = __ryu_shiftright128(__s1low, __s1high, __dist);
|
||||
return __uint128_mod1e9(__shiftedhigh, __shiftedlow);
|
||||
#else // ^^^ intrinsics available ^^^ / vvv intrinsics unavailable vvv
|
||||
if (__j < 160) { // __j: [128, 160)
|
||||
const uint64_t __r0 = __mod1e9(__s1high);
|
||||
const uint64_t __r1 = __mod1e9((__r0 << 32) | (__s1low >> 32));
|
||||
const uint64_t __r2 = ((__r1 << 32) | (__s1low & 0xffffffff));
|
||||
return __mod1e9(__r2 >> (__j - 128));
|
||||
} else { // __j: [160, 192)
|
||||
const uint64_t __r0 = __mod1e9(__s1high);
|
||||
const uint64_t __r1 = ((__r0 << 32) | (__s1low >> 32));
|
||||
return __mod1e9(__r1 >> (__j - 160));
|
||||
}
|
||||
#endif // ^^^ intrinsics unavailable ^^^
|
||||
}
|
||||
|
||||
void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
|
||||
uint32_t __i = 0;
|
||||
while (__digits >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = __digits - 10000 * (__digits / 10000);
|
||||
#else
|
||||
const uint32_t __c = __digits % 10000;
|
||||
#endif
|
||||
__digits /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
|
||||
__i += 4;
|
||||
}
|
||||
if (__digits >= 100) {
|
||||
const uint32_t __c = (__digits % 100) << 1;
|
||||
__digits /= 100;
|
||||
_VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
|
||||
__i += 2;
|
||||
}
|
||||
if (__digits >= 10) {
|
||||
const uint32_t __c = __digits << 1;
|
||||
_VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
|
||||
} else {
|
||||
__result[0] = static_cast<char>('0' + __digits);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, uint32_t __digits, char* const __result) {
|
||||
uint32_t __i = 0;
|
||||
while (__digits >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = __digits - 10000 * (__digits / 10000);
|
||||
#else
|
||||
const uint32_t __c = __digits % 10000;
|
||||
#endif
|
||||
__digits /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
|
||||
__i += 4;
|
||||
}
|
||||
if (__digits >= 100) {
|
||||
const uint32_t __c = (__digits % 100) << 1;
|
||||
__digits /= 100;
|
||||
_VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
|
||||
__i += 2;
|
||||
}
|
||||
if (__digits >= 10) {
|
||||
const uint32_t __c = __digits << 1;
|
||||
__result[2] = __DIGIT_TABLE[__c + 1];
|
||||
__result[1] = '.';
|
||||
__result[0] = __DIGIT_TABLE[__c];
|
||||
} else {
|
||||
__result[1] = '.';
|
||||
__result[0] = static_cast<char>('0' + __digits);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint32_t __digits, char* const __result) {
|
||||
uint32_t __i = 0;
|
||||
for (; __i < __count - 1; __i += 2) {
|
||||
const uint32_t __c = (__digits % 100) << 1;
|
||||
__digits /= 100;
|
||||
_VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
|
||||
}
|
||||
if (__i < __count) {
|
||||
const char __c = static_cast<char>('0' + (__digits % 10));
|
||||
__result[__count - __i - 1] = __c;
|
||||
}
|
||||
}
|
||||
|
||||
void __append_nine_digits(uint32_t __digits, char* const __result) {
|
||||
if (__digits == 0) {
|
||||
_VSTD::memset(__result, '0', 9);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t __i = 0; __i < 5; __i += 4) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = __digits - 10000 * (__digits / 10000);
|
||||
#else
|
||||
const uint32_t __c = __digits % 10000;
|
||||
#endif
|
||||
__digits /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
|
||||
}
|
||||
__result[0] = static_cast<char>('0' + __digits);
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __indexForExponent(const uint32_t __e) {
|
||||
return (__e + 15) / 16;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow10BitsForIndex(const uint32_t __idx) {
|
||||
return 16 * __idx + __POW10_ADDITIONAL_BITS;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __lengthForIndex(const uint32_t __idx) {
|
||||
// +1 for ceil, +16 for mantissa, +8 to round up when dividing by 9
|
||||
return (__log10Pow2(16 * static_cast<int32_t>(__idx)) + 1 + 16 + 8) / 9;
|
||||
}
|
||||
|
||||
[[nodiscard]] to_chars_result __d2fixed_buffered_n(char* _First, char* const _Last, const double __d,
|
||||
const uint32_t __precision) {
|
||||
char* const _Original_first = _First;
|
||||
|
||||
const uint64_t __bits = __double_to_bits(__d);
|
||||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (__bits == 0) {
|
||||
const int32_t _Total_zero_length = 1 // leading zero
|
||||
+ static_cast<int32_t>(__precision != 0) // possible decimal point
|
||||
+ static_cast<int32_t>(__precision); // zeroes after decimal point
|
||||
|
||||
if (_Last - _First < _Total_zero_length) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
*_First++ = '0';
|
||||
if (__precision > 0) {
|
||||
*_First++ = '.';
|
||||
_VSTD::memset(_First, '0', __precision);
|
||||
_First += __precision;
|
||||
}
|
||||
return { _First, errc{} };
|
||||
}
|
||||
|
||||
// Decode __bits into mantissa and exponent.
|
||||
const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
|
||||
const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
|
||||
|
||||
int32_t __e2;
|
||||
uint64_t __m2;
|
||||
if (__ieeeExponent == 0) {
|
||||
__e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
|
||||
__m2 = __ieeeMantissa;
|
||||
} else {
|
||||
__e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
|
||||
__m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
|
||||
}
|
||||
|
||||
bool __nonzero = false;
|
||||
if (__e2 >= -52) {
|
||||
const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
|
||||
const uint32_t __p10bits = __pow10BitsForIndex(__idx);
|
||||
const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
|
||||
for (int32_t __i = __len - 1; __i >= 0; --__i) {
|
||||
const uint32_t __j = __p10bits - __e2;
|
||||
// Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
|
||||
// a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
|
||||
const uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
|
||||
static_cast<int32_t>(__j + 8));
|
||||
if (__nonzero) {
|
||||
if (_Last - _First < 9) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_nine_digits(__digits, _First);
|
||||
_First += 9;
|
||||
} else if (__digits != 0) {
|
||||
const uint32_t __olength = __decimalLength9(__digits);
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__olength)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_n_digits(__olength, __digits, _First);
|
||||
_First += __olength;
|
||||
__nonzero = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!__nonzero) {
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = '0';
|
||||
}
|
||||
if (__precision > 0) {
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = '.';
|
||||
}
|
||||
if (__e2 < 0) {
|
||||
const int32_t __idx = -__e2 / 16;
|
||||
const uint32_t __blocks = __precision / 9 + 1;
|
||||
// 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
|
||||
int __roundUp = 0;
|
||||
uint32_t __i = 0;
|
||||
if (__blocks <= __MIN_BLOCK_2[__idx]) {
|
||||
__i = __blocks;
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
_VSTD::memset(_First, '0', __precision);
|
||||
_First += __precision;
|
||||
} else if (__i < __MIN_BLOCK_2[__idx]) {
|
||||
__i = __MIN_BLOCK_2[__idx];
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
_VSTD::memset(_First, '0', 9 * __i);
|
||||
_First += 9 * __i;
|
||||
}
|
||||
for (; __i < __blocks; ++__i) {
|
||||
const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
|
||||
const uint32_t __p = __POW10_OFFSET_2[__idx] + __i - __MIN_BLOCK_2[__idx];
|
||||
if (__p >= __POW10_OFFSET_2[__idx + 1]) {
|
||||
// If the remaining digits are all 0, then we might as well use memset.
|
||||
// No rounding required in this case.
|
||||
const uint32_t __fill = __precision - 9 * __i;
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
_VSTD::memset(_First, '0', __fill);
|
||||
_First += __fill;
|
||||
break;
|
||||
}
|
||||
// Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
|
||||
// a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
|
||||
uint32_t __digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
|
||||
if (__i < __blocks - 1) {
|
||||
if (_Last - _First < 9) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_nine_digits(__digits, _First);
|
||||
_First += 9;
|
||||
} else {
|
||||
const uint32_t __maximum = __precision - 9 * __i;
|
||||
uint32_t __lastDigit = 0;
|
||||
for (uint32_t __k = 0; __k < 9 - __maximum; ++__k) {
|
||||
__lastDigit = __digits % 10;
|
||||
__digits /= 10;
|
||||
}
|
||||
if (__lastDigit != 5) {
|
||||
__roundUp = __lastDigit > 5;
|
||||
} else {
|
||||
// Is m * 10^(additionalDigits + 1) / 2^(-__e2) integer?
|
||||
const int32_t __requiredTwos = -__e2 - static_cast<int32_t>(__precision) - 1;
|
||||
const bool __trailingZeros = __requiredTwos <= 0
|
||||
|| (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
|
||||
__roundUp = __trailingZeros ? 2 : 1;
|
||||
}
|
||||
if (__maximum > 0) {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_c_digits(__maximum, __digits, _First);
|
||||
_First += __maximum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (__roundUp != 0) {
|
||||
char* _Round = _First;
|
||||
char* _Dot = _Last;
|
||||
while (true) {
|
||||
if (_Round == _Original_first) {
|
||||
_Round[0] = '1';
|
||||
if (_Dot != _Last) {
|
||||
_Dot[0] = '0';
|
||||
_Dot[1] = '.';
|
||||
}
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = '0';
|
||||
break;
|
||||
}
|
||||
--_Round;
|
||||
const char __c = _Round[0];
|
||||
if (__c == '.') {
|
||||
_Dot = _Round;
|
||||
} else if (__c == '9') {
|
||||
_Round[0] = '0';
|
||||
__roundUp = 1;
|
||||
} else {
|
||||
if (__roundUp == 1 || __c % 2 != 0) {
|
||||
_Round[0] = __c + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
_VSTD::memset(_First, '0', __precision);
|
||||
_First += __precision;
|
||||
}
|
||||
return { _First, errc{} };
|
||||
}
|
||||
|
||||
[[nodiscard]] to_chars_result __d2exp_buffered_n(char* _First, char* const _Last, const double __d,
|
||||
uint32_t __precision) {
|
||||
char* const _Original_first = _First;
|
||||
|
||||
const uint64_t __bits = __double_to_bits(__d);
|
||||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (__bits == 0) {
|
||||
const int32_t _Total_zero_length = 1 // leading zero
|
||||
+ static_cast<int32_t>(__precision != 0) // possible decimal point
|
||||
+ static_cast<int32_t>(__precision) // zeroes after decimal point
|
||||
+ 4; // "e+00"
|
||||
if (_Last - _First < _Total_zero_length) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = '0';
|
||||
if (__precision > 0) {
|
||||
*_First++ = '.';
|
||||
_VSTD::memset(_First, '0', __precision);
|
||||
_First += __precision;
|
||||
}
|
||||
_VSTD::memcpy(_First, "e+00", 4);
|
||||
_First += 4;
|
||||
return { _First, errc{} };
|
||||
}
|
||||
|
||||
// Decode __bits into mantissa and exponent.
|
||||
const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
|
||||
const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
|
||||
|
||||
int32_t __e2;
|
||||
uint64_t __m2;
|
||||
if (__ieeeExponent == 0) {
|
||||
__e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
|
||||
__m2 = __ieeeMantissa;
|
||||
} else {
|
||||
__e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
|
||||
__m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
|
||||
}
|
||||
|
||||
const bool __printDecimalPoint = __precision > 0;
|
||||
++__precision;
|
||||
uint32_t __digits = 0;
|
||||
uint32_t __printedDigits = 0;
|
||||
uint32_t __availableDigits = 0;
|
||||
int32_t __exp = 0;
|
||||
if (__e2 >= -52) {
|
||||
const uint32_t __idx = __e2 < 0 ? 0 : __indexForExponent(static_cast<uint32_t>(__e2));
|
||||
const uint32_t __p10bits = __pow10BitsForIndex(__idx);
|
||||
const int32_t __len = static_cast<int32_t>(__lengthForIndex(__idx));
|
||||
for (int32_t __i = __len - 1; __i >= 0; --__i) {
|
||||
const uint32_t __j = __p10bits - __e2;
|
||||
// Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
|
||||
// a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
|
||||
__digits = __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT[__POW10_OFFSET[__idx] + __i],
|
||||
static_cast<int32_t>(__j + 8));
|
||||
if (__printedDigits != 0) {
|
||||
if (__printedDigits + 9 > __precision) {
|
||||
__availableDigits = 9;
|
||||
break;
|
||||
}
|
||||
if (_Last - _First < 9) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_nine_digits(__digits, _First);
|
||||
_First += 9;
|
||||
__printedDigits += 9;
|
||||
} else if (__digits != 0) {
|
||||
__availableDigits = __decimalLength9(__digits);
|
||||
__exp = __i * 9 + static_cast<int32_t>(__availableDigits) - 1;
|
||||
if (__availableDigits > __precision) {
|
||||
break;
|
||||
}
|
||||
if (__printDecimalPoint) {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_d_digits(__availableDigits, __digits, _First);
|
||||
_First += __availableDigits + 1; // +1 for decimal point
|
||||
} else {
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = static_cast<char>('0' + __digits);
|
||||
}
|
||||
__printedDigits = __availableDigits;
|
||||
__availableDigits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (__e2 < 0 && __availableDigits == 0) {
|
||||
const int32_t __idx = -__e2 / 16;
|
||||
for (int32_t __i = __MIN_BLOCK_2[__idx]; __i < 200; ++__i) {
|
||||
const int32_t __j = __ADDITIONAL_BITS_2 + (-__e2 - 16 * __idx);
|
||||
const uint32_t __p = __POW10_OFFSET_2[__idx] + static_cast<uint32_t>(__i) - __MIN_BLOCK_2[__idx];
|
||||
// Temporary: __j is usually around 128, and by shifting a bit, we push it to 128 or above, which is
|
||||
// a slightly faster code path in __mulShift_mod1e9. Instead, we can just increase the multipliers.
|
||||
__digits = (__p >= __POW10_OFFSET_2[__idx + 1]) ? 0 : __mulShift_mod1e9(__m2 << 8, __POW10_SPLIT_2[__p], __j + 8);
|
||||
if (__printedDigits != 0) {
|
||||
if (__printedDigits + 9 > __precision) {
|
||||
__availableDigits = 9;
|
||||
break;
|
||||
}
|
||||
if (_Last - _First < 9) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_nine_digits(__digits, _First);
|
||||
_First += 9;
|
||||
__printedDigits += 9;
|
||||
} else if (__digits != 0) {
|
||||
__availableDigits = __decimalLength9(__digits);
|
||||
__exp = -(__i + 1) * 9 + static_cast<int32_t>(__availableDigits) - 1;
|
||||
if (__availableDigits > __precision) {
|
||||
break;
|
||||
}
|
||||
if (__printDecimalPoint) {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__availableDigits + 1)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_d_digits(__availableDigits, __digits, _First);
|
||||
_First += __availableDigits + 1; // +1 for decimal point
|
||||
} else {
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = static_cast<char>('0' + __digits);
|
||||
}
|
||||
__printedDigits = __availableDigits;
|
||||
__availableDigits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t __maximum = __precision - __printedDigits;
|
||||
if (__availableDigits == 0) {
|
||||
__digits = 0;
|
||||
}
|
||||
uint32_t __lastDigit = 0;
|
||||
if (__availableDigits > __maximum) {
|
||||
for (uint32_t __k = 0; __k < __availableDigits - __maximum; ++__k) {
|
||||
__lastDigit = __digits % 10;
|
||||
__digits /= 10;
|
||||
}
|
||||
}
|
||||
// 0 = don't round up; 1 = round up unconditionally; 2 = round up if odd.
|
||||
int __roundUp = 0;
|
||||
if (__lastDigit != 5) {
|
||||
__roundUp = __lastDigit > 5;
|
||||
} else {
|
||||
// Is m * 2^__e2 * 10^(__precision + 1 - __exp) integer?
|
||||
// __precision was already increased by 1, so we don't need to write + 1 here.
|
||||
const int32_t __rexp = static_cast<int32_t>(__precision) - __exp;
|
||||
const int32_t __requiredTwos = -__e2 - __rexp;
|
||||
bool __trailingZeros = __requiredTwos <= 0
|
||||
|| (__requiredTwos < 60 && __multipleOfPowerOf2(__m2, static_cast<uint32_t>(__requiredTwos)));
|
||||
if (__rexp < 0) {
|
||||
const int32_t __requiredFives = -__rexp;
|
||||
__trailingZeros = __trailingZeros && __multipleOfPowerOf5(__m2, static_cast<uint32_t>(__requiredFives));
|
||||
}
|
||||
__roundUp = __trailingZeros ? 2 : 1;
|
||||
}
|
||||
if (__printedDigits != 0) {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__maximum)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
if (__digits == 0) {
|
||||
_VSTD::memset(_First, '0', __maximum);
|
||||
} else {
|
||||
__append_c_digits(__maximum, __digits, _First);
|
||||
}
|
||||
_First += __maximum;
|
||||
} else {
|
||||
if (__printDecimalPoint) {
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(__maximum + 1)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
__append_d_digits(__maximum, __digits, _First);
|
||||
_First += __maximum + 1; // +1 for decimal point
|
||||
} else {
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
*_First++ = static_cast<char>('0' + __digits);
|
||||
}
|
||||
}
|
||||
if (__roundUp != 0) {
|
||||
char* _Round = _First;
|
||||
while (true) {
|
||||
if (_Round == _Original_first) {
|
||||
_Round[0] = '1';
|
||||
++__exp;
|
||||
break;
|
||||
}
|
||||
--_Round;
|
||||
const char __c = _Round[0];
|
||||
if (__c == '.') {
|
||||
// Keep going.
|
||||
} else if (__c == '9') {
|
||||
_Round[0] = '0';
|
||||
__roundUp = 1;
|
||||
} else {
|
||||
if (__roundUp == 1 || __c % 2 != 0) {
|
||||
_Round[0] = __c + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char _Sign_character;
|
||||
|
||||
if (__exp < 0) {
|
||||
_Sign_character = '-';
|
||||
__exp = -__exp;
|
||||
} else {
|
||||
_Sign_character = '+';
|
||||
}
|
||||
|
||||
const int _Exponent_part_length = __exp >= 100
|
||||
? 5 // "e+NNN"
|
||||
: 4; // "e+NN"
|
||||
|
||||
if (_Last - _First < _Exponent_part_length) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
*_First++ = 'e';
|
||||
*_First++ = _Sign_character;
|
||||
|
||||
if (__exp >= 100) {
|
||||
const int32_t __c = __exp % 10;
|
||||
_VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
|
||||
_First[2] = static_cast<char>('0' + __c);
|
||||
_First += 3;
|
||||
} else {
|
||||
_VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
|
||||
_First += 2;
|
||||
}
|
||||
|
||||
return { _First, errc{} };
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
|
@ -1,782 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
#include "charconv"
|
||||
|
||||
#include "include/ryu/common.h"
|
||||
#include "include/ryu/d2fixed.h"
|
||||
#include "include/ryu/d2s.h"
|
||||
#include "include/ryu/d2s_full_table.h"
|
||||
#include "include/ryu/d2s_intrinsics.h"
|
||||
#include "include/ryu/digit_table.h"
|
||||
#include "include/ryu/ryu.h"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// We need a 64x128-bit multiplication and a subsequent 128-bit shift.
|
||||
// Multiplication:
|
||||
// The 64-bit factor is variable and passed in, the 128-bit factor comes
|
||||
// from a lookup table. We know that the 64-bit factor only has 55
|
||||
// significant bits (i.e., the 9 topmost bits are zeros). The 128-bit
|
||||
// factor only has 124 significant bits (i.e., the 4 topmost bits are
|
||||
// zeros).
|
||||
// Shift:
|
||||
// In principle, the multiplication result requires 55 + 124 = 179 bits to
|
||||
// represent. However, we then shift this value to the right by __j, which is
|
||||
// at least __j >= 115, so the result is guaranteed to fit into 179 - 115 = 64
|
||||
// bits. This means that we only need the topmost 64 significant bits of
|
||||
// the 64x128-bit multiplication.
|
||||
//
|
||||
// There are several ways to do this:
|
||||
// 1. Best case: the compiler exposes a 128-bit type.
|
||||
// We perform two 64x64-bit multiplications, add the higher 64 bits of the
|
||||
// lower result to the higher result, and shift by __j - 64 bits.
|
||||
//
|
||||
// We explicitly cast from 64-bit to 128-bit, so the compiler can tell
|
||||
// that these are only 64-bit inputs, and can map these to the best
|
||||
// possible sequence of assembly instructions.
|
||||
// x64 machines happen to have matching assembly instructions for
|
||||
// 64x64-bit multiplications and 128-bit shifts.
|
||||
//
|
||||
// 2. Second best case: the compiler exposes intrinsics for the x64 assembly
|
||||
// instructions mentioned in 1.
|
||||
//
|
||||
// 3. We only have 64x64 bit instructions that return the lower 64 bits of
|
||||
// the result, i.e., we have to use plain C.
|
||||
// Our inputs are less than the full width, so we have three options:
|
||||
// a. Ignore this fact and just implement the intrinsics manually.
|
||||
// b. Split both into 31-bit pieces, which guarantees no internal overflow,
|
||||
// but requires extra work upfront (unless we change the lookup table).
|
||||
// c. Split only the first factor into 31-bit pieces, which also guarantees
|
||||
// no internal overflow, but requires extra work since the intermediate
|
||||
// results are not perfectly aligned.
|
||||
#ifdef _LIBCPP_INTRINSIC128
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __mulShift(const uint64_t __m, const uint64_t* const __mul, const int32_t __j) {
|
||||
// __m is maximum 55 bits
|
||||
uint64_t __high1; // 128
|
||||
const uint64_t __low1 = __ryu_umul128(__m, __mul[1], &__high1); // 64
|
||||
uint64_t __high0; // 64
|
||||
(void) __ryu_umul128(__m, __mul[0], &__high0); // 0
|
||||
const uint64_t __sum = __high0 + __low1;
|
||||
if (__sum < __high0) {
|
||||
++__high1; // overflow into __high1
|
||||
}
|
||||
return __ryu_shiftright128(__sum, __high1, static_cast<uint32_t>(__j - 64));
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __mulShiftAll(const uint64_t __m, const uint64_t* const __mul, const int32_t __j,
|
||||
uint64_t* const __vp, uint64_t* const __vm, const uint32_t __mmShift) {
|
||||
*__vp = __mulShift(4 * __m + 2, __mul, __j);
|
||||
*__vm = __mulShift(4 * __m - 1 - __mmShift, __mul, __j);
|
||||
return __mulShift(4 * __m, __mul, __j);
|
||||
}
|
||||
|
||||
#else // ^^^ intrinsics available ^^^ / vvv intrinsics unavailable vvv
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ALWAYS_INLINE uint64_t __mulShiftAll(uint64_t __m, const uint64_t* const __mul, const int32_t __j,
|
||||
uint64_t* const __vp, uint64_t* const __vm, const uint32_t __mmShift) { // TRANSITION, VSO-634761
|
||||
__m <<= 1;
|
||||
// __m is maximum 55 bits
|
||||
uint64_t __tmp;
|
||||
const uint64_t __lo = __ryu_umul128(__m, __mul[0], &__tmp);
|
||||
uint64_t __hi;
|
||||
const uint64_t __mid = __tmp + __ryu_umul128(__m, __mul[1], &__hi);
|
||||
__hi += __mid < __tmp; // overflow into __hi
|
||||
|
||||
const uint64_t __lo2 = __lo + __mul[0];
|
||||
const uint64_t __mid2 = __mid + __mul[1] + (__lo2 < __lo);
|
||||
const uint64_t __hi2 = __hi + (__mid2 < __mid);
|
||||
*__vp = __ryu_shiftright128(__mid2, __hi2, static_cast<uint32_t>(__j - 64 - 1));
|
||||
|
||||
if (__mmShift == 1) {
|
||||
const uint64_t __lo3 = __lo - __mul[0];
|
||||
const uint64_t __mid3 = __mid - __mul[1] - (__lo3 > __lo);
|
||||
const uint64_t __hi3 = __hi - (__mid3 > __mid);
|
||||
*__vm = __ryu_shiftright128(__mid3, __hi3, static_cast<uint32_t>(__j - 64 - 1));
|
||||
} else {
|
||||
const uint64_t __lo3 = __lo + __lo;
|
||||
const uint64_t __mid3 = __mid + __mid + (__lo3 < __lo);
|
||||
const uint64_t __hi3 = __hi + __hi + (__mid3 < __mid);
|
||||
const uint64_t __lo4 = __lo3 - __mul[0];
|
||||
const uint64_t __mid4 = __mid3 - __mul[1] - (__lo4 > __lo3);
|
||||
const uint64_t __hi4 = __hi3 - (__mid4 > __mid3);
|
||||
*__vm = __ryu_shiftright128(__mid4, __hi4, static_cast<uint32_t>(__j - 64));
|
||||
}
|
||||
|
||||
return __ryu_shiftright128(__mid, __hi, static_cast<uint32_t>(__j - 64 - 1));
|
||||
}
|
||||
|
||||
#endif // ^^^ intrinsics unavailable ^^^
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __decimalLength17(const uint64_t __v) {
|
||||
// This is slightly faster than a loop.
|
||||
// The average output length is 16.38 digits, so we check high-to-low.
|
||||
// Function precondition: __v is not an 18, 19, or 20-digit number.
|
||||
// (17 digits are sufficient for round-tripping.)
|
||||
_LIBCPP_ASSERT(__v < 100000000000000000u, "");
|
||||
if (__v >= 10000000000000000u) { return 17; }
|
||||
if (__v >= 1000000000000000u) { return 16; }
|
||||
if (__v >= 100000000000000u) { return 15; }
|
||||
if (__v >= 10000000000000u) { return 14; }
|
||||
if (__v >= 1000000000000u) { return 13; }
|
||||
if (__v >= 100000000000u) { return 12; }
|
||||
if (__v >= 10000000000u) { return 11; }
|
||||
if (__v >= 1000000000u) { return 10; }
|
||||
if (__v >= 100000000u) { return 9; }
|
||||
if (__v >= 10000000u) { return 8; }
|
||||
if (__v >= 1000000u) { return 7; }
|
||||
if (__v >= 100000u) { return 6; }
|
||||
if (__v >= 10000u) { return 5; }
|
||||
if (__v >= 1000u) { return 4; }
|
||||
if (__v >= 100u) { return 3; }
|
||||
if (__v >= 10u) { return 2; }
|
||||
return 1;
|
||||
}
|
||||
|
||||
// A floating decimal representing m * 10^e.
|
||||
struct __floating_decimal_64 {
|
||||
uint64_t __mantissa;
|
||||
int32_t __exponent;
|
||||
};
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline __floating_decimal_64 __d2d(const uint64_t __ieeeMantissa, const uint32_t __ieeeExponent) {
|
||||
int32_t __e2;
|
||||
uint64_t __m2;
|
||||
if (__ieeeExponent == 0) {
|
||||
// We subtract 2 so that the bounds computation has 2 additional bits.
|
||||
__e2 = 1 - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS - 2;
|
||||
__m2 = __ieeeMantissa;
|
||||
} else {
|
||||
__e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS - 2;
|
||||
__m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
|
||||
}
|
||||
const bool __even = (__m2 & 1) == 0;
|
||||
const bool __acceptBounds = __even;
|
||||
|
||||
// Step 2: Determine the interval of valid decimal representations.
|
||||
const uint64_t __mv = 4 * __m2;
|
||||
// Implicit bool -> int conversion. True is 1, false is 0.
|
||||
const uint32_t __mmShift = __ieeeMantissa != 0 || __ieeeExponent <= 1;
|
||||
// We would compute __mp and __mm like this:
|
||||
// uint64_t __mp = 4 * __m2 + 2;
|
||||
// uint64_t __mm = __mv - 1 - __mmShift;
|
||||
|
||||
// Step 3: Convert to a decimal power base using 128-bit arithmetic.
|
||||
uint64_t __vr, __vp, __vm;
|
||||
int32_t __e10;
|
||||
bool __vmIsTrailingZeros = false;
|
||||
bool __vrIsTrailingZeros = false;
|
||||
if (__e2 >= 0) {
|
||||
// I tried special-casing __q == 0, but there was no effect on performance.
|
||||
// This expression is slightly faster than max(0, __log10Pow2(__e2) - 1).
|
||||
const uint32_t __q = __log10Pow2(__e2) - (__e2 > 3);
|
||||
__e10 = static_cast<int32_t>(__q);
|
||||
const int32_t __k = __DOUBLE_POW5_INV_BITCOUNT + __pow5bits(static_cast<int32_t>(__q)) - 1;
|
||||
const int32_t __i = -__e2 + static_cast<int32_t>(__q) + __k;
|
||||
__vr = __mulShiftAll(__m2, __DOUBLE_POW5_INV_SPLIT[__q], __i, &__vp, &__vm, __mmShift);
|
||||
if (__q <= 21) {
|
||||
// This should use __q <= 22, but I think 21 is also safe. Smaller values
|
||||
// may still be safe, but it's more difficult to reason about them.
|
||||
// Only one of __mp, __mv, and __mm can be a multiple of 5, if any.
|
||||
const uint32_t __mvMod5 = static_cast<uint32_t>(__mv) - 5 * static_cast<uint32_t>(__div5(__mv));
|
||||
if (__mvMod5 == 0) {
|
||||
__vrIsTrailingZeros = __multipleOfPowerOf5(__mv, __q);
|
||||
} else if (__acceptBounds) {
|
||||
// Same as min(__e2 + (~__mm & 1), __pow5Factor(__mm)) >= __q
|
||||
// <=> __e2 + (~__mm & 1) >= __q && __pow5Factor(__mm) >= __q
|
||||
// <=> true && __pow5Factor(__mm) >= __q, since __e2 >= __q.
|
||||
__vmIsTrailingZeros = __multipleOfPowerOf5(__mv - 1 - __mmShift, __q);
|
||||
} else {
|
||||
// Same as min(__e2 + 1, __pow5Factor(__mp)) >= __q.
|
||||
__vp -= __multipleOfPowerOf5(__mv + 2, __q);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This expression is slightly faster than max(0, __log10Pow5(-__e2) - 1).
|
||||
const uint32_t __q = __log10Pow5(-__e2) - (-__e2 > 1);
|
||||
__e10 = static_cast<int32_t>(__q) + __e2;
|
||||
const int32_t __i = -__e2 - static_cast<int32_t>(__q);
|
||||
const int32_t __k = __pow5bits(__i) - __DOUBLE_POW5_BITCOUNT;
|
||||
const int32_t __j = static_cast<int32_t>(__q) - __k;
|
||||
__vr = __mulShiftAll(__m2, __DOUBLE_POW5_SPLIT[__i], __j, &__vp, &__vm, __mmShift);
|
||||
if (__q <= 1) {
|
||||
// {__vr,__vp,__vm} is trailing zeros if {__mv,__mp,__mm} has at least __q trailing 0 bits.
|
||||
// __mv = 4 * __m2, so it always has at least two trailing 0 bits.
|
||||
__vrIsTrailingZeros = true;
|
||||
if (__acceptBounds) {
|
||||
// __mm = __mv - 1 - __mmShift, so it has 1 trailing 0 bit iff __mmShift == 1.
|
||||
__vmIsTrailingZeros = __mmShift == 1;
|
||||
} else {
|
||||
// __mp = __mv + 2, so it always has at least one trailing 0 bit.
|
||||
--__vp;
|
||||
}
|
||||
} else if (__q < 63) { // TRANSITION(ulfjack): Use a tighter bound here.
|
||||
// We need to compute min(ntz(__mv), __pow5Factor(__mv) - __e2) >= __q - 1
|
||||
// <=> ntz(__mv) >= __q - 1 && __pow5Factor(__mv) - __e2 >= __q - 1
|
||||
// <=> ntz(__mv) >= __q - 1 (__e2 is negative and -__e2 >= __q)
|
||||
// <=> (__mv & ((1 << (__q - 1)) - 1)) == 0
|
||||
// We also need to make sure that the left shift does not overflow.
|
||||
__vrIsTrailingZeros = __multipleOfPowerOf2(__mv, __q - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Find the shortest decimal representation in the interval of valid representations.
|
||||
int32_t __removed = 0;
|
||||
uint8_t __lastRemovedDigit = 0;
|
||||
uint64_t _Output;
|
||||
// On average, we remove ~2 digits.
|
||||
if (__vmIsTrailingZeros || __vrIsTrailingZeros) {
|
||||
// General case, which happens rarely (~0.7%).
|
||||
for (;;) {
|
||||
const uint64_t __vpDiv10 = __div10(__vp);
|
||||
const uint64_t __vmDiv10 = __div10(__vm);
|
||||
if (__vpDiv10 <= __vmDiv10) {
|
||||
break;
|
||||
}
|
||||
const uint32_t __vmMod10 = static_cast<uint32_t>(__vm) - 10 * static_cast<uint32_t>(__vmDiv10);
|
||||
const uint64_t __vrDiv10 = __div10(__vr);
|
||||
const uint32_t __vrMod10 = static_cast<uint32_t>(__vr) - 10 * static_cast<uint32_t>(__vrDiv10);
|
||||
__vmIsTrailingZeros &= __vmMod10 == 0;
|
||||
__vrIsTrailingZeros &= __lastRemovedDigit == 0;
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__vrMod10);
|
||||
__vr = __vrDiv10;
|
||||
__vp = __vpDiv10;
|
||||
__vm = __vmDiv10;
|
||||
++__removed;
|
||||
}
|
||||
if (__vmIsTrailingZeros) {
|
||||
for (;;) {
|
||||
const uint64_t __vmDiv10 = __div10(__vm);
|
||||
const uint32_t __vmMod10 = static_cast<uint32_t>(__vm) - 10 * static_cast<uint32_t>(__vmDiv10);
|
||||
if (__vmMod10 != 0) {
|
||||
break;
|
||||
}
|
||||
const uint64_t __vpDiv10 = __div10(__vp);
|
||||
const uint64_t __vrDiv10 = __div10(__vr);
|
||||
const uint32_t __vrMod10 = static_cast<uint32_t>(__vr) - 10 * static_cast<uint32_t>(__vrDiv10);
|
||||
__vrIsTrailingZeros &= __lastRemovedDigit == 0;
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__vrMod10);
|
||||
__vr = __vrDiv10;
|
||||
__vp = __vpDiv10;
|
||||
__vm = __vmDiv10;
|
||||
++__removed;
|
||||
}
|
||||
}
|
||||
if (__vrIsTrailingZeros && __lastRemovedDigit == 5 && __vr % 2 == 0) {
|
||||
// Round even if the exact number is .....50..0.
|
||||
__lastRemovedDigit = 4;
|
||||
}
|
||||
// We need to take __vr + 1 if __vr is outside bounds or we need to round up.
|
||||
_Output = __vr + ((__vr == __vm && (!__acceptBounds || !__vmIsTrailingZeros)) || __lastRemovedDigit >= 5);
|
||||
} else {
|
||||
// Specialized for the common case (~99.3%). Percentages below are relative to this.
|
||||
bool __roundUp = false;
|
||||
const uint64_t __vpDiv100 = __div100(__vp);
|
||||
const uint64_t __vmDiv100 = __div100(__vm);
|
||||
if (__vpDiv100 > __vmDiv100) { // Optimization: remove two digits at a time (~86.2%).
|
||||
const uint64_t __vrDiv100 = __div100(__vr);
|
||||
const uint32_t __vrMod100 = static_cast<uint32_t>(__vr) - 100 * static_cast<uint32_t>(__vrDiv100);
|
||||
__roundUp = __vrMod100 >= 50;
|
||||
__vr = __vrDiv100;
|
||||
__vp = __vpDiv100;
|
||||
__vm = __vmDiv100;
|
||||
__removed += 2;
|
||||
}
|
||||
// Loop iterations below (approximately), without optimization above:
|
||||
// 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02%
|
||||
// Loop iterations below (approximately), with optimization above:
|
||||
// 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
|
||||
for (;;) {
|
||||
const uint64_t __vpDiv10 = __div10(__vp);
|
||||
const uint64_t __vmDiv10 = __div10(__vm);
|
||||
if (__vpDiv10 <= __vmDiv10) {
|
||||
break;
|
||||
}
|
||||
const uint64_t __vrDiv10 = __div10(__vr);
|
||||
const uint32_t __vrMod10 = static_cast<uint32_t>(__vr) - 10 * static_cast<uint32_t>(__vrDiv10);
|
||||
__roundUp = __vrMod10 >= 5;
|
||||
__vr = __vrDiv10;
|
||||
__vp = __vpDiv10;
|
||||
__vm = __vmDiv10;
|
||||
++__removed;
|
||||
}
|
||||
// We need to take __vr + 1 if __vr is outside bounds or we need to round up.
|
||||
_Output = __vr + (__vr == __vm || __roundUp);
|
||||
}
|
||||
const int32_t __exp = __e10 + __removed;
|
||||
|
||||
__floating_decimal_64 __fd;
|
||||
__fd.__exponent = __exp;
|
||||
__fd.__mantissa = _Output;
|
||||
return __fd;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline to_chars_result __to_chars(char* const _First, char* const _Last, const __floating_decimal_64 __v,
|
||||
chars_format _Fmt, const double __f) {
|
||||
// Step 5: Print the decimal representation.
|
||||
uint64_t _Output = __v.__mantissa;
|
||||
int32_t _Ryu_exponent = __v.__exponent;
|
||||
const uint32_t __olength = __decimalLength17(_Output);
|
||||
int32_t _Scientific_exponent = _Ryu_exponent + static_cast<int32_t>(__olength) - 1;
|
||||
|
||||
if (_Fmt == chars_format{}) {
|
||||
int32_t _Lower;
|
||||
int32_t _Upper;
|
||||
|
||||
if (__olength == 1) {
|
||||
// Value | Fixed | Scientific
|
||||
// 1e-3 | "0.001" | "1e-03"
|
||||
// 1e4 | "10000" | "1e+04"
|
||||
_Lower = -3;
|
||||
_Upper = 4;
|
||||
} else {
|
||||
// Value | Fixed | Scientific
|
||||
// 1234e-7 | "0.0001234" | "1.234e-04"
|
||||
// 1234e5 | "123400000" | "1.234e+08"
|
||||
_Lower = -static_cast<int32_t>(__olength + 3);
|
||||
_Upper = 5;
|
||||
}
|
||||
|
||||
if (_Lower <= _Ryu_exponent && _Ryu_exponent <= _Upper) {
|
||||
_Fmt = chars_format::fixed;
|
||||
} else {
|
||||
_Fmt = chars_format::scientific;
|
||||
}
|
||||
} else if (_Fmt == chars_format::general) {
|
||||
// C11 7.21.6.1 "The fprintf function"/8:
|
||||
// "Let P equal [...] 6 if the precision is omitted [...].
|
||||
// Then, if a conversion with style E would have an exponent of X:
|
||||
// - if P > X >= -4, the conversion is with style f [...].
|
||||
// - otherwise, the conversion is with style e [...]."
|
||||
if (-4 <= _Scientific_exponent && _Scientific_exponent < 6) {
|
||||
_Fmt = chars_format::fixed;
|
||||
} else {
|
||||
_Fmt = chars_format::scientific;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Fmt == chars_format::fixed) {
|
||||
// Example: _Output == 1729, __olength == 4
|
||||
|
||||
// _Ryu_exponent | Printed | _Whole_digits | _Total_fixed_length | Notes
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// 2 | 172900 | 6 | _Whole_digits | Ryu can't be used for printing
|
||||
// 1 | 17290 | 5 | (sometimes adjusted) | when the trimmed digits are nonzero.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// 0 | 1729 | 4 | _Whole_digits | Unified length cases.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// -1 | 172.9 | 3 | __olength + 1 | This case can't happen for
|
||||
// -2 | 17.29 | 2 | | __olength == 1, but no additional
|
||||
// -3 | 1.729 | 1 | | code is needed to avoid it.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// -4 | 0.1729 | 0 | 2 - _Ryu_exponent | C11 7.21.6.1 "The fprintf function"/8:
|
||||
// -5 | 0.01729 | -1 | | "If a decimal-point character appears,
|
||||
// -6 | 0.001729 | -2 | | at least one digit appears before it."
|
||||
|
||||
const int32_t _Whole_digits = static_cast<int32_t>(__olength) + _Ryu_exponent;
|
||||
|
||||
uint32_t _Total_fixed_length;
|
||||
if (_Ryu_exponent >= 0) { // cases "172900" and "1729"
|
||||
_Total_fixed_length = static_cast<uint32_t>(_Whole_digits);
|
||||
if (_Output == 1) {
|
||||
// Rounding can affect the number of digits.
|
||||
// For example, 1e23 is exactly "99999999999999991611392" which is 23 digits instead of 24.
|
||||
// We can use a lookup table to detect this and adjust the total length.
|
||||
static constexpr uint8_t _Adjustment[309] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,0,
|
||||
1,1,0,0,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,0,0,1,1,1,
|
||||
1,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,1,0,1,1,0,1,
|
||||
1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,1,
|
||||
0,1,0,1,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,0,1,0,1,1,0,0,0,1,
|
||||
1,1,0,1,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,1,1,0,0,0,1,0,1,0,0,0,0,0,1,1,0,
|
||||
0,1,0,1,1,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0 };
|
||||
_Total_fixed_length -= _Adjustment[_Ryu_exponent];
|
||||
// _Whole_digits doesn't need to be adjusted because these cases won't refer to it later.
|
||||
}
|
||||
} else if (_Whole_digits > 0) { // case "17.29"
|
||||
_Total_fixed_length = __olength + 1;
|
||||
} else { // case "0.001729"
|
||||
_Total_fixed_length = static_cast<uint32_t>(2 - _Ryu_exponent);
|
||||
}
|
||||
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(_Total_fixed_length)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
char* _Mid;
|
||||
if (_Ryu_exponent > 0) { // case "172900"
|
||||
bool _Can_use_ryu;
|
||||
|
||||
if (_Ryu_exponent > 22) { // 10^22 is the largest power of 10 that's exactly representable as a double.
|
||||
_Can_use_ryu = false;
|
||||
} else {
|
||||
// Ryu generated X: __v.__mantissa * 10^_Ryu_exponent
|
||||
// __v.__mantissa == 2^_Trailing_zero_bits * (__v.__mantissa >> _Trailing_zero_bits)
|
||||
// 10^_Ryu_exponent == 2^_Ryu_exponent * 5^_Ryu_exponent
|
||||
|
||||
// _Trailing_zero_bits is [0, 56] (aside: because 2^56 is the largest power of 2
|
||||
// with 17 decimal digits, which is double's round-trip limit.)
|
||||
// _Ryu_exponent is [1, 22].
|
||||
// Normalization adds [2, 52] (aside: at least 2 because the pre-normalized mantissa is at least 5).
|
||||
// This adds up to [3, 130], which is well below double's maximum binary exponent 1023.
|
||||
|
||||
// Therefore, we just need to consider (__v.__mantissa >> _Trailing_zero_bits) * 5^_Ryu_exponent.
|
||||
|
||||
// If that product would exceed 53 bits, then X can't be exactly represented as a double.
|
||||
// (That's not a problem for round-tripping, because X is close enough to the original double,
|
||||
// but X isn't mathematically equal to the original double.) This requires a high-precision fallback.
|
||||
|
||||
// If the product is 53 bits or smaller, then X can be exactly represented as a double (and we don't
|
||||
// need to re-synthesize it; the original double must have been X, because Ryu wouldn't produce the
|
||||
// same output for two different doubles X and Y). This allows Ryu's output to be used (zero-filled).
|
||||
|
||||
// (2^53 - 1) / 5^0 (for indexing), (2^53 - 1) / 5^1, ..., (2^53 - 1) / 5^22
|
||||
static constexpr uint64_t _Max_shifted_mantissa[23] = {
|
||||
9007199254740991u, 1801439850948198u, 360287970189639u, 72057594037927u, 14411518807585u,
|
||||
2882303761517u, 576460752303u, 115292150460u, 23058430092u, 4611686018u, 922337203u, 184467440u,
|
||||
36893488u, 7378697u, 1475739u, 295147u, 59029u, 11805u, 2361u, 472u, 94u, 18u, 3u };
|
||||
|
||||
unsigned long _Trailing_zero_bits;
|
||||
#ifdef _LIBCPP_HAS_BITSCAN64
|
||||
(void) _BitScanForward64(&_Trailing_zero_bits, __v.__mantissa); // __v.__mantissa is guaranteed nonzero
|
||||
#else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
|
||||
const uint32_t _Low_mantissa = static_cast<uint32_t>(__v.__mantissa);
|
||||
if (_Low_mantissa != 0) {
|
||||
(void) _BitScanForward(&_Trailing_zero_bits, _Low_mantissa);
|
||||
} else {
|
||||
const uint32_t _High_mantissa = static_cast<uint32_t>(__v.__mantissa >> 32); // nonzero here
|
||||
(void) _BitScanForward(&_Trailing_zero_bits, _High_mantissa);
|
||||
_Trailing_zero_bits += 32;
|
||||
}
|
||||
#endif // ^^^ 32-bit ^^^
|
||||
const uint64_t _Shifted_mantissa = __v.__mantissa >> _Trailing_zero_bits;
|
||||
_Can_use_ryu = _Shifted_mantissa <= _Max_shifted_mantissa[_Ryu_exponent];
|
||||
}
|
||||
|
||||
if (!_Can_use_ryu) {
|
||||
// Print the integer exactly.
|
||||
// Performance note: This will redundantly perform bounds checking.
|
||||
// Performance note: This will redundantly decompose the IEEE representation.
|
||||
return __d2fixed_buffered_n(_First, _Last, __f, 0);
|
||||
}
|
||||
|
||||
// _Can_use_ryu
|
||||
// Print the decimal digits, left-aligned within [_First, _First + _Total_fixed_length).
|
||||
_Mid = _First + __olength;
|
||||
} else { // cases "1729", "17.29", and "0.001729"
|
||||
// Print the decimal digits, right-aligned within [_First, _First + _Total_fixed_length).
|
||||
_Mid = _First + _Total_fixed_length;
|
||||
}
|
||||
|
||||
// We prefer 32-bit operations, even on 64-bit platforms.
|
||||
// We have at most 17 digits, and uint32_t can store 9 digits.
|
||||
// If _Output doesn't fit into uint32_t, we cut off 8 digits,
|
||||
// so the rest will fit into uint32_t.
|
||||
if ((_Output >> 32) != 0) {
|
||||
// Expensive 64-bit division.
|
||||
const uint64_t __q = __div1e8(_Output);
|
||||
uint32_t __output2 = static_cast<uint32_t>(_Output - 100000000 * __q);
|
||||
_Output = __q;
|
||||
|
||||
const uint32_t __c = __output2 % 10000;
|
||||
__output2 /= 10000;
|
||||
const uint32_t __d = __output2 % 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
const uint32_t __d0 = (__d % 100) << 1;
|
||||
const uint32_t __d1 = (__d / 100) << 1;
|
||||
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
|
||||
}
|
||||
uint32_t __output2 = static_cast<uint32_t>(_Output);
|
||||
while (__output2 >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = __output2 - 10000 * (__output2 / 10000);
|
||||
#else
|
||||
const uint32_t __c = __output2 % 10000;
|
||||
#endif
|
||||
__output2 /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
|
||||
}
|
||||
if (__output2 >= 100) {
|
||||
const uint32_t __c = (__output2 % 100) << 1;
|
||||
__output2 /= 100;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
|
||||
}
|
||||
if (__output2 >= 10) {
|
||||
const uint32_t __c = __output2 << 1;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
|
||||
} else {
|
||||
*--_Mid = static_cast<char>('0' + __output2);
|
||||
}
|
||||
|
||||
if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
|
||||
// Performance note: it might be more efficient to do this immediately after setting _Mid.
|
||||
_VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
|
||||
} else if (_Ryu_exponent == 0) { // case "1729"
|
||||
// Done!
|
||||
} else if (_Whole_digits > 0) { // case "17.29"
|
||||
// Performance note: moving digits might not be optimal.
|
||||
_VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
|
||||
_First[_Whole_digits] = '.';
|
||||
} else { // case "0.001729"
|
||||
// Performance note: a larger memset() followed by overwriting '.' might be more efficient.
|
||||
_First[0] = '0';
|
||||
_First[1] = '.';
|
||||
_VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
|
||||
}
|
||||
|
||||
return { _First + _Total_fixed_length, errc{} };
|
||||
}
|
||||
|
||||
const uint32_t _Total_scientific_length = __olength + (__olength > 1) // digits + possible decimal point
|
||||
+ (-100 < _Scientific_exponent && _Scientific_exponent < 100 ? 4 : 5); // + scientific exponent
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(_Total_scientific_length)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
char* const __result = _First;
|
||||
|
||||
// Print the decimal digits.
|
||||
uint32_t __i = 0;
|
||||
// We prefer 32-bit operations, even on 64-bit platforms.
|
||||
// We have at most 17 digits, and uint32_t can store 9 digits.
|
||||
// If _Output doesn't fit into uint32_t, we cut off 8 digits,
|
||||
// so the rest will fit into uint32_t.
|
||||
if ((_Output >> 32) != 0) {
|
||||
// Expensive 64-bit division.
|
||||
const uint64_t __q = __div1e8(_Output);
|
||||
uint32_t __output2 = static_cast<uint32_t>(_Output) - 100000000 * static_cast<uint32_t>(__q);
|
||||
_Output = __q;
|
||||
|
||||
const uint32_t __c = __output2 % 10000;
|
||||
__output2 /= 10000;
|
||||
const uint32_t __d = __output2 % 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
const uint32_t __d0 = (__d % 100) << 1;
|
||||
const uint32_t __d1 = (__d / 100) << 1;
|
||||
_VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
|
||||
__i += 8;
|
||||
}
|
||||
uint32_t __output2 = static_cast<uint32_t>(_Output);
|
||||
while (__output2 >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = __output2 - 10000 * (__output2 / 10000);
|
||||
#else
|
||||
const uint32_t __c = __output2 % 10000;
|
||||
#endif
|
||||
__output2 /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
|
||||
__i += 4;
|
||||
}
|
||||
if (__output2 >= 100) {
|
||||
const uint32_t __c = (__output2 % 100) << 1;
|
||||
__output2 /= 100;
|
||||
_VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
|
||||
__i += 2;
|
||||
}
|
||||
if (__output2 >= 10) {
|
||||
const uint32_t __c = __output2 << 1;
|
||||
// We can't use memcpy here: the decimal dot goes between these two digits.
|
||||
__result[2] = __DIGIT_TABLE[__c + 1];
|
||||
__result[0] = __DIGIT_TABLE[__c];
|
||||
} else {
|
||||
__result[0] = static_cast<char>('0' + __output2);
|
||||
}
|
||||
|
||||
// Print decimal point if needed.
|
||||
uint32_t __index;
|
||||
if (__olength > 1) {
|
||||
__result[1] = '.';
|
||||
__index = __olength + 1;
|
||||
} else {
|
||||
__index = 1;
|
||||
}
|
||||
|
||||
// Print the exponent.
|
||||
__result[__index++] = 'e';
|
||||
if (_Scientific_exponent < 0) {
|
||||
__result[__index++] = '-';
|
||||
_Scientific_exponent = -_Scientific_exponent;
|
||||
} else {
|
||||
__result[__index++] = '+';
|
||||
}
|
||||
|
||||
if (_Scientific_exponent >= 100) {
|
||||
const int32_t __c = _Scientific_exponent % 10;
|
||||
_VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
|
||||
__result[__index + 2] = static_cast<char>('0' + __c);
|
||||
__index += 3;
|
||||
} else {
|
||||
_VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
|
||||
__index += 2;
|
||||
}
|
||||
|
||||
return { _First + _Total_scientific_length, errc{} };
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __d2d_small_int(const uint64_t __ieeeMantissa, const uint32_t __ieeeExponent,
|
||||
__floating_decimal_64* const __v) {
|
||||
const uint64_t __m2 = (1ull << __DOUBLE_MANTISSA_BITS) | __ieeeMantissa;
|
||||
const int32_t __e2 = static_cast<int32_t>(__ieeeExponent) - __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS;
|
||||
|
||||
if (__e2 > 0) {
|
||||
// f = __m2 * 2^__e2 >= 2^53 is an integer.
|
||||
// Ignore this case for now.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__e2 < -52) {
|
||||
// f < 1.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since 2^52 <= __m2 < 2^53 and 0 <= -__e2 <= 52: 1 <= f = __m2 / 2^-__e2 < 2^53.
|
||||
// Test if the lower -__e2 bits of the significand are 0, i.e. whether the fraction is 0.
|
||||
const uint64_t __mask = (1ull << -__e2) - 1;
|
||||
const uint64_t __fraction = __m2 & __mask;
|
||||
if (__fraction != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// f is an integer in the range [1, 2^53).
|
||||
// Note: __mantissa might contain trailing (decimal) 0's.
|
||||
// Note: since 2^53 < 10^16, there is no need to adjust __decimalLength17().
|
||||
__v->__mantissa = __m2 >> -__e2;
|
||||
__v->__exponent = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] to_chars_result __d2s_buffered_n(char* const _First, char* const _Last, const double __f,
|
||||
const chars_format _Fmt) {
|
||||
|
||||
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
||||
const uint64_t __bits = __double_to_bits(__f);
|
||||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (__bits == 0) {
|
||||
if (_Fmt == chars_format::scientific) {
|
||||
if (_Last - _First < 5) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
_VSTD::memcpy(_First, "0e+00", 5);
|
||||
|
||||
return { _First + 5, errc{} };
|
||||
}
|
||||
|
||||
// Print "0" for chars_format::fixed, chars_format::general, and chars_format{}.
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
*_First = '0';
|
||||
|
||||
return { _First + 1, errc{} };
|
||||
}
|
||||
|
||||
// Decode __bits into mantissa and exponent.
|
||||
const uint64_t __ieeeMantissa = __bits & ((1ull << __DOUBLE_MANTISSA_BITS) - 1);
|
||||
const uint32_t __ieeeExponent = static_cast<uint32_t>(__bits >> __DOUBLE_MANTISSA_BITS);
|
||||
|
||||
if (_Fmt == chars_format::fixed) {
|
||||
// const uint64_t _Mantissa2 = __ieeeMantissa | (1ull << __DOUBLE_MANTISSA_BITS); // restore implicit bit
|
||||
const int32_t _Exponent2 = static_cast<int32_t>(__ieeeExponent)
|
||||
- __DOUBLE_BIAS - __DOUBLE_MANTISSA_BITS; // bias and normalization
|
||||
|
||||
// Normal values are equal to _Mantissa2 * 2^_Exponent2.
|
||||
// (Subnormals are different, but they'll be rejected by the _Exponent2 test here, so they can be ignored.)
|
||||
|
||||
// For nonzero integers, _Exponent2 >= -52. (The minimum value occurs when _Mantissa2 * 2^_Exponent2 is 1.
|
||||
// In that case, _Mantissa2 is the implicit 1 bit followed by 52 zeros, so _Exponent2 is -52 to shift away
|
||||
// the zeros.) The dense range of exactly representable integers has negative or zero exponents
|
||||
// (as positive exponents make the range non-dense). For that dense range, Ryu will always be used:
|
||||
// every digit is necessary to uniquely identify the value, so Ryu must print them all.
|
||||
|
||||
// Positive exponents are the non-dense range of exactly representable integers. This contains all of the values
|
||||
// for which Ryu can't be used (and a few Ryu-friendly values). We can save time by detecting positive
|
||||
// exponents here and skipping Ryu. Calling __d2fixed_buffered_n() with precision 0 is valid for all integers
|
||||
// (so it's okay if we call it with a Ryu-friendly value).
|
||||
if (_Exponent2 > 0) {
|
||||
return __d2fixed_buffered_n(_First, _Last, __f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
__floating_decimal_64 __v;
|
||||
const bool __isSmallInt = __d2d_small_int(__ieeeMantissa, __ieeeExponent, &__v);
|
||||
if (__isSmallInt) {
|
||||
// For small integers in the range [1, 2^53), __v.__mantissa might contain trailing (decimal) zeros.
|
||||
// For scientific notation we need to move these zeros into the exponent.
|
||||
// (This is not needed for fixed-point notation, so it might be beneficial to trim
|
||||
// trailing zeros in __to_chars only if needed - once fixed-point notation output is implemented.)
|
||||
for (;;) {
|
||||
const uint64_t __q = __div10(__v.__mantissa);
|
||||
const uint32_t __r = static_cast<uint32_t>(__v.__mantissa) - 10 * static_cast<uint32_t>(__q);
|
||||
if (__r != 0) {
|
||||
break;
|
||||
}
|
||||
__v.__mantissa = __q;
|
||||
++__v.__exponent;
|
||||
}
|
||||
} else {
|
||||
__v = __d2d(__ieeeMantissa, __ieeeExponent);
|
||||
}
|
||||
|
||||
return __to_chars(_First, _Last, __v, _Fmt, __f);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
|
@ -1,715 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Avoid formatting to keep the changes with the original code minimal.
|
||||
// clang-format off
|
||||
|
||||
#include "__config"
|
||||
#include "charconv"
|
||||
|
||||
#include "include/ryu/common.h"
|
||||
#include "include/ryu/d2fixed.h"
|
||||
#include "include/ryu/d2s_intrinsics.h"
|
||||
#include "include/ryu/digit_table.h"
|
||||
#include "include/ryu/f2s.h"
|
||||
#include "include/ryu/ryu.h"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline constexpr int __FLOAT_MANTISSA_BITS = 23;
|
||||
inline constexpr int __FLOAT_EXPONENT_BITS = 8;
|
||||
inline constexpr int __FLOAT_BIAS = 127;
|
||||
|
||||
inline constexpr int __FLOAT_POW5_INV_BITCOUNT = 59;
|
||||
inline constexpr uint64_t __FLOAT_POW5_INV_SPLIT[31] = {
|
||||
576460752303423489u, 461168601842738791u, 368934881474191033u, 295147905179352826u,
|
||||
472236648286964522u, 377789318629571618u, 302231454903657294u, 483570327845851670u,
|
||||
386856262276681336u, 309485009821345069u, 495176015714152110u, 396140812571321688u,
|
||||
316912650057057351u, 507060240091291761u, 405648192073033409u, 324518553658426727u,
|
||||
519229685853482763u, 415383748682786211u, 332306998946228969u, 531691198313966350u,
|
||||
425352958651173080u, 340282366920938464u, 544451787073501542u, 435561429658801234u,
|
||||
348449143727040987u, 557518629963265579u, 446014903970612463u, 356811923176489971u,
|
||||
570899077082383953u, 456719261665907162u, 365375409332725730u
|
||||
};
|
||||
inline constexpr int __FLOAT_POW5_BITCOUNT = 61;
|
||||
inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
|
||||
1152921504606846976u, 1441151880758558720u, 1801439850948198400u, 2251799813685248000u,
|
||||
1407374883553280000u, 1759218604441600000u, 2199023255552000000u, 1374389534720000000u,
|
||||
1717986918400000000u, 2147483648000000000u, 1342177280000000000u, 1677721600000000000u,
|
||||
2097152000000000000u, 1310720000000000000u, 1638400000000000000u, 2048000000000000000u,
|
||||
1280000000000000000u, 1600000000000000000u, 2000000000000000000u, 1250000000000000000u,
|
||||
1562500000000000000u, 1953125000000000000u, 1220703125000000000u, 1525878906250000000u,
|
||||
1907348632812500000u, 1192092895507812500u, 1490116119384765625u, 1862645149230957031u,
|
||||
1164153218269348144u, 1455191522836685180u, 1818989403545856475u, 2273736754432320594u,
|
||||
1421085471520200371u, 1776356839400250464u, 2220446049250313080u, 1387778780781445675u,
|
||||
1734723475976807094u, 2168404344971008868u, 1355252715606880542u, 1694065894508600678u,
|
||||
2117582368135750847u, 1323488980084844279u, 1654361225106055349u, 2067951531382569187u,
|
||||
1292469707114105741u, 1615587133892632177u, 2019483917365790221u
|
||||
};
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) {
|
||||
uint32_t __count = 0;
|
||||
for (;;) {
|
||||
_LIBCPP_ASSERT(__value != 0, "");
|
||||
const uint32_t __q = __value / 5;
|
||||
const uint32_t __r = __value % 5;
|
||||
if (__r != 0) {
|
||||
break;
|
||||
}
|
||||
__value = __q;
|
||||
++__count;
|
||||
}
|
||||
return __count;
|
||||
}
|
||||
|
||||
// Returns true if __value is divisible by 5^__p.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf5(const uint32_t __value, const uint32_t __p) {
|
||||
return __pow5Factor(__value) >= __p;
|
||||
}
|
||||
|
||||
// Returns true if __value is divisible by 2^__p.
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) {
|
||||
_LIBCPP_ASSERT(__value != 0, "");
|
||||
_LIBCPP_ASSERT(__p < 32, "");
|
||||
// __builtin_ctz doesn't appear to be faster here.
|
||||
return (__value & ((1u << __p) - 1)) == 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) {
|
||||
_LIBCPP_ASSERT(__shift > 32, "");
|
||||
|
||||
// The casts here help MSVC to avoid calls to the __allmul library
|
||||
// function.
|
||||
const uint32_t __factorLo = static_cast<uint32_t>(__factor);
|
||||
const uint32_t __factorHi = static_cast<uint32_t>(__factor >> 32);
|
||||
const uint64_t __bits0 = static_cast<uint64_t>(__m) * __factorLo;
|
||||
const uint64_t __bits1 = static_cast<uint64_t>(__m) * __factorHi;
|
||||
|
||||
#ifndef _LIBCPP_64_BIT
|
||||
// On 32-bit platforms we can avoid a 64-bit shift-right since we only
|
||||
// need the upper 32 bits of the result and the shift value is > 32.
|
||||
const uint32_t __bits0Hi = static_cast<uint32_t>(__bits0 >> 32);
|
||||
uint32_t __bits1Lo = static_cast<uint32_t>(__bits1);
|
||||
uint32_t __bits1Hi = static_cast<uint32_t>(__bits1 >> 32);
|
||||
__bits1Lo += __bits0Hi;
|
||||
__bits1Hi += (__bits1Lo < __bits0Hi);
|
||||
const int32_t __s = __shift - 32;
|
||||
return (__bits1Hi << (32 - __s)) | (__bits1Lo >> __s);
|
||||
#else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
|
||||
const uint64_t __sum = (__bits0 >> 32) + __bits1;
|
||||
const uint64_t __shiftedSum = __sum >> (__shift - 32);
|
||||
_LIBCPP_ASSERT(__shiftedSum <= UINT32_MAX, "");
|
||||
return static_cast<uint32_t>(__shiftedSum);
|
||||
#endif // ^^^ 64-bit ^^^
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulPow5InvDivPow2(const uint32_t __m, const uint32_t __q, const int32_t __j) {
|
||||
return __mulShift(__m, __FLOAT_POW5_INV_SPLIT[__q], __j);
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulPow5divPow2(const uint32_t __m, const uint32_t __i, const int32_t __j) {
|
||||
return __mulShift(__m, __FLOAT_POW5_SPLIT[__i], __j);
|
||||
}
|
||||
|
||||
// A floating decimal representing m * 10^e.
|
||||
struct __floating_decimal_32 {
|
||||
uint32_t __mantissa;
|
||||
int32_t __exponent;
|
||||
};
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline __floating_decimal_32 __f2d(const uint32_t __ieeeMantissa, const uint32_t __ieeeExponent) {
|
||||
int32_t __e2;
|
||||
uint32_t __m2;
|
||||
if (__ieeeExponent == 0) {
|
||||
// We subtract 2 so that the bounds computation has 2 additional bits.
|
||||
__e2 = 1 - __FLOAT_BIAS - __FLOAT_MANTISSA_BITS - 2;
|
||||
__m2 = __ieeeMantissa;
|
||||
} else {
|
||||
__e2 = static_cast<int32_t>(__ieeeExponent) - __FLOAT_BIAS - __FLOAT_MANTISSA_BITS - 2;
|
||||
__m2 = (1u << __FLOAT_MANTISSA_BITS) | __ieeeMantissa;
|
||||
}
|
||||
const bool __even = (__m2 & 1) == 0;
|
||||
const bool __acceptBounds = __even;
|
||||
|
||||
// Step 2: Determine the interval of valid decimal representations.
|
||||
const uint32_t __mv = 4 * __m2;
|
||||
const uint32_t __mp = 4 * __m2 + 2;
|
||||
// Implicit bool -> int conversion. True is 1, false is 0.
|
||||
const uint32_t __mmShift = __ieeeMantissa != 0 || __ieeeExponent <= 1;
|
||||
const uint32_t __mm = 4 * __m2 - 1 - __mmShift;
|
||||
|
||||
// Step 3: Convert to a decimal power base using 64-bit arithmetic.
|
||||
uint32_t __vr, __vp, __vm;
|
||||
int32_t __e10;
|
||||
bool __vmIsTrailingZeros = false;
|
||||
bool __vrIsTrailingZeros = false;
|
||||
uint8_t __lastRemovedDigit = 0;
|
||||
if (__e2 >= 0) {
|
||||
const uint32_t __q = __log10Pow2(__e2);
|
||||
__e10 = static_cast<int32_t>(__q);
|
||||
const int32_t __k = __FLOAT_POW5_INV_BITCOUNT + __pow5bits(static_cast<int32_t>(__q)) - 1;
|
||||
const int32_t __i = -__e2 + static_cast<int32_t>(__q) + __k;
|
||||
__vr = __mulPow5InvDivPow2(__mv, __q, __i);
|
||||
__vp = __mulPow5InvDivPow2(__mp, __q, __i);
|
||||
__vm = __mulPow5InvDivPow2(__mm, __q, __i);
|
||||
if (__q != 0 && (__vp - 1) / 10 <= __vm / 10) {
|
||||
// We need to know one removed digit even if we are not going to loop below. We could use
|
||||
// __q = X - 1 above, except that would require 33 bits for the result, and we've found that
|
||||
// 32-bit arithmetic is faster even on 64-bit machines.
|
||||
const int32_t __l = __FLOAT_POW5_INV_BITCOUNT + __pow5bits(static_cast<int32_t>(__q - 1)) - 1;
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__mulPow5InvDivPow2(__mv, __q - 1,
|
||||
-__e2 + static_cast<int32_t>(__q) - 1 + __l) % 10);
|
||||
}
|
||||
if (__q <= 9) {
|
||||
// The largest power of 5 that fits in 24 bits is 5^10, but __q <= 9 seems to be safe as well.
|
||||
// Only one of __mp, __mv, and __mm can be a multiple of 5, if any.
|
||||
if (__mv % 5 == 0) {
|
||||
__vrIsTrailingZeros = __multipleOfPowerOf5(__mv, __q);
|
||||
} else if (__acceptBounds) {
|
||||
__vmIsTrailingZeros = __multipleOfPowerOf5(__mm, __q);
|
||||
} else {
|
||||
__vp -= __multipleOfPowerOf5(__mp, __q);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const uint32_t __q = __log10Pow5(-__e2);
|
||||
__e10 = static_cast<int32_t>(__q) + __e2;
|
||||
const int32_t __i = -__e2 - static_cast<int32_t>(__q);
|
||||
const int32_t __k = __pow5bits(__i) - __FLOAT_POW5_BITCOUNT;
|
||||
int32_t __j = static_cast<int32_t>(__q) - __k;
|
||||
__vr = __mulPow5divPow2(__mv, static_cast<uint32_t>(__i), __j);
|
||||
__vp = __mulPow5divPow2(__mp, static_cast<uint32_t>(__i), __j);
|
||||
__vm = __mulPow5divPow2(__mm, static_cast<uint32_t>(__i), __j);
|
||||
if (__q != 0 && (__vp - 1) / 10 <= __vm / 10) {
|
||||
__j = static_cast<int32_t>(__q) - 1 - (__pow5bits(__i + 1) - __FLOAT_POW5_BITCOUNT);
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__mulPow5divPow2(__mv, static_cast<uint32_t>(__i + 1), __j) % 10);
|
||||
}
|
||||
if (__q <= 1) {
|
||||
// {__vr,__vp,__vm} is trailing zeros if {__mv,__mp,__mm} has at least __q trailing 0 bits.
|
||||
// __mv = 4 * __m2, so it always has at least two trailing 0 bits.
|
||||
__vrIsTrailingZeros = true;
|
||||
if (__acceptBounds) {
|
||||
// __mm = __mv - 1 - __mmShift, so it has 1 trailing 0 bit iff __mmShift == 1.
|
||||
__vmIsTrailingZeros = __mmShift == 1;
|
||||
} else {
|
||||
// __mp = __mv + 2, so it always has at least one trailing 0 bit.
|
||||
--__vp;
|
||||
}
|
||||
} else if (__q < 31) { // TRANSITION(ulfjack): Use a tighter bound here.
|
||||
__vrIsTrailingZeros = __multipleOfPowerOf2(__mv, __q - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Find the shortest decimal representation in the interval of valid representations.
|
||||
int32_t __removed = 0;
|
||||
uint32_t _Output;
|
||||
if (__vmIsTrailingZeros || __vrIsTrailingZeros) {
|
||||
// General case, which happens rarely (~4.0%).
|
||||
while (__vp / 10 > __vm / 10) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-23106
|
||||
__vmIsTrailingZeros &= __vm - (__vm / 10) * 10 == 0;
|
||||
#else
|
||||
__vmIsTrailingZeros &= __vm % 10 == 0;
|
||||
#endif
|
||||
__vrIsTrailingZeros &= __lastRemovedDigit == 0;
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__vr % 10);
|
||||
__vr /= 10;
|
||||
__vp /= 10;
|
||||
__vm /= 10;
|
||||
++__removed;
|
||||
}
|
||||
if (__vmIsTrailingZeros) {
|
||||
while (__vm % 10 == 0) {
|
||||
__vrIsTrailingZeros &= __lastRemovedDigit == 0;
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__vr % 10);
|
||||
__vr /= 10;
|
||||
__vp /= 10;
|
||||
__vm /= 10;
|
||||
++__removed;
|
||||
}
|
||||
}
|
||||
if (__vrIsTrailingZeros && __lastRemovedDigit == 5 && __vr % 2 == 0) {
|
||||
// Round even if the exact number is .....50..0.
|
||||
__lastRemovedDigit = 4;
|
||||
}
|
||||
// We need to take __vr + 1 if __vr is outside bounds or we need to round up.
|
||||
_Output = __vr + ((__vr == __vm && (!__acceptBounds || !__vmIsTrailingZeros)) || __lastRemovedDigit >= 5);
|
||||
} else {
|
||||
// Specialized for the common case (~96.0%). Percentages below are relative to this.
|
||||
// Loop iterations below (approximately):
|
||||
// 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
|
||||
while (__vp / 10 > __vm / 10) {
|
||||
__lastRemovedDigit = static_cast<uint8_t>(__vr % 10);
|
||||
__vr /= 10;
|
||||
__vp /= 10;
|
||||
__vm /= 10;
|
||||
++__removed;
|
||||
}
|
||||
// We need to take __vr + 1 if __vr is outside bounds or we need to round up.
|
||||
_Output = __vr + (__vr == __vm || __lastRemovedDigit >= 5);
|
||||
}
|
||||
const int32_t __exp = __e10 + __removed;
|
||||
|
||||
__floating_decimal_32 __fd;
|
||||
__fd.__exponent = __exp;
|
||||
__fd.__mantissa = _Output;
|
||||
return __fd;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline to_chars_result _Large_integer_to_chars(char* const _First, char* const _Last,
|
||||
const uint32_t _Mantissa2, const int32_t _Exponent2) {
|
||||
|
||||
// Print the integer _Mantissa2 * 2^_Exponent2 exactly.
|
||||
|
||||
// For nonzero integers, _Exponent2 >= -23. (The minimum value occurs when _Mantissa2 * 2^_Exponent2 is 1.
|
||||
// In that case, _Mantissa2 is the implicit 1 bit followed by 23 zeros, so _Exponent2 is -23 to shift away
|
||||
// the zeros.) The dense range of exactly representable integers has negative or zero exponents
|
||||
// (as positive exponents make the range non-dense). For that dense range, Ryu will always be used:
|
||||
// every digit is necessary to uniquely identify the value, so Ryu must print them all.
|
||||
|
||||
// Positive exponents are the non-dense range of exactly representable integers.
|
||||
// This contains all of the values for which Ryu can't be used (and a few Ryu-friendly values).
|
||||
|
||||
// Performance note: Long division appears to be faster than losslessly widening float to double and calling
|
||||
// __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division.
|
||||
|
||||
_LIBCPP_ASSERT(_Exponent2 > 0, "");
|
||||
_LIBCPP_ASSERT(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
|
||||
|
||||
// Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits
|
||||
// (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits.
|
||||
// 24 + 104 equals 128 equals 4 * 32, so we need exactly 4 32-bit elements.
|
||||
// We use a little-endian representation, visualized like this:
|
||||
|
||||
// << left shift <<
|
||||
// most significant
|
||||
// _Data[3] _Data[2] _Data[1] _Data[0]
|
||||
// least significant
|
||||
// >> right shift >>
|
||||
|
||||
constexpr uint32_t _Data_size = 4;
|
||||
uint32_t _Data[_Data_size]{};
|
||||
|
||||
// _Maxidx is the index of the most significant nonzero element.
|
||||
uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1;
|
||||
_LIBCPP_ASSERT(_Maxidx < _Data_size, "");
|
||||
|
||||
const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32;
|
||||
if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary
|
||||
_Data[_Maxidx] = _Mantissa2 << _Bit_shift;
|
||||
} else { // _Mantissa2's 24 bits cross an element boundary
|
||||
_Data[_Maxidx - 1] = _Mantissa2 << _Bit_shift;
|
||||
_Data[_Maxidx] = _Mantissa2 >> (32 - _Bit_shift);
|
||||
}
|
||||
|
||||
// If Ryu hasn't determined the total output length, we need to buffer the digits generated from right to left
|
||||
// by long division. The largest possible float is: 340'282346638'528859811'704183484'516925440
|
||||
uint32_t _Blocks[4];
|
||||
int32_t _Filled_blocks = 0;
|
||||
// From left to right, we're going to print:
|
||||
// _Data[0] will be [1, 10] digits.
|
||||
// Then if _Filled_blocks > 0:
|
||||
// _Blocks[_Filled_blocks - 1], ..., _Blocks[0] will be 0-filled 9-digit blocks.
|
||||
|
||||
if (_Maxidx != 0) { // If the integer is actually large, perform long division.
|
||||
// Otherwise, skip to printing _Data[0].
|
||||
for (;;) {
|
||||
// Loop invariant: _Maxidx != 0 (i.e. the integer is actually large)
|
||||
|
||||
const uint32_t _Most_significant_elem = _Data[_Maxidx];
|
||||
const uint32_t _Initial_remainder = _Most_significant_elem % 1000000000;
|
||||
const uint32_t _Initial_quotient = _Most_significant_elem / 1000000000;
|
||||
_Data[_Maxidx] = _Initial_quotient;
|
||||
uint64_t _Remainder = _Initial_remainder;
|
||||
|
||||
// Process less significant elements.
|
||||
uint32_t _Idx = _Maxidx;
|
||||
do {
|
||||
--_Idx; // Initially, _Remainder is at most 10^9 - 1.
|
||||
|
||||
// Now, _Remainder is at most (10^9 - 1) * 2^32 + 2^32 - 1, simplified to 10^9 * 2^32 - 1.
|
||||
_Remainder = (_Remainder << 32) | _Data[_Idx];
|
||||
|
||||
// floor((10^9 * 2^32 - 1) / 10^9) == 2^32 - 1, so uint32_t _Quotient is lossless.
|
||||
const uint32_t _Quotient = static_cast<uint32_t>(__div1e9(_Remainder));
|
||||
|
||||
// _Remainder is at most 10^9 - 1 again.
|
||||
// For uint32_t truncation, see the __mod1e9() comment in d2s_intrinsics.h.
|
||||
_Remainder = static_cast<uint32_t>(_Remainder) - 1000000000u * _Quotient;
|
||||
|
||||
_Data[_Idx] = _Quotient;
|
||||
} while (_Idx != 0);
|
||||
|
||||
// Store a 0-filled 9-digit block.
|
||||
_Blocks[_Filled_blocks++] = static_cast<uint32_t>(_Remainder);
|
||||
|
||||
if (_Initial_quotient == 0) { // Is the large integer shrinking?
|
||||
--_Maxidx; // log2(10^9) is 29.9, so we can't shrink by more than one element.
|
||||
if (_Maxidx == 0) {
|
||||
break; // We've finished long division. Now we need to print _Data[0].
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_ASSERT(_Data[0] != 0, "");
|
||||
for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) {
|
||||
_LIBCPP_ASSERT(_Data[_Idx] == 0, "");
|
||||
}
|
||||
|
||||
const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]);
|
||||
const uint32_t _Total_fixed_length = _Data_olength + 9 * _Filled_blocks;
|
||||
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(_Total_fixed_length)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
char* _Result = _First;
|
||||
|
||||
// Print _Data[0]. While it's up to 10 digits,
|
||||
// which is more than Ryu generates, the code below can handle this.
|
||||
__append_n_digits(_Data_olength, _Data[0], _Result);
|
||||
_Result += _Data_olength;
|
||||
|
||||
// Print 0-filled 9-digit blocks.
|
||||
for (int32_t _Idx = _Filled_blocks - 1; _Idx >= 0; --_Idx) {
|
||||
__append_nine_digits(_Blocks[_Idx], _Result);
|
||||
_Result += 9;
|
||||
}
|
||||
|
||||
return { _Result, errc{} };
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline to_chars_result __to_chars(char* const _First, char* const _Last, const __floating_decimal_32 __v,
|
||||
chars_format _Fmt, const uint32_t __ieeeMantissa, const uint32_t __ieeeExponent) {
|
||||
// Step 5: Print the decimal representation.
|
||||
uint32_t _Output = __v.__mantissa;
|
||||
int32_t _Ryu_exponent = __v.__exponent;
|
||||
const uint32_t __olength = __decimalLength9(_Output);
|
||||
int32_t _Scientific_exponent = _Ryu_exponent + static_cast<int32_t>(__olength) - 1;
|
||||
|
||||
if (_Fmt == chars_format{}) {
|
||||
int32_t _Lower;
|
||||
int32_t _Upper;
|
||||
|
||||
if (__olength == 1) {
|
||||
// Value | Fixed | Scientific
|
||||
// 1e-3 | "0.001" | "1e-03"
|
||||
// 1e4 | "10000" | "1e+04"
|
||||
_Lower = -3;
|
||||
_Upper = 4;
|
||||
} else {
|
||||
// Value | Fixed | Scientific
|
||||
// 1234e-7 | "0.0001234" | "1.234e-04"
|
||||
// 1234e5 | "123400000" | "1.234e+08"
|
||||
_Lower = -static_cast<int32_t>(__olength + 3);
|
||||
_Upper = 5;
|
||||
}
|
||||
|
||||
if (_Lower <= _Ryu_exponent && _Ryu_exponent <= _Upper) {
|
||||
_Fmt = chars_format::fixed;
|
||||
} else {
|
||||
_Fmt = chars_format::scientific;
|
||||
}
|
||||
} else if (_Fmt == chars_format::general) {
|
||||
// C11 7.21.6.1 "The fprintf function"/8:
|
||||
// "Let P equal [...] 6 if the precision is omitted [...].
|
||||
// Then, if a conversion with style E would have an exponent of X:
|
||||
// - if P > X >= -4, the conversion is with style f [...].
|
||||
// - otherwise, the conversion is with style e [...]."
|
||||
if (-4 <= _Scientific_exponent && _Scientific_exponent < 6) {
|
||||
_Fmt = chars_format::fixed;
|
||||
} else {
|
||||
_Fmt = chars_format::scientific;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Fmt == chars_format::fixed) {
|
||||
// Example: _Output == 1729, __olength == 4
|
||||
|
||||
// _Ryu_exponent | Printed | _Whole_digits | _Total_fixed_length | Notes
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// 2 | 172900 | 6 | _Whole_digits | Ryu can't be used for printing
|
||||
// 1 | 17290 | 5 | (sometimes adjusted) | when the trimmed digits are nonzero.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// 0 | 1729 | 4 | _Whole_digits | Unified length cases.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// -1 | 172.9 | 3 | __olength + 1 | This case can't happen for
|
||||
// -2 | 17.29 | 2 | | __olength == 1, but no additional
|
||||
// -3 | 1.729 | 1 | | code is needed to avoid it.
|
||||
// --------------|----------|---------------|----------------------|---------------------------------------
|
||||
// -4 | 0.1729 | 0 | 2 - _Ryu_exponent | C11 7.21.6.1 "The fprintf function"/8:
|
||||
// -5 | 0.01729 | -1 | | "If a decimal-point character appears,
|
||||
// -6 | 0.001729 | -2 | | at least one digit appears before it."
|
||||
|
||||
const int32_t _Whole_digits = static_cast<int32_t>(__olength) + _Ryu_exponent;
|
||||
|
||||
uint32_t _Total_fixed_length;
|
||||
if (_Ryu_exponent >= 0) { // cases "172900" and "1729"
|
||||
_Total_fixed_length = static_cast<uint32_t>(_Whole_digits);
|
||||
if (_Output == 1) {
|
||||
// Rounding can affect the number of digits.
|
||||
// For example, 1e11f is exactly "99999997952" which is 11 digits instead of 12.
|
||||
// We can use a lookup table to detect this and adjust the total length.
|
||||
static constexpr uint8_t _Adjustment[39] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,1,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,1,0,1,1,1 };
|
||||
_Total_fixed_length -= _Adjustment[_Ryu_exponent];
|
||||
// _Whole_digits doesn't need to be adjusted because these cases won't refer to it later.
|
||||
}
|
||||
} else if (_Whole_digits > 0) { // case "17.29"
|
||||
_Total_fixed_length = __olength + 1;
|
||||
} else { // case "0.001729"
|
||||
_Total_fixed_length = static_cast<uint32_t>(2 - _Ryu_exponent);
|
||||
}
|
||||
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(_Total_fixed_length)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
char* _Mid;
|
||||
if (_Ryu_exponent > 0) { // case "172900"
|
||||
bool _Can_use_ryu;
|
||||
|
||||
if (_Ryu_exponent > 10) { // 10^10 is the largest power of 10 that's exactly representable as a float.
|
||||
_Can_use_ryu = false;
|
||||
} else {
|
||||
// Ryu generated X: __v.__mantissa * 10^_Ryu_exponent
|
||||
// __v.__mantissa == 2^_Trailing_zero_bits * (__v.__mantissa >> _Trailing_zero_bits)
|
||||
// 10^_Ryu_exponent == 2^_Ryu_exponent * 5^_Ryu_exponent
|
||||
|
||||
// _Trailing_zero_bits is [0, 29] (aside: because 2^29 is the largest power of 2
|
||||
// with 9 decimal digits, which is float's round-trip limit.)
|
||||
// _Ryu_exponent is [1, 10].
|
||||
// Normalization adds [2, 23] (aside: at least 2 because the pre-normalized mantissa is at least 5).
|
||||
// This adds up to [3, 62], which is well below float's maximum binary exponent 127.
|
||||
|
||||
// Therefore, we just need to consider (__v.__mantissa >> _Trailing_zero_bits) * 5^_Ryu_exponent.
|
||||
|
||||
// If that product would exceed 24 bits, then X can't be exactly represented as a float.
|
||||
// (That's not a problem for round-tripping, because X is close enough to the original float,
|
||||
// but X isn't mathematically equal to the original float.) This requires a high-precision fallback.
|
||||
|
||||
// If the product is 24 bits or smaller, then X can be exactly represented as a float (and we don't
|
||||
// need to re-synthesize it; the original float must have been X, because Ryu wouldn't produce the
|
||||
// same output for two different floats X and Y). This allows Ryu's output to be used (zero-filled).
|
||||
|
||||
// (2^24 - 1) / 5^0 (for indexing), (2^24 - 1) / 5^1, ..., (2^24 - 1) / 5^10
|
||||
static constexpr uint32_t _Max_shifted_mantissa[11] = {
|
||||
16777215, 3355443, 671088, 134217, 26843, 5368, 1073, 214, 42, 8, 1 };
|
||||
|
||||
unsigned long _Trailing_zero_bits;
|
||||
(void) _BitScanForward(&_Trailing_zero_bits, __v.__mantissa); // __v.__mantissa is guaranteed nonzero
|
||||
const uint32_t _Shifted_mantissa = __v.__mantissa >> _Trailing_zero_bits;
|
||||
_Can_use_ryu = _Shifted_mantissa <= _Max_shifted_mantissa[_Ryu_exponent];
|
||||
}
|
||||
|
||||
if (!_Can_use_ryu) {
|
||||
const uint32_t _Mantissa2 = __ieeeMantissa | (1u << __FLOAT_MANTISSA_BITS); // restore implicit bit
|
||||
const int32_t _Exponent2 = static_cast<int32_t>(__ieeeExponent)
|
||||
- __FLOAT_BIAS - __FLOAT_MANTISSA_BITS; // bias and normalization
|
||||
|
||||
// Performance note: We've already called Ryu, so this will redundantly perform buffering and bounds checking.
|
||||
return _Large_integer_to_chars(_First, _Last, _Mantissa2, _Exponent2);
|
||||
}
|
||||
|
||||
// _Can_use_ryu
|
||||
// Print the decimal digits, left-aligned within [_First, _First + _Total_fixed_length).
|
||||
_Mid = _First + __olength;
|
||||
} else { // cases "1729", "17.29", and "0.001729"
|
||||
// Print the decimal digits, right-aligned within [_First, _First + _Total_fixed_length).
|
||||
_Mid = _First + _Total_fixed_length;
|
||||
}
|
||||
|
||||
while (_Output >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = _Output - 10000 * (_Output / 10000);
|
||||
#else
|
||||
const uint32_t __c = _Output % 10000;
|
||||
#endif
|
||||
_Output /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
|
||||
}
|
||||
if (_Output >= 100) {
|
||||
const uint32_t __c = (_Output % 100) << 1;
|
||||
_Output /= 100;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
|
||||
}
|
||||
if (_Output >= 10) {
|
||||
const uint32_t __c = _Output << 1;
|
||||
_VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
|
||||
} else {
|
||||
*--_Mid = static_cast<char>('0' + _Output);
|
||||
}
|
||||
|
||||
if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
|
||||
// Performance note: it might be more efficient to do this immediately after setting _Mid.
|
||||
_VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
|
||||
} else if (_Ryu_exponent == 0) { // case "1729"
|
||||
// Done!
|
||||
} else if (_Whole_digits > 0) { // case "17.29"
|
||||
// Performance note: moving digits might not be optimal.
|
||||
_VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
|
||||
_First[_Whole_digits] = '.';
|
||||
} else { // case "0.001729"
|
||||
// Performance note: a larger memset() followed by overwriting '.' might be more efficient.
|
||||
_First[0] = '0';
|
||||
_First[1] = '.';
|
||||
_VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
|
||||
}
|
||||
|
||||
return { _First + _Total_fixed_length, errc{} };
|
||||
}
|
||||
|
||||
const uint32_t _Total_scientific_length =
|
||||
__olength + (__olength > 1) + 4; // digits + possible decimal point + scientific exponent
|
||||
if (_Last - _First < static_cast<ptrdiff_t>(_Total_scientific_length)) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
char* const __result = _First;
|
||||
|
||||
// Print the decimal digits.
|
||||
uint32_t __i = 0;
|
||||
while (_Output >= 10000) {
|
||||
#ifdef __clang__ // TRANSITION, LLVM-38217
|
||||
const uint32_t __c = _Output - 10000 * (_Output / 10000);
|
||||
#else
|
||||
const uint32_t __c = _Output % 10000;
|
||||
#endif
|
||||
_Output /= 10000;
|
||||
const uint32_t __c0 = (__c % 100) << 1;
|
||||
const uint32_t __c1 = (__c / 100) << 1;
|
||||
_VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
|
||||
_VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
|
||||
__i += 4;
|
||||
}
|
||||
if (_Output >= 100) {
|
||||
const uint32_t __c = (_Output % 100) << 1;
|
||||
_Output /= 100;
|
||||
_VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
|
||||
__i += 2;
|
||||
}
|
||||
if (_Output >= 10) {
|
||||
const uint32_t __c = _Output << 1;
|
||||
// We can't use memcpy here: the decimal dot goes between these two digits.
|
||||
__result[2] = __DIGIT_TABLE[__c + 1];
|
||||
__result[0] = __DIGIT_TABLE[__c];
|
||||
} else {
|
||||
__result[0] = static_cast<char>('0' + _Output);
|
||||
}
|
||||
|
||||
// Print decimal point if needed.
|
||||
uint32_t __index;
|
||||
if (__olength > 1) {
|
||||
__result[1] = '.';
|
||||
__index = __olength + 1;
|
||||
} else {
|
||||
__index = 1;
|
||||
}
|
||||
|
||||
// Print the exponent.
|
||||
__result[__index++] = 'e';
|
||||
if (_Scientific_exponent < 0) {
|
||||
__result[__index++] = '-';
|
||||
_Scientific_exponent = -_Scientific_exponent;
|
||||
} else {
|
||||
__result[__index++] = '+';
|
||||
}
|
||||
|
||||
_VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
|
||||
__index += 2;
|
||||
|
||||
return { _First + _Total_scientific_length, errc{} };
|
||||
}
|
||||
|
||||
[[nodiscard]] to_chars_result __f2s_buffered_n(char* const _First, char* const _Last, const float __f,
|
||||
const chars_format _Fmt) {
|
||||
|
||||
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
||||
const uint32_t __bits = __float_to_bits(__f);
|
||||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (__bits == 0) {
|
||||
if (_Fmt == chars_format::scientific) {
|
||||
if (_Last - _First < 5) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
_VSTD::memcpy(_First, "0e+00", 5);
|
||||
|
||||
return { _First + 5, errc{} };
|
||||
}
|
||||
|
||||
// Print "0" for chars_format::fixed, chars_format::general, and chars_format{}.
|
||||
if (_First == _Last) {
|
||||
return { _Last, errc::value_too_large };
|
||||
}
|
||||
|
||||
*_First = '0';
|
||||
|
||||
return { _First + 1, errc{} };
|
||||
}
|
||||
|
||||
// Decode __bits into mantissa and exponent.
|
||||
const uint32_t __ieeeMantissa = __bits & ((1u << __FLOAT_MANTISSA_BITS) - 1);
|
||||
const uint32_t __ieeeExponent = __bits >> __FLOAT_MANTISSA_BITS;
|
||||
|
||||
// When _Fmt == chars_format::fixed and the floating-point number is a large integer,
|
||||
// it's faster to skip Ryu and immediately print the integer exactly.
|
||||
if (_Fmt == chars_format::fixed) {
|
||||
const uint32_t _Mantissa2 = __ieeeMantissa | (1u << __FLOAT_MANTISSA_BITS); // restore implicit bit
|
||||
const int32_t _Exponent2 = static_cast<int32_t>(__ieeeExponent)
|
||||
- __FLOAT_BIAS - __FLOAT_MANTISSA_BITS; // bias and normalization
|
||||
|
||||
// Normal values are equal to _Mantissa2 * 2^_Exponent2.
|
||||
// (Subnormals are different, but they'll be rejected by the _Exponent2 test here, so they can be ignored.)
|
||||
|
||||
if (_Exponent2 > 0) {
|
||||
return _Large_integer_to_chars(_First, _Last, _Mantissa2, _Exponent2);
|
||||
}
|
||||
}
|
||||
|
||||
const __floating_decimal_32 __v = __f2d(__ieeeMantissa, __ieeeExponent);
|
||||
return __to_chars(_First, _Last, __v, _Fmt, __ieeeMantissa, __ieeeExponent);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
// clang-format on
|
|
@ -1,300 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
// This file contains test cases derived from:
|
||||
// https://github.com/ulfjack/ryu
|
||||
// See xcharconv_ryu.h for the exact commit.
|
||||
// (Keep the cgmanifest.json commitHash in sync.)
|
||||
|
||||
|
||||
#ifndef DOUBLE_FIXED_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
||||
#define DOUBLE_FIXED_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "test.hpp"
|
||||
using namespace std;
|
||||
|
||||
inline constexpr DoublePrecisionToCharsTestCase double_fixed_precision_to_chars_test_cases_1[] = {
|
||||
// Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
|
||||
{0.0, chars_format::fixed, 4, "0.0000"},
|
||||
{-0.0, chars_format::fixed, 4, "-0.0000"},
|
||||
{double_inf, chars_format::fixed, 4, "inf"},
|
||||
{-double_inf, chars_format::fixed, 4, "-inf"},
|
||||
{double_nan, chars_format::fixed, 4, "nan"},
|
||||
{-double_nan, chars_format::fixed, 4, "-nan(ind)"},
|
||||
{double_nan_payload, chars_format::fixed, 4, "nan"},
|
||||
{-double_nan_payload, chars_format::fixed, 4, "-nan"},
|
||||
{1.729, chars_format::fixed, 4, "1.7290"},
|
||||
{-1.729, chars_format::fixed, 4, "-1.7290"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest Basic
|
||||
{0x1.000000001869fp+211, chars_format::fixed, 0,
|
||||
"3291009114715486435425664845573426149758869524108446525879746560"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest Zero
|
||||
{0.0, chars_format::fixed, 4, "0.0000"},
|
||||
{0.0, chars_format::fixed, 3, "0.000"},
|
||||
{0.0, chars_format::fixed, 2, "0.00"},
|
||||
{0.0, chars_format::fixed, 1, "0.0"},
|
||||
{0.0, chars_format::fixed, 0, "0"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest MinMax
|
||||
{0x0.0000000000001p-1022, chars_format::fixed, 1074,
|
||||
"0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"000000000000000000000000000000000000000000000000000000049406564584124654417656879286822137"
|
||||
"236505980261432476442558568250067550727020875186529983636163599237979656469544571773092665"
|
||||
"671035593979639877479601078187812630071319031140452784581716784898210368871863605699873072"
|
||||
"305000638740915356498438731247339727316961514003171538539807412623856559117102665855668676"
|
||||
"818703956031062493194527159149245532930545654440112748012970999954193198940908041656332452"
|
||||
"475714786901472678015935523861155013480352649347201937902681071074917033322268447533357208"
|
||||
"324319360923828934583680601060115061698097530783422773183292479049825247307763759272478746"
|
||||
"560847782037344696995336470179726777175851256605511991315048911014510378627381672509558373"
|
||||
"89733598993664809941164205702637090279242767544565229087538682506419718265533447265625"},
|
||||
|
||||
{0x1.fffffffffffffp+1023, chars_format::fixed, 0,
|
||||
"179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558"
|
||||
"632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245"
|
||||
"490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168"
|
||||
"738177180919299881250404026184124858368"},
|
||||
|
||||
// Test more corner cases.
|
||||
{0x0.fffffffffffffp-1022, chars_format::fixed, 1074,
|
||||
"0."
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585"
|
||||
"0720088902458687608585988765042311224095946549352480256244000922823569517877588880375915526423097809504343"
|
||||
"1208587738715835729182199302029437922422355981982750124204178896957131179108226104397197960400045489739193"
|
||||
"8079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429"
|
||||
"1050802018159266421349966065178030950759130587198464239060686371020051087232827846788436319445158661350412"
|
||||
"2347901479236958520832159762106637540161373658304419360371477835530668283453563400507407304013560296804637"
|
||||
"5918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417"
|
||||
"9060225895030235019375197730309457631732108525072993050897615825191597207572324554347709124613174935802817"
|
||||
"34466552734375"}, // max subnormal
|
||||
{0x1p-1022, chars_format::fixed, 1022,
|
||||
"0."
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585"
|
||||
"0720138309023271733240406421921598046233183055332741688720443481391819585428315901251102056406733973103581"
|
||||
"1005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250"
|
||||
"8066506166581589487204911799685916396485006359087701183048747997808877537499494515804516050509153998565824"
|
||||
"7081864511353793580499211598108576605199243335211435239014879569960959128889160299264151106346631339366347"
|
||||
"7586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618"
|
||||
"5671661505401542850847167529019031613227788967297073731233340869889831750678388469260927739779728586596549"
|
||||
"41091369095406136467568702398678315290680984617210924625396728515625"}, // min normal
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest RoundToEven
|
||||
{0.125, chars_format::fixed, 3, "0.125"},
|
||||
{0.125, chars_format::fixed, 2, "0.12"},
|
||||
{0.375, chars_format::fixed, 3, "0.375"},
|
||||
{0.375, chars_format::fixed, 2, "0.38"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest RoundToEvenInteger
|
||||
{2.5, chars_format::fixed, 1, "2.5"},
|
||||
{2.5, chars_format::fixed, 0, "2"},
|
||||
{3.5, chars_format::fixed, 1, "3.5"},
|
||||
{3.5, chars_format::fixed, 0, "4"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest NonRoundToEvenScenarios
|
||||
{0.748046875, chars_format::fixed, 3, "0.748"},
|
||||
{0.748046875, chars_format::fixed, 2, "0.75"},
|
||||
{0.748046875, chars_format::fixed, 1, "0.7"}, // 0.75 would round to "0.8", but this is smaller
|
||||
|
||||
{0.2509765625, chars_format::fixed, 3, "0.251"},
|
||||
{0.2509765625, chars_format::fixed, 2, "0.25"},
|
||||
{0.2509765625, chars_format::fixed, 1, "0.3"}, // 0.25 would round to "0.2", but this is larger
|
||||
|
||||
{0x1.0000000000001p-2, chars_format::fixed, 54, "0.250000000000000055511151231257827021181583404541015625"},
|
||||
{0x1.0000000000001p-2, chars_format::fixed, 3, "0.250"},
|
||||
{0x1.0000000000001p-2, chars_format::fixed, 2, "0.25"},
|
||||
{0x1.0000000000001p-2, chars_format::fixed, 1, "0.3"}, // 0.25 would round to "0.2", but this is larger (again)
|
||||
|
||||
// More rounding tests.
|
||||
{9.5, chars_format::fixed, 1, "9.5"},
|
||||
{9.5, chars_format::fixed, 0, "10"},
|
||||
{10.5, chars_format::fixed, 1, "10.5"},
|
||||
{10.5, chars_format::fixed, 0, "10"},
|
||||
|
||||
{1.241, chars_format::fixed, 3, "1.241"},
|
||||
{1.241, chars_format::fixed, 1, "1.2"},
|
||||
{1.251, chars_format::fixed, 3, "1.251"},
|
||||
{1.251, chars_format::fixed, 1, "1.3"},
|
||||
{1.261, chars_format::fixed, 3, "1.261"},
|
||||
{1.261, chars_format::fixed, 1, "1.3"},
|
||||
{1.341, chars_format::fixed, 3, "1.341"},
|
||||
{1.341, chars_format::fixed, 1, "1.3"},
|
||||
{1.351, chars_format::fixed, 3, "1.351"},
|
||||
{1.351, chars_format::fixed, 1, "1.4"},
|
||||
{1.361, chars_format::fixed, 3, "1.361"},
|
||||
{1.361, chars_format::fixed, 1, "1.4"},
|
||||
|
||||
{2.41, chars_format::fixed, 2, "2.41"},
|
||||
{2.41, chars_format::fixed, 0, "2"},
|
||||
{2.51, chars_format::fixed, 2, "2.51"},
|
||||
{2.51, chars_format::fixed, 0, "3"},
|
||||
{2.61, chars_format::fixed, 2, "2.61"},
|
||||
{2.61, chars_format::fixed, 0, "3"},
|
||||
{3.41, chars_format::fixed, 2, "3.41"},
|
||||
{3.41, chars_format::fixed, 0, "3"},
|
||||
{3.51, chars_format::fixed, 2, "3.51"},
|
||||
{3.51, chars_format::fixed, 0, "4"},
|
||||
{3.61, chars_format::fixed, 2, "3.61"},
|
||||
{3.61, chars_format::fixed, 0, "4"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest VaryingPrecision
|
||||
{1729.142857142857, chars_format::fixed, 47, "1729.14285714285711037518922239542007446289062500000"},
|
||||
{1729.142857142857, chars_format::fixed, 46, "1729.1428571428571103751892223954200744628906250000"},
|
||||
{1729.142857142857, chars_format::fixed, 45, "1729.142857142857110375189222395420074462890625000"},
|
||||
{1729.142857142857, chars_format::fixed, 44, "1729.14285714285711037518922239542007446289062500"},
|
||||
{1729.142857142857, chars_format::fixed, 43, "1729.1428571428571103751892223954200744628906250"},
|
||||
{1729.142857142857, chars_format::fixed, 42, "1729.142857142857110375189222395420074462890625"},
|
||||
{1729.142857142857, chars_format::fixed, 41, "1729.14285714285711037518922239542007446289062"},
|
||||
{1729.142857142857, chars_format::fixed, 40, "1729.1428571428571103751892223954200744628906"},
|
||||
{1729.142857142857, chars_format::fixed, 39, "1729.142857142857110375189222395420074462891"},
|
||||
{1729.142857142857, chars_format::fixed, 38, "1729.14285714285711037518922239542007446289"},
|
||||
{1729.142857142857, chars_format::fixed, 37, "1729.1428571428571103751892223954200744629"},
|
||||
{1729.142857142857, chars_format::fixed, 36, "1729.142857142857110375189222395420074463"},
|
||||
{1729.142857142857, chars_format::fixed, 35, "1729.14285714285711037518922239542007446"},
|
||||
{1729.142857142857, chars_format::fixed, 34, "1729.1428571428571103751892223954200745"},
|
||||
{1729.142857142857, chars_format::fixed, 33, "1729.142857142857110375189222395420074"},
|
||||
{1729.142857142857, chars_format::fixed, 32, "1729.14285714285711037518922239542007"},
|
||||
{1729.142857142857, chars_format::fixed, 31, "1729.1428571428571103751892223954201"},
|
||||
{1729.142857142857, chars_format::fixed, 30, "1729.142857142857110375189222395420"},
|
||||
{1729.142857142857, chars_format::fixed, 29, "1729.14285714285711037518922239542"},
|
||||
{1729.142857142857, chars_format::fixed, 28, "1729.1428571428571103751892223954"},
|
||||
{1729.142857142857, chars_format::fixed, 27, "1729.142857142857110375189222395"},
|
||||
{1729.142857142857, chars_format::fixed, 26, "1729.14285714285711037518922240"},
|
||||
{1729.142857142857, chars_format::fixed, 25, "1729.1428571428571103751892224"},
|
||||
{1729.142857142857, chars_format::fixed, 24, "1729.142857142857110375189222"},
|
||||
{1729.142857142857, chars_format::fixed, 23, "1729.14285714285711037518922"},
|
||||
{1729.142857142857, chars_format::fixed, 22, "1729.1428571428571103751892"},
|
||||
{1729.142857142857, chars_format::fixed, 21, "1729.142857142857110375189"},
|
||||
{1729.142857142857, chars_format::fixed, 20, "1729.14285714285711037519"},
|
||||
{1729.142857142857, chars_format::fixed, 19, "1729.1428571428571103752"},
|
||||
{1729.142857142857, chars_format::fixed, 18, "1729.142857142857110375"},
|
||||
{1729.142857142857, chars_format::fixed, 17, "1729.14285714285711038"},
|
||||
{1729.142857142857, chars_format::fixed, 16, "1729.1428571428571104"},
|
||||
{1729.142857142857, chars_format::fixed, 15, "1729.142857142857110"},
|
||||
{1729.142857142857, chars_format::fixed, 14, "1729.14285714285711"},
|
||||
{1729.142857142857, chars_format::fixed, 13, "1729.1428571428571"},
|
||||
{1729.142857142857, chars_format::fixed, 12, "1729.142857142857"},
|
||||
{1729.142857142857, chars_format::fixed, 11, "1729.14285714286"},
|
||||
{1729.142857142857, chars_format::fixed, 10, "1729.1428571429"},
|
||||
{1729.142857142857, chars_format::fixed, 9, "1729.142857143"},
|
||||
{1729.142857142857, chars_format::fixed, 8, "1729.14285714"},
|
||||
{1729.142857142857, chars_format::fixed, 7, "1729.1428571"},
|
||||
{1729.142857142857, chars_format::fixed, 6, "1729.142857"},
|
||||
{1729.142857142857, chars_format::fixed, 5, "1729.14286"},
|
||||
{1729.142857142857, chars_format::fixed, 4, "1729.1429"},
|
||||
{1729.142857142857, chars_format::fixed, 3, "1729.143"},
|
||||
{1729.142857142857, chars_format::fixed, 2, "1729.14"},
|
||||
{1729.142857142857, chars_format::fixed, 1, "1729.1"},
|
||||
{1729.142857142857, chars_format::fixed, 0, "1729"},
|
||||
|
||||
// Negative precision requests 6 digits of precision.
|
||||
{1729.142857142857, chars_format::fixed, -1, "1729.142857"},
|
||||
{1729.142857142857, chars_format::fixed, -2, "1729.142857"},
|
||||
{1729.142857142857, chars_format::fixed, -3, "1729.142857"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest Carrying
|
||||
{0.0009, chars_format::fixed, 4, "0.0009"},
|
||||
{0.0009, chars_format::fixed, 3, "0.001"},
|
||||
{0.0029, chars_format::fixed, 4, "0.0029"},
|
||||
{0.0029, chars_format::fixed, 3, "0.003"},
|
||||
{0.0099, chars_format::fixed, 4, "0.0099"},
|
||||
{0.0099, chars_format::fixed, 3, "0.010"},
|
||||
{0.0299, chars_format::fixed, 4, "0.0299"},
|
||||
{0.0299, chars_format::fixed, 3, "0.030"},
|
||||
{0.0999, chars_format::fixed, 4, "0.0999"},
|
||||
{0.0999, chars_format::fixed, 3, "0.100"},
|
||||
{0.2999, chars_format::fixed, 4, "0.2999"},
|
||||
{0.2999, chars_format::fixed, 3, "0.300"},
|
||||
{0.9999, chars_format::fixed, 4, "0.9999"},
|
||||
{0.9999, chars_format::fixed, 3, "1.000"},
|
||||
{2.9999, chars_format::fixed, 4, "2.9999"},
|
||||
{2.9999, chars_format::fixed, 3, "3.000"},
|
||||
{9.9999, chars_format::fixed, 4, "9.9999"},
|
||||
{9.9999, chars_format::fixed, 3, "10.000"},
|
||||
{29.9999, chars_format::fixed, 4, "29.9999"},
|
||||
{29.9999, chars_format::fixed, 3, "30.000"},
|
||||
{99.9999, chars_format::fixed, 4, "99.9999"},
|
||||
{99.9999, chars_format::fixed, 3, "100.000"},
|
||||
{299.9999, chars_format::fixed, 4, "299.9999"},
|
||||
{299.9999, chars_format::fixed, 3, "300.000"},
|
||||
|
||||
{0.09, chars_format::fixed, 2, "0.09"},
|
||||
{0.09, chars_format::fixed, 1, "0.1"},
|
||||
{0.29, chars_format::fixed, 2, "0.29"},
|
||||
{0.29, chars_format::fixed, 1, "0.3"},
|
||||
{0.99, chars_format::fixed, 2, "0.99"},
|
||||
{0.99, chars_format::fixed, 1, "1.0"},
|
||||
{2.99, chars_format::fixed, 2, "2.99"},
|
||||
{2.99, chars_format::fixed, 1, "3.0"},
|
||||
{9.99, chars_format::fixed, 2, "9.99"},
|
||||
{9.99, chars_format::fixed, 1, "10.0"},
|
||||
{29.99, chars_format::fixed, 2, "29.99"},
|
||||
{29.99, chars_format::fixed, 1, "30.0"},
|
||||
{99.99, chars_format::fixed, 2, "99.99"},
|
||||
{99.99, chars_format::fixed, 1, "100.0"},
|
||||
{299.99, chars_format::fixed, 2, "299.99"},
|
||||
{299.99, chars_format::fixed, 1, "300.0"},
|
||||
|
||||
{0.9, chars_format::fixed, 1, "0.9"},
|
||||
{0.9, chars_format::fixed, 0, "1"},
|
||||
{2.9, chars_format::fixed, 1, "2.9"},
|
||||
{2.9, chars_format::fixed, 0, "3"},
|
||||
{9.9, chars_format::fixed, 1, "9.9"},
|
||||
{9.9, chars_format::fixed, 0, "10"},
|
||||
{29.9, chars_format::fixed, 1, "29.9"},
|
||||
{29.9, chars_format::fixed, 0, "30"},
|
||||
{99.9, chars_format::fixed, 1, "99.9"},
|
||||
{99.9, chars_format::fixed, 0, "100"},
|
||||
{299.9, chars_format::fixed, 1, "299.9"},
|
||||
{299.9, chars_format::fixed, 0, "300"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest RoundingResultZero
|
||||
{0.004, chars_format::fixed, 3, "0.004"},
|
||||
{0.004, chars_format::fixed, 2, "0.00"},
|
||||
{0.4, chars_format::fixed, 1, "0.4"},
|
||||
{0.4, chars_format::fixed, 0, "0"},
|
||||
{0.5, chars_format::fixed, 1, "0.5"},
|
||||
{0.5, chars_format::fixed, 0, "0"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2fixedTest Regression
|
||||
{7.018232e-82, chars_format::fixed, 6, "0.000000"},
|
||||
};
|
||||
|
||||
#endif // DOUBLE_FIXED_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,120 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef DOUBLE_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
||||
#define DOUBLE_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "test.hpp"
|
||||
using namespace std;
|
||||
|
||||
inline constexpr DoublePrecisionToCharsTestCase double_hex_precision_to_chars_test_cases[] = {
|
||||
// Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
|
||||
{0.0, chars_format::hex, 4, "0.0000p+0"},
|
||||
{-0.0, chars_format::hex, 4, "-0.0000p+0"},
|
||||
{double_inf, chars_format::hex, 4, "inf"},
|
||||
{-double_inf, chars_format::hex, 4, "-inf"},
|
||||
{double_nan, chars_format::hex, 4, "nan"},
|
||||
{-double_nan, chars_format::hex, 4, "-nan(ind)"},
|
||||
{double_nan_payload, chars_format::hex, 4, "nan"},
|
||||
{-double_nan_payload, chars_format::hex, 4, "-nan"},
|
||||
{0x1.729p+0, chars_format::hex, 4, "1.7290p+0"},
|
||||
{-0x1.729p+0, chars_format::hex, 4, "-1.7290p+0"},
|
||||
|
||||
// Test hexfloat corner cases.
|
||||
{0x1.728p+0, chars_format::hex, 13, "1.7280000000000p+0"},
|
||||
{0x0.0000000000001p-1022, chars_format::hex, 13, "0.0000000000001p-1022"}, // min subnormal
|
||||
{0x0.fffffffffffffp-1022, chars_format::hex, 13, "0.fffffffffffffp-1022"}, // max subnormal
|
||||
{0x1p-1022, chars_format::hex, 13, "1.0000000000000p-1022"}, // min normal
|
||||
{0x1.fffffffffffffp+1023, chars_format::hex, 13, "1.fffffffffffffp+1023"}, // max normal
|
||||
|
||||
// Test hexfloat exponents.
|
||||
{0x1p-1009, chars_format::hex, 0, "1p-1009"},
|
||||
{0x1p-999, chars_format::hex, 0, "1p-999"},
|
||||
{0x1p-99, chars_format::hex, 0, "1p-99"},
|
||||
{0x1p-9, chars_format::hex, 0, "1p-9"},
|
||||
{0x1p+0, chars_format::hex, 0, "1p+0"},
|
||||
{0x1p+9, chars_format::hex, 0, "1p+9"},
|
||||
{0x1p+99, chars_format::hex, 0, "1p+99"},
|
||||
{0x1p+999, chars_format::hex, 0, "1p+999"},
|
||||
{0x1p+1009, chars_format::hex, 0, "1p+1009"},
|
||||
|
||||
// Test hexfloat hexits.
|
||||
{0x1.01234567p+0, chars_format::hex, 8, "1.01234567p+0"},
|
||||
{0x1.89abcdefp+0, chars_format::hex, 8, "1.89abcdefp+0"},
|
||||
|
||||
// Test varying precision. Negative precision requests full precision, not shortest round-trip.
|
||||
{0x1.1234561234561p+0, chars_format::hex, -2, "1.1234561234561p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, -1, "1.1234561234561p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 1, "1.1p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 2, "1.12p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 3, "1.123p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 4, "1.1234p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 5, "1.12345p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 6, "1.123456p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 7, "1.1234561p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 8, "1.12345612p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 9, "1.123456123p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 10, "1.1234561234p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 11, "1.12345612345p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 12, "1.123456123456p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 13, "1.1234561234561p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 14, "1.12345612345610p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 15, "1.123456123456100p+0"},
|
||||
{0x1.1234561234561p+0, chars_format::hex, 16, "1.1234561234561000p+0"},
|
||||
|
||||
// Test rounding at every position.
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 1, "1.dp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 2, "1.cdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 3, "1.ccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 4, "1.cccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 5, "1.ccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 6, "1.cccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 7, "1.ccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 8, "1.cccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 9, "1.ccccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 10, "1.cccccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 11, "1.ccccccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 12, "1.cccccccccccdp+0"},
|
||||
{0x1.cccccccccccccp+0, chars_format::hex, 13, "1.cccccccccccccp+0"},
|
||||
|
||||
// Test all combinations of least significant bit, round bit, and trailing bits.
|
||||
{0x1.04000p+0, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0, Trailing 0
|
||||
{0x1.04001p+0, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0 and Trailing 1 in different hexits
|
||||
{0x1.04200p+0, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0 and Trailing 1 in same hexit
|
||||
{0x1.04800p+0, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 1, Trailing 0
|
||||
{0x1.04801p+0, chars_format::hex, 2, "1.05p+0"}, // Lsb 0, Round 1 and Trailing 1 in different hexits
|
||||
{0x1.04900p+0, chars_format::hex, 2, "1.05p+0"}, // Lsb 0, Round 1 and Trailing 1 in same hexit
|
||||
{0x1.05000p+0, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0, Trailing 0
|
||||
{0x1.05001p+0, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0 and Trailing 1 in different hexits
|
||||
{0x1.05200p+0, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0 and Trailing 1 in same hexit
|
||||
{0x1.05800p+0, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1, Trailing 0
|
||||
{0x1.05801p+0, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1 and Trailing 1 in different hexits
|
||||
{0x1.05900p+0, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1 and Trailing 1 in same hexit
|
||||
|
||||
// Test carry propagation.
|
||||
{0x1.0affffffffffep+0, chars_format::hex, 12, "1.0b0000000000p+0"},
|
||||
|
||||
// Test carry propagation into the leading hexit.
|
||||
{0x0.fffffffffffffp-1022, chars_format::hex, 12, "1.000000000000p-1022"},
|
||||
{0x1.fffffffffffffp+1023, chars_format::hex, 12, "2.000000000000p+1023"},
|
||||
|
||||
// Test how the leading hexit participates in the rounding decision.
|
||||
{0x0.000p+0, chars_format::hex, 0, "0p+0"},
|
||||
{0x0.001p-1022, chars_format::hex, 0, "0p-1022"},
|
||||
{0x0.200p-1022, chars_format::hex, 0, "0p-1022"},
|
||||
{0x0.800p-1022, chars_format::hex, 0, "0p-1022"},
|
||||
{0x0.801p-1022, chars_format::hex, 0, "1p-1022"},
|
||||
{0x0.900p-1022, chars_format::hex, 0, "1p-1022"},
|
||||
{0x1.000p+0, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.001p+0, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.200p+0, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.800p+0, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.801p+0, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.900p+0, chars_format::hex, 0, "2p+0"},
|
||||
};
|
||||
|
||||
#endif // DOUBLE_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
|
@ -1,327 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
// This file contains test cases derived from:
|
||||
// https://github.com/ulfjack/ryu
|
||||
// See xcharconv_ryu.h for the exact commit.
|
||||
// (Keep the cgmanifest.json commitHash in sync.)
|
||||
|
||||
|
||||
#ifndef DOUBLE_SCIENTIFIC_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
||||
#define DOUBLE_SCIENTIFIC_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "test.hpp"
|
||||
using namespace std;
|
||||
|
||||
inline constexpr DoublePrecisionToCharsTestCase double_scientific_precision_to_chars_test_cases_1[] = {
|
||||
// Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
|
||||
{0.0, chars_format::scientific, 4, "0.0000e+00"},
|
||||
{-0.0, chars_format::scientific, 4, "-0.0000e+00"},
|
||||
{double_inf, chars_format::scientific, 4, "inf"},
|
||||
{-double_inf, chars_format::scientific, 4, "-inf"},
|
||||
{double_nan, chars_format::scientific, 4, "nan"},
|
||||
{-double_nan, chars_format::scientific, 4, "-nan(ind)"},
|
||||
{double_nan_payload, chars_format::scientific, 4, "nan"},
|
||||
{-double_nan_payload, chars_format::scientific, 4, "-nan"},
|
||||
{1.729, chars_format::scientific, 4, "1.7290e+00"},
|
||||
{-1.729, chars_format::scientific, 4, "-1.7290e+00"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest Basic
|
||||
{0x1.000000001869fp+211, chars_format::scientific, 62,
|
||||
"3.29100911471548643542566484557342614975886952410844652587974656e+63"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest Zero
|
||||
{0.0, chars_format::scientific, 4, "0.0000e+00"},
|
||||
{0.0, chars_format::scientific, 3, "0.000e+00"},
|
||||
{0.0, chars_format::scientific, 2, "0.00e+00"},
|
||||
{0.0, chars_format::scientific, 1, "0.0e+00"},
|
||||
{0.0, chars_format::scientific, 0, "0e+00"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest MinMax
|
||||
{0x0.0000000000001p-1022, chars_format::scientific, 750,
|
||||
"4.9406564584124654417656879286822137236505980261432476442558568250067550727020875186529983"
|
||||
"636163599237979656469544571773092665671035593979639877479601078187812630071319031140452784"
|
||||
"581716784898210368871863605699873072305000638740915356498438731247339727316961514003171538"
|
||||
"539807412623856559117102665855668676818703956031062493194527159149245532930545654440112748"
|
||||
"012970999954193198940908041656332452475714786901472678015935523861155013480352649347201937"
|
||||
"902681071074917033322268447533357208324319360923828934583680601060115061698097530783422773"
|
||||
"183292479049825247307763759272478746560847782037344696995336470179726777175851256605511991"
|
||||
"315048911014510378627381672509558373897335989936648099411642057026370902792427675445652290"
|
||||
"87538682506419718265533447265625e-324"},
|
||||
|
||||
{0x1.fffffffffffffp+1023, chars_format::scientific, 308,
|
||||
"1.7976931348623157081452742373170435679807056752584499659891747680315726078002853876058955"
|
||||
"863276687817154045895351438246423432132688946418276846754670353751698604991057655128207624"
|
||||
"549009038932894407586850845513394230458323690322294816580855933212334827479782620414472316"
|
||||
"8738177180919299881250404026184124858368e+308"},
|
||||
|
||||
// Test more corner cases.
|
||||
{0x0.fffffffffffffp-1022, chars_format::scientific, 766,
|
||||
"2."
|
||||
"2250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309"
|
||||
"7809504343120858773871583572918219930202943792242235598198275012420417889695713117910822610439719796040004"
|
||||
"5489739193807919893608152561311337614984204327175103362739154978273159414382813627511383860409424946494228"
|
||||
"6316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515"
|
||||
"8661350412234790147923695852083215976210663754016137365830441936037147783553066828345356340050740730401356"
|
||||
"0296804637591858316312422452159926254649430083685186171942241764645513713542013221703137049658321015465406"
|
||||
"8035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317"
|
||||
"493580281734466552734375e-308"}, // max subnormal
|
||||
{0x1p-1022, chars_format::scientific, 714,
|
||||
"2."
|
||||
"2250738585072013830902327173324040642192159804623318305533274168872044348139181958542831590125110205640673"
|
||||
"3973103581100515243416155346010885601238537771882113077799353200233047961014744258363607192156504694250373"
|
||||
"4208375250806650616658158948720491179968591639648500635908770118304874799780887753749949451580451605050915"
|
||||
"3998565824708186451135379358049921159810857660519924333521143523901487956996095912888916029926415110634663"
|
||||
"1339366347758651302937176204732563178148566435087212282863764204484681140761391147706280168985324411002416"
|
||||
"1447421618567166150540154285084716752901903161322778896729707373123334086988983175067838846926092773977972"
|
||||
"858659654941091369095406136467568702398678315290680984617210924625396728515625e-308"}, // min normal
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest RoundToEven
|
||||
{0.125, chars_format::scientific, 2, "1.25e-01"},
|
||||
{0.125, chars_format::scientific, 1, "1.2e-01"},
|
||||
{0.375, chars_format::scientific, 2, "3.75e-01"},
|
||||
{0.375, chars_format::scientific, 1, "3.8e-01"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest RoundToEvenInteger
|
||||
{2.5, chars_format::scientific, 1, "2.5e+00"},
|
||||
{2.5, chars_format::scientific, 0, "2e+00"},
|
||||
{3.5, chars_format::scientific, 1, "3.5e+00"},
|
||||
{3.5, chars_format::scientific, 0, "4e+00"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest NonRoundToEvenScenarios
|
||||
{0.748046875, chars_format::scientific, 2, "7.48e-01"},
|
||||
{0.748046875, chars_format::scientific, 1, "7.5e-01"},
|
||||
{0.748046875, chars_format::scientific, 0, "7e-01"}, // 0.75 would round to "8e-01", but this is smaller
|
||||
|
||||
{0.2509765625, chars_format::scientific, 2, "2.51e-01"},
|
||||
{0.2509765625, chars_format::scientific, 1, "2.5e-01"},
|
||||
{0.2509765625, chars_format::scientific, 0, "3e-01"}, // 0.25 would round to "2e-01", but this is larger
|
||||
|
||||
{0x1.0000000000001p-2, chars_format::scientific, 53, "2.50000000000000055511151231257827021181583404541015625e-01"},
|
||||
{0x1.0000000000001p-2, chars_format::scientific, 2, "2.50e-01"},
|
||||
{0x1.0000000000001p-2, chars_format::scientific, 1, "2.5e-01"},
|
||||
{0x1.0000000000001p-2, chars_format::scientific, 0,
|
||||
"3e-01"}, // 0.25 would round to "2e-01", but this is larger (again)
|
||||
|
||||
// More rounding tests.
|
||||
{9.5, chars_format::scientific, 1, "9.5e+00"},
|
||||
{9.5, chars_format::scientific, 0, "1e+01"},
|
||||
{10.5, chars_format::scientific, 2, "1.05e+01"},
|
||||
{10.5, chars_format::scientific, 1, "1.0e+01"},
|
||||
|
||||
{1.241, chars_format::scientific, 3, "1.241e+00"},
|
||||
{1.241, chars_format::scientific, 1, "1.2e+00"},
|
||||
{1.251, chars_format::scientific, 3, "1.251e+00"},
|
||||
{1.251, chars_format::scientific, 1, "1.3e+00"},
|
||||
{1.261, chars_format::scientific, 3, "1.261e+00"},
|
||||
{1.261, chars_format::scientific, 1, "1.3e+00"},
|
||||
{1.341, chars_format::scientific, 3, "1.341e+00"},
|
||||
{1.341, chars_format::scientific, 1, "1.3e+00"},
|
||||
{1.351, chars_format::scientific, 3, "1.351e+00"},
|
||||
{1.351, chars_format::scientific, 1, "1.4e+00"},
|
||||
{1.361, chars_format::scientific, 3, "1.361e+00"},
|
||||
{1.361, chars_format::scientific, 1, "1.4e+00"},
|
||||
|
||||
{2.41, chars_format::scientific, 2, "2.41e+00"},
|
||||
{2.41, chars_format::scientific, 0, "2e+00"},
|
||||
{2.51, chars_format::scientific, 2, "2.51e+00"},
|
||||
{2.51, chars_format::scientific, 0, "3e+00"},
|
||||
{2.61, chars_format::scientific, 2, "2.61e+00"},
|
||||
{2.61, chars_format::scientific, 0, "3e+00"},
|
||||
{3.41, chars_format::scientific, 2, "3.41e+00"},
|
||||
{3.41, chars_format::scientific, 0, "3e+00"},
|
||||
{3.51, chars_format::scientific, 2, "3.51e+00"},
|
||||
{3.51, chars_format::scientific, 0, "4e+00"},
|
||||
{3.61, chars_format::scientific, 2, "3.61e+00"},
|
||||
{3.61, chars_format::scientific, 0, "4e+00"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest VaryingPrecision
|
||||
{1729.142857142857, chars_format::scientific, 50, "1.72914285714285711037518922239542007446289062500000e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 49, "1.7291428571428571103751892223954200744628906250000e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 48, "1.729142857142857110375189222395420074462890625000e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 47, "1.72914285714285711037518922239542007446289062500e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 46, "1.7291428571428571103751892223954200744628906250e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 45, "1.729142857142857110375189222395420074462890625e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 44, "1.72914285714285711037518922239542007446289062e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 43, "1.7291428571428571103751892223954200744628906e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 42, "1.729142857142857110375189222395420074462891e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 41, "1.72914285714285711037518922239542007446289e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 40, "1.7291428571428571103751892223954200744629e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 39, "1.729142857142857110375189222395420074463e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 38, "1.72914285714285711037518922239542007446e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 37, "1.7291428571428571103751892223954200745e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 36, "1.729142857142857110375189222395420074e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 35, "1.72914285714285711037518922239542007e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 34, "1.7291428571428571103751892223954201e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 33, "1.729142857142857110375189222395420e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 32, "1.72914285714285711037518922239542e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 31, "1.7291428571428571103751892223954e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 30, "1.729142857142857110375189222395e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 29, "1.72914285714285711037518922240e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 28, "1.7291428571428571103751892224e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 27, "1.729142857142857110375189222e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 26, "1.72914285714285711037518922e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 25, "1.7291428571428571103751892e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 24, "1.729142857142857110375189e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 23, "1.72914285714285711037519e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 22, "1.7291428571428571103752e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 21, "1.729142857142857110375e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 20, "1.72914285714285711038e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 19, "1.7291428571428571104e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 18, "1.729142857142857110e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 17, "1.72914285714285711e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 16, "1.7291428571428571e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 15, "1.729142857142857e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 14, "1.72914285714286e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 13, "1.7291428571429e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 12, "1.729142857143e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 11, "1.72914285714e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 10, "1.7291428571e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 9, "1.729142857e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 8, "1.72914286e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 7, "1.7291429e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 6, "1.729143e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 5, "1.72914e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 4, "1.7291e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 3, "1.729e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 2, "1.73e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 1, "1.7e+03"},
|
||||
{1729.142857142857, chars_format::scientific, 0, "2e+03"},
|
||||
|
||||
// Negative precision requests 6 digits of precision.
|
||||
{1729.142857142857, chars_format::scientific, -1, "1.729143e+03"},
|
||||
{1729.142857142857, chars_format::scientific, -2, "1.729143e+03"},
|
||||
{1729.142857142857, chars_format::scientific, -3, "1.729143e+03"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest Carrying
|
||||
{2.0009, chars_format::scientific, 4, "2.0009e+00"},
|
||||
{2.0009, chars_format::scientific, 3, "2.001e+00"},
|
||||
{2.0029, chars_format::scientific, 4, "2.0029e+00"},
|
||||
{2.0029, chars_format::scientific, 3, "2.003e+00"},
|
||||
{2.0099, chars_format::scientific, 4, "2.0099e+00"},
|
||||
{2.0099, chars_format::scientific, 3, "2.010e+00"},
|
||||
{2.0299, chars_format::scientific, 4, "2.0299e+00"},
|
||||
{2.0299, chars_format::scientific, 3, "2.030e+00"},
|
||||
{2.0999, chars_format::scientific, 4, "2.0999e+00"},
|
||||
{2.0999, chars_format::scientific, 3, "2.100e+00"},
|
||||
{2.2999, chars_format::scientific, 4, "2.2999e+00"},
|
||||
{2.2999, chars_format::scientific, 3, "2.300e+00"},
|
||||
{2.9999, chars_format::scientific, 4, "2.9999e+00"},
|
||||
{2.9999, chars_format::scientific, 3, "3.000e+00"},
|
||||
{9.9999, chars_format::scientific, 4, "9.9999e+00"},
|
||||
{9.9999, chars_format::scientific, 3, "1.000e+01"},
|
||||
|
||||
{2.09, chars_format::scientific, 2, "2.09e+00"},
|
||||
{2.09, chars_format::scientific, 1, "2.1e+00"},
|
||||
{2.29, chars_format::scientific, 2, "2.29e+00"},
|
||||
{2.29, chars_format::scientific, 1, "2.3e+00"},
|
||||
{2.99, chars_format::scientific, 2, "2.99e+00"},
|
||||
{2.99, chars_format::scientific, 1, "3.0e+00"},
|
||||
{9.99, chars_format::scientific, 2, "9.99e+00"},
|
||||
{9.99, chars_format::scientific, 1, "1.0e+01"},
|
||||
|
||||
{2.9, chars_format::scientific, 1, "2.9e+00"},
|
||||
{2.9, chars_format::scientific, 0, "3e+00"},
|
||||
{9.9, chars_format::scientific, 1, "9.9e+00"},
|
||||
{9.9, chars_format::scientific, 0, "1e+01"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest Exponents
|
||||
{9.99e-100, chars_format::scientific, 2, "9.99e-100"},
|
||||
{9.99e-99, chars_format::scientific, 2, "9.99e-99"},
|
||||
{9.99e-10, chars_format::scientific, 2, "9.99e-10"},
|
||||
{9.99e-09, chars_format::scientific, 2, "9.99e-09"},
|
||||
{9.99e-01, chars_format::scientific, 2, "9.99e-01"},
|
||||
{9.99e+00, chars_format::scientific, 2, "9.99e+00"},
|
||||
{9.99e+01, chars_format::scientific, 2, "9.99e+01"},
|
||||
{9.99e+09, chars_format::scientific, 2, "9.99e+09"},
|
||||
{9.99e+10, chars_format::scientific, 2, "9.99e+10"},
|
||||
{9.99e+99, chars_format::scientific, 2, "9.99e+99"},
|
||||
{9.99e+100, chars_format::scientific, 2, "9.99e+100"},
|
||||
|
||||
{9.99e-100, chars_format::scientific, 1, "1.0e-99"},
|
||||
{9.99e-99, chars_format::scientific, 1, "1.0e-98"},
|
||||
{9.99e-10, chars_format::scientific, 1, "1.0e-09"},
|
||||
{9.99e-09, chars_format::scientific, 1, "1.0e-08"},
|
||||
{9.99e-01, chars_format::scientific, 1, "1.0e+00"},
|
||||
{9.99e+00, chars_format::scientific, 1, "1.0e+01"},
|
||||
{9.99e+01, chars_format::scientific, 1, "1.0e+02"},
|
||||
{9.99e+09, chars_format::scientific, 1, "1.0e+10"},
|
||||
{9.99e+10, chars_format::scientific, 1, "1.0e+11"},
|
||||
{9.99e+99, chars_format::scientific, 1, "1.0e+100"},
|
||||
{9.99e+100, chars_format::scientific, 1, "1.0e+101"},
|
||||
|
||||
// Ryu Printf d2fixed_test.cc D2expTest PrintDecimalPoint
|
||||
// These values exercise each codepath.
|
||||
{1e+54, chars_format::scientific, 0, "1e+54"},
|
||||
{1e+54, chars_format::scientific, 1, "1.0e+54"},
|
||||
{1e-63, chars_format::scientific, 0, "1e-63"},
|
||||
{1e-63, chars_format::scientific, 1, "1.0e-63"},
|
||||
{1e+83, chars_format::scientific, 0, "1e+83"},
|
||||
{1e+83, chars_format::scientific, 1, "1.0e+83"},
|
||||
|
||||
// The UCRT had trouble with rounding this value. charconv was never affected, but let's test it anyways.
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 104,
|
||||
"1.09995565999999994887854821710219658911365648587951921896774663603198787416706536331386569598149846892544e+"
|
||||
"104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 18, "1.099955659999999949e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 17, "1.09995565999999995e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 16, "1.0999556599999999e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 15, "1.099955660000000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 14, "1.09995566000000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 13, "1.0999556600000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 12, "1.099955660000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 11, "1.09995566000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 10, "1.0999556600e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 9, "1.099955660e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 8, "1.09995566e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 7, "1.0999557e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 6, "1.099956e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 5, "1.09996e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 4, "1.1000e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 3, "1.100e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 2, "1.10e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 1, "1.1e+104"},
|
||||
{0x1.88e2d605edc3dp+345, chars_format::scientific, 0, "1e+104"},
|
||||
|
||||
// More cases that the UCRT had trouble with (e.g. DevCom-1093399).
|
||||
{0x1.8p+62, chars_format::scientific, 16, "6.9175290276410819e+18"},
|
||||
{0x1.0a2742p+17, chars_format::scientific, 5, "1.36271e+05"},
|
||||
{0x1.f8b0f962cdffbp+205, chars_format::scientific, 13, "1.0137595739223e+62"},
|
||||
{0x1.f8b0f962cdffbp+205, chars_format::scientific, 16, "1.0137595739222531e+62"},
|
||||
{0x1.f8b0f962cdffbp+205, chars_format::scientific, 50, "1.01375957392225305727423222620636224221808910954041e+62"},
|
||||
{0x1.f8b0f962cdffbp+205, chars_format::scientific, 54,
|
||||
"1.013759573922253057274232226206362242218089109540405973e+62"},
|
||||
};
|
||||
|
||||
#endif // DOUBLE_SCIENTIFIC_PRECISION_TO_CHARS_TEST_CASES_1_HPP
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,139 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef FLOAT_FROM_CHARS_TEST_CASES_HPP
|
||||
#define FLOAT_FROM_CHARS_TEST_CASES_HPP
|
||||
|
||||
#include <charconv>
|
||||
#include <stddef.h>
|
||||
#include <system_error>
|
||||
using namespace std;
|
||||
|
||||
inline constexpr FloatFromCharsTestCase float_from_chars_test_cases[] = {
|
||||
{"1.a0000400", chars_format::hex, 10, errc{}, 0x1.a00004p0f}, // exact
|
||||
{"1.a0000401", chars_format::hex, 10, errc{}, 0x1.a00004p0f}, // below midpoint, round down
|
||||
{"1.a0000500", chars_format::hex, 10, errc{}, 0x1.a00004p0f}, // midpoint, round down to even
|
||||
{"1.a0000501", chars_format::hex, 10, errc{}, 0x1.a00006p0f}, // above midpoint, round up
|
||||
{"1.a0000600", chars_format::hex, 10, errc{}, 0x1.a00006p0f}, // exact
|
||||
{"1.a0000601", chars_format::hex, 10, errc{}, 0x1.a00006p0f}, // below midpoint, round down
|
||||
{"1.a0000700", chars_format::hex, 10, errc{}, 0x1.a00008p0f}, // midpoint, round up to even
|
||||
{"1.a0000701", chars_format::hex, 10, errc{}, 0x1.a00008p0f}, // above midpoint, round up
|
||||
|
||||
{"1.0000040", chars_format::hex, 9, errc{}, 0x1.000004p0f}, // exact
|
||||
{"1.0000041", chars_format::hex, 9, errc{}, 0x1.000004p0f}, // below midpoint, round down
|
||||
{"1.0000050", chars_format::hex, 9, errc{}, 0x1.000004p0f}, // midpoint, round down to even
|
||||
{"1.0000051", chars_format::hex, 9, errc{}, 0x1.000006p0f}, // above midpoint, round up
|
||||
{"1.0000060", chars_format::hex, 9, errc{}, 0x1.000006p0f}, // exact
|
||||
{"1.0000061", chars_format::hex, 9, errc{}, 0x1.000006p0f}, // below midpoint, round down
|
||||
{"1.0000070", chars_format::hex, 9, errc{}, 0x1.000008p0f}, // midpoint, round up to even
|
||||
{"1.0000071", chars_format::hex, 9, errc{}, 0x1.000008p0f}, // above midpoint, round up
|
||||
|
||||
{"1.0000002384185791015625000000", chars_format::general, 30, errc{}, 0x1.000004p0f}, // exact
|
||||
{"1.0000002421438694000244140625", chars_format::general, 30, errc{}, 0x1.000004p0f}, // below midpoint, round down
|
||||
{"1.0000002980232238769531249999", chars_format::general, 30, errc{}, 0x1.000004p0f}, // below midpoint, round down
|
||||
{"1.0000002980232238769531250000", chars_format::general, 30, errc{},
|
||||
0x1.000004p0f}, // midpoint, round down to even
|
||||
{"1.0000002980232238769531250001", chars_format::general, 30, errc{}, 0x1.000006p0f}, // above midpoint, round up
|
||||
{"1.0000003017485141754150390625", chars_format::general, 30, errc{}, 0x1.000006p0f}, // above midpoint, round up
|
||||
{"1.0000003576278686523437500000", chars_format::general, 30, errc{}, 0x1.000006p0f}, // exact
|
||||
{"1.0000003613531589508056640625", chars_format::general, 30, errc{}, 0x1.000006p0f}, // below midpoint, round down
|
||||
{"1.0000004172325134277343749999", chars_format::general, 30, errc{}, 0x1.000006p0f}, // below midpoint, round down
|
||||
{"1.0000004172325134277343750000", chars_format::general, 30, errc{}, 0x1.000008p0f}, // midpoint, round up to even
|
||||
{"1.0000004172325134277343750001", chars_format::general, 30, errc{}, 0x1.000008p0f}, // above midpoint, round up
|
||||
{"1.0000004209578037261962890625", chars_format::general, 30, errc{}, 0x1.000008p0f}, // above midpoint, round up
|
||||
|
||||
// VSO-838635 "<charconv>: from_chars() mishandles certain subnormals"
|
||||
// This bug didn't actually affect float, but we should have similar test cases.
|
||||
// These values change on half-ulp boundaries:
|
||||
// 1 * 2^-150 ~= 7.01e-46 (half-ulp between zero and min subnormal)
|
||||
// 2 * 2^-150 ~= 1.40e-45 (min subnormal)
|
||||
// 3 * 2^-150 ~= 2.10e-45 (half-ulp between min subnormal and next subnormal)
|
||||
// 4 * 2^-150 ~= 2.80e-45 (next subnormal)
|
||||
{"6."
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"
|
||||
"6666666666666666666e-46",
|
||||
chars_format::scientific, 1006, errc::result_out_of_range, 0x0.000000p+0f},
|
||||
{"7."
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
||||
"7777777777777777777e-46",
|
||||
chars_format::scientific, 1006, errc{}, 0x0.000002p-126f},
|
||||
{"8."
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
|
||||
"8888888888888888888e-46",
|
||||
chars_format::scientific, 1006, errc{}, 0x0.000002p-126f},
|
||||
{"9."
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"9999999999999999999e-46",
|
||||
chars_format::scientific, 1006, errc{}, 0x0.000002p-126f},
|
||||
{"1."
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111e-45",
|
||||
chars_format::scientific, 1006, errc{}, 0x0.000002p-126f},
|
||||
{"2."
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
"2222222222222222222e-45",
|
||||
chars_format::scientific, 1006, errc{}, 0x0.000004p-126f},
|
||||
|
||||
// VSO-733765 "<charconv>: [Feedback] double std::from_chars behavior on exponent out of range"
|
||||
// LWG-3081 "Floating point from_chars API does not distinguish between overflow and underflow"
|
||||
// These test cases exercise every overflow/underflow codepath.
|
||||
{"1e+1000", chars_format::scientific, 7, errc::result_out_of_range, float_inf},
|
||||
{"1e-1000", chars_format::scientific, 7, errc::result_out_of_range, 0.0f},
|
||||
{"1.ffffffp+127", chars_format::hex, 13, errc::result_out_of_range, float_inf},
|
||||
{"1e+2000", chars_format::scientific, 7, errc::result_out_of_range, float_inf},
|
||||
{"1e-2000", chars_format::scientific, 7, errc::result_out_of_range, 0.0f},
|
||||
{"1e+9999", chars_format::scientific, 7, errc::result_out_of_range, float_inf},
|
||||
{"1e-9999", chars_format::scientific, 7, errc::result_out_of_range, 0.0f},
|
||||
{"10e+5199", chars_format::scientific, 8, errc::result_out_of_range, float_inf},
|
||||
{"0.001e-5199", chars_format::scientific, 11, errc::result_out_of_range, 0.0f},
|
||||
};
|
||||
|
||||
#endif // FLOAT_FROM_CHARS_TEST_CASES_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,106 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef FLOAT_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
||||
#define FLOAT_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "test.hpp"
|
||||
using namespace std;
|
||||
|
||||
inline constexpr FloatPrecisionToCharsTestCase float_hex_precision_to_chars_test_cases[] = {
|
||||
// Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
|
||||
{0.0f, chars_format::hex, 4, "0.0000p+0"},
|
||||
{-0.0f, chars_format::hex, 4, "-0.0000p+0"},
|
||||
{float_inf, chars_format::hex, 4, "inf"},
|
||||
{-float_inf, chars_format::hex, 4, "-inf"},
|
||||
{float_nan, chars_format::hex, 4, "nan"},
|
||||
{-float_nan, chars_format::hex, 4, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format::hex, 4, "nan"},
|
||||
{-float_nan_payload, chars_format::hex, 4, "-nan"},
|
||||
{0x1.729p+0f, chars_format::hex, 4, "1.7290p+0"},
|
||||
{-0x1.729p+0f, chars_format::hex, 4, "-1.7290p+0"},
|
||||
|
||||
// Test hexfloat corner cases.
|
||||
{0x1.728p+0f, chars_format::hex, 6, "1.728000p+0"},
|
||||
{0x0.000002p-126f, chars_format::hex, 6, "0.000002p-126"}, // min subnormal
|
||||
{0x0.fffffep-126f, chars_format::hex, 6, "0.fffffep-126"}, // max subnormal
|
||||
{0x1p-126f, chars_format::hex, 6, "1.000000p-126"}, // min normal
|
||||
{0x1.fffffep+127f, chars_format::hex, 6, "1.fffffep+127"}, // max normal
|
||||
|
||||
// Test hexfloat exponents.
|
||||
{0x1p-109f, chars_format::hex, 0, "1p-109"},
|
||||
{0x1p-99f, chars_format::hex, 0, "1p-99"},
|
||||
{0x1p-9f, chars_format::hex, 0, "1p-9"},
|
||||
{0x1p+0f, chars_format::hex, 0, "1p+0"},
|
||||
{0x1p+9f, chars_format::hex, 0, "1p+9"},
|
||||
{0x1p+99f, chars_format::hex, 0, "1p+99"},
|
||||
{0x1p+109f, chars_format::hex, 0, "1p+109"},
|
||||
|
||||
// Test hexfloat hexits.
|
||||
{0x1.0123p+0f, chars_format::hex, 4, "1.0123p+0"},
|
||||
{0x1.4567p+0f, chars_format::hex, 4, "1.4567p+0"},
|
||||
{0x1.89abp+0f, chars_format::hex, 4, "1.89abp+0"},
|
||||
{0x1.cdefp+0f, chars_format::hex, 4, "1.cdefp+0"},
|
||||
|
||||
// Test varying precision. Negative precision requests full precision, not shortest round-trip.
|
||||
{0x1.123456p+0f, chars_format::hex, -2, "1.123456p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, -1, "1.123456p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 1, "1.1p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 2, "1.12p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 3, "1.123p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 4, "1.1234p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 5, "1.12345p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 6, "1.123456p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 7, "1.1234560p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 8, "1.12345600p+0"},
|
||||
{0x1.123456p+0f, chars_format::hex, 9, "1.123456000p+0"},
|
||||
|
||||
// Test rounding at every position.
|
||||
{0x1.ccccccp+0f, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 1, "1.dp+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 2, "1.cdp+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 3, "1.ccdp+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 4, "1.cccdp+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 5, "1.ccccdp+0"},
|
||||
{0x1.ccccccp+0f, chars_format::hex, 6, "1.ccccccp+0"},
|
||||
|
||||
// Test all combinations of least significant bit, round bit, and trailing bits.
|
||||
{0x1.04000p+0f, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0, Trailing 0
|
||||
{0x1.04001p+0f, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0 and Trailing 1 in different hexits
|
||||
{0x1.04200p+0f, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 0 and Trailing 1 in same hexit
|
||||
{0x1.04800p+0f, chars_format::hex, 2, "1.04p+0"}, // Lsb 0, Round 1, Trailing 0
|
||||
{0x1.04801p+0f, chars_format::hex, 2, "1.05p+0"}, // Lsb 0, Round 1 and Trailing 1 in different hexits
|
||||
{0x1.04900p+0f, chars_format::hex, 2, "1.05p+0"}, // Lsb 0, Round 1 and Trailing 1 in same hexit
|
||||
{0x1.05000p+0f, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0, Trailing 0
|
||||
{0x1.05001p+0f, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0 and Trailing 1 in different hexits
|
||||
{0x1.05200p+0f, chars_format::hex, 2, "1.05p+0"}, // Lsb 1, Round 0 and Trailing 1 in same hexit
|
||||
{0x1.05800p+0f, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1, Trailing 0
|
||||
{0x1.05801p+0f, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1 and Trailing 1 in different hexits
|
||||
{0x1.05900p+0f, chars_format::hex, 2, "1.06p+0"}, // Lsb 1, Round 1 and Trailing 1 in same hexit
|
||||
|
||||
// Test carry propagation.
|
||||
{0x1.0afffep+0f, chars_format::hex, 5, "1.0b000p+0"},
|
||||
|
||||
// Test carry propagation into the leading hexit.
|
||||
{0x0.fffffep-126f, chars_format::hex, 5, "1.00000p-126"},
|
||||
{0x1.fffffep+127f, chars_format::hex, 5, "2.00000p+127"},
|
||||
|
||||
// Test how the leading hexit participates in the rounding decision.
|
||||
{0x0.000p+0f, chars_format::hex, 0, "0p+0"},
|
||||
{0x0.001p-126f, chars_format::hex, 0, "0p-126"},
|
||||
{0x0.200p-126f, chars_format::hex, 0, "0p-126"},
|
||||
{0x0.800p-126f, chars_format::hex, 0, "0p-126"},
|
||||
{0x0.801p-126f, chars_format::hex, 0, "1p-126"},
|
||||
{0x0.900p-126f, chars_format::hex, 0, "1p-126"},
|
||||
{0x1.000p+0f, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.001p+0f, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.200p+0f, chars_format::hex, 0, "1p+0"},
|
||||
{0x1.800p+0f, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.801p+0f, chars_format::hex, 0, "2p+0"},
|
||||
{0x1.900p+0f, chars_format::hex, 0, "2p+0"},
|
||||
};
|
||||
|
||||
#endif // FLOAT_HEX_PRECISION_TO_CHARS_TEST_CASES_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,541 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
|
||||
// Copyright 2018 Ulf Adams
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
// Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
// This file contains test cases derived from:
|
||||
// https://github.com/ulfjack/ryu
|
||||
// See xcharconv_ryu.h for the exact commit.
|
||||
// (Keep the cgmanifest.json commitHash in sync.)
|
||||
|
||||
|
||||
#ifndef FLOAT_TO_CHARS_TEST_CASES_HPP
|
||||
#define FLOAT_TO_CHARS_TEST_CASES_HPP
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "test.hpp"
|
||||
using namespace std;
|
||||
|
||||
inline constexpr FloatToCharsTestCase float_to_chars_test_cases[] = {
|
||||
// Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
|
||||
{0.0f, chars_format::scientific, "0e+00"},
|
||||
{-0.0f, chars_format::scientific, "-0e+00"},
|
||||
{float_inf, chars_format::scientific, "inf"},
|
||||
{-float_inf, chars_format::scientific, "-inf"},
|
||||
{float_nan, chars_format::scientific, "nan"},
|
||||
{-float_nan, chars_format::scientific, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format::scientific, "nan"},
|
||||
{-float_nan_payload, chars_format::scientific, "-nan"},
|
||||
{2.018f, chars_format::scientific, "2.018e+00"},
|
||||
{-2.018f, chars_format::scientific, "-2.018e+00"},
|
||||
|
||||
// Ditto for fixed, which doesn't emit exponents.
|
||||
{0.0f, chars_format::fixed, "0"},
|
||||
{-0.0f, chars_format::fixed, "-0"},
|
||||
{float_inf, chars_format::fixed, "inf"},
|
||||
{-float_inf, chars_format::fixed, "-inf"},
|
||||
{float_nan, chars_format::fixed, "nan"},
|
||||
{-float_nan, chars_format::fixed, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format::fixed, "nan"},
|
||||
{-float_nan_payload, chars_format::fixed, "-nan"},
|
||||
{2.018f, chars_format::fixed, "2.018"},
|
||||
{-2.018f, chars_format::fixed, "-2.018"},
|
||||
|
||||
// Ditto for general, which selects fixed for the scientific exponent 0.
|
||||
{0.0f, chars_format::general, "0"},
|
||||
{-0.0f, chars_format::general, "-0"},
|
||||
{float_inf, chars_format::general, "inf"},
|
||||
{-float_inf, chars_format::general, "-inf"},
|
||||
{float_nan, chars_format::general, "nan"},
|
||||
{-float_nan, chars_format::general, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format::general, "nan"},
|
||||
{-float_nan_payload, chars_format::general, "-nan"},
|
||||
{2.018f, chars_format::general, "2.018"},
|
||||
{-2.018f, chars_format::general, "-2.018"},
|
||||
|
||||
// Ditto for plain, which selects fixed because it's shorter for these values.
|
||||
{0.0f, chars_format{}, "0"},
|
||||
{-0.0f, chars_format{}, "-0"},
|
||||
{float_inf, chars_format{}, "inf"},
|
||||
{-float_inf, chars_format{}, "-inf"},
|
||||
{float_nan, chars_format{}, "nan"},
|
||||
{-float_nan, chars_format{}, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format{}, "nan"},
|
||||
{-float_nan_payload, chars_format{}, "-nan"},
|
||||
{2.018f, chars_format{}, "2.018"},
|
||||
{-2.018f, chars_format{}, "-2.018"},
|
||||
|
||||
// Ditto for hex.
|
||||
{0.0f, chars_format::hex, "0p+0"},
|
||||
{-0.0f, chars_format::hex, "-0p+0"},
|
||||
{float_inf, chars_format::hex, "inf"},
|
||||
{-float_inf, chars_format::hex, "-inf"},
|
||||
{float_nan, chars_format::hex, "nan"},
|
||||
{-float_nan, chars_format::hex, "-nan(ind)"},
|
||||
{float_nan_payload, chars_format::hex, "nan"},
|
||||
{-float_nan_payload, chars_format::hex, "-nan"},
|
||||
{0x1.729p+0f, chars_format::hex, "1.729p+0"},
|
||||
{-0x1.729p+0f, chars_format::hex, "-1.729p+0"},
|
||||
|
||||
// Ryu f2s_test.cc SwitchToSubnormal
|
||||
{1.1754944e-38f, chars_format::scientific, "1.1754944e-38"},
|
||||
|
||||
// Ryu f2s_test.cc MinAndMax
|
||||
{0x1.fffffep+127f, chars_format::scientific, "3.4028235e+38"},
|
||||
{0x1.000000p-149f, chars_format::scientific, "1e-45"},
|
||||
|
||||
// Ryu f2s_test.cc BoundaryRoundEven
|
||||
{3.355445e7f, chars_format::scientific, "3.355445e+07"},
|
||||
{8.999999e9f, chars_format::scientific, "9e+09"},
|
||||
{3.4366717e10f, chars_format::scientific, "3.436672e+10"},
|
||||
|
||||
// Ryu f2s_test.cc ExactValueRoundEven
|
||||
{3.0540412e5f, chars_format::scientific, "3.0540412e+05"},
|
||||
{8.0990312e3f, chars_format::scientific, "8.0990312e+03"},
|
||||
|
||||
// Ryu f2s_test.cc LotsOfTrailingZeros
|
||||
{2.4414062e-4f, chars_format::scientific, "2.4414062e-04"},
|
||||
{2.4414062e-3f, chars_format::scientific, "2.4414062e-03"},
|
||||
{4.3945312e-3f, chars_format::scientific, "4.3945312e-03"},
|
||||
{6.3476562e-3f, chars_format::scientific, "6.3476562e-03"},
|
||||
|
||||
// Ryu f2s_test.cc Regression
|
||||
{4.7223665e21f, chars_format::scientific, "4.7223665e+21"},
|
||||
{8388608.0f, chars_format::scientific, "8.388608e+06"},
|
||||
{1.6777216e7f, chars_format::scientific, "1.6777216e+07"},
|
||||
{3.3554436e7f, chars_format::scientific, "3.3554436e+07"},
|
||||
{6.7131496e7f, chars_format::scientific, "6.7131496e+07"},
|
||||
{1.9310392e-38f, chars_format::scientific, "1.9310392e-38"},
|
||||
{-2.47e-43f, chars_format::scientific, "-2.47e-43"},
|
||||
{1.993244e-38f, chars_format::scientific, "1.993244e-38"},
|
||||
{4103.9003f, chars_format::scientific, "4.1039004e+03"},
|
||||
{5.3399997e9f, chars_format::scientific, "5.3399997e+09"},
|
||||
{6.0898e-39f, chars_format::scientific, "6.0898e-39"},
|
||||
{0.0010310042f, chars_format::scientific, "1.0310042e-03"},
|
||||
{2.8823261e17f, chars_format::scientific, "2.882326e+17"},
|
||||
{0x1.5c87fap-84f, chars_format::scientific, "7.038531e-26"}, // TRANSITION, VSO-629490, should be 7.038531e-26f
|
||||
{9.2234038e17f, chars_format::scientific, "9.223404e+17"},
|
||||
{6.7108872e7f, chars_format::scientific, "6.710887e+07"},
|
||||
{1.0e-44f, chars_format::scientific, "1e-44"},
|
||||
{2.816025e14f, chars_format::scientific, "2.816025e+14"},
|
||||
{9.223372e18f, chars_format::scientific, "9.223372e+18"},
|
||||
{1.5846085e29f, chars_format::scientific, "1.5846086e+29"},
|
||||
{1.1811161e19f, chars_format::scientific, "1.1811161e+19"},
|
||||
{5.368709e18f, chars_format::scientific, "5.368709e+18"},
|
||||
{4.6143165e18f, chars_format::scientific, "4.6143166e+18"},
|
||||
{0.007812537f, chars_format::scientific, "7.812537e-03"},
|
||||
{1.4e-45f, chars_format::scientific, "1e-45"},
|
||||
{1.18697724e20f, chars_format::scientific, "1.18697725e+20"},
|
||||
{1.00014165e-36f, chars_format::scientific, "1.00014165e-36"},
|
||||
{200.0f, chars_format::scientific, "2e+02"},
|
||||
{3.3554432e7f, chars_format::scientific, "3.3554432e+07"},
|
||||
|
||||
// Ryu f2s_test.cc LooksLikePow5
|
||||
{0x1.2a05f2p+59f, chars_format::scientific, "6.7108864e+17"},
|
||||
{0x1.2a05f2p+60f, chars_format::scientific, "1.3421773e+18"},
|
||||
{0x1.2a05f2p+61f, chars_format::scientific, "2.6843546e+18"},
|
||||
|
||||
// Ryu f2s_test.cc OutputLength
|
||||
{1.0f, chars_format::scientific, "1e+00"},
|
||||
{1.2f, chars_format::scientific, "1.2e+00"},
|
||||
{1.23f, chars_format::scientific, "1.23e+00"},
|
||||
{1.234f, chars_format::scientific, "1.234e+00"},
|
||||
{1.2345f, chars_format::scientific, "1.2345e+00"},
|
||||
{1.23456f, chars_format::scientific, "1.23456e+00"},
|
||||
{1.234567f, chars_format::scientific, "1.234567e+00"},
|
||||
{1.2345678f, chars_format::scientific, "1.2345678e+00"},
|
||||
{1.23456735e-36f, chars_format::scientific, "1.23456735e-36"},
|
||||
|
||||
// Test all exponents.
|
||||
{1.729e-45f, chars_format::scientific, "1e-45"},
|
||||
{1.729e-44f, chars_format::scientific, "1.7e-44"},
|
||||
{1.729e-43f, chars_format::scientific, "1.72e-43"},
|
||||
{1.729e-42f, chars_format::scientific, "1.729e-42"},
|
||||
{1.729e-41f, chars_format::scientific, "1.729e-41"},
|
||||
{1.729e-40f, chars_format::scientific, "1.729e-40"},
|
||||
{1.729e-39f, chars_format::scientific, "1.729e-39"},
|
||||
{1.729e-38f, chars_format::scientific, "1.729e-38"},
|
||||
{1.729e-37f, chars_format::scientific, "1.729e-37"},
|
||||
{1.729e-36f, chars_format::scientific, "1.729e-36"},
|
||||
{1.729e-35f, chars_format::scientific, "1.729e-35"},
|
||||
{1.729e-34f, chars_format::scientific, "1.729e-34"},
|
||||
{1.729e-33f, chars_format::scientific, "1.729e-33"},
|
||||
{1.729e-32f, chars_format::scientific, "1.729e-32"},
|
||||
{1.729e-31f, chars_format::scientific, "1.729e-31"},
|
||||
{1.729e-30f, chars_format::scientific, "1.729e-30"},
|
||||
{1.729e-29f, chars_format::scientific, "1.729e-29"},
|
||||
{1.729e-28f, chars_format::scientific, "1.729e-28"},
|
||||
{1.729e-27f, chars_format::scientific, "1.729e-27"},
|
||||
{1.729e-26f, chars_format::scientific, "1.729e-26"},
|
||||
{1.729e-25f, chars_format::scientific, "1.729e-25"},
|
||||
{1.729e-24f, chars_format::scientific, "1.729e-24"},
|
||||
{1.729e-23f, chars_format::scientific, "1.729e-23"},
|
||||
{1.729e-22f, chars_format::scientific, "1.729e-22"},
|
||||
{1.729e-21f, chars_format::scientific, "1.729e-21"},
|
||||
{1.729e-20f, chars_format::scientific, "1.729e-20"},
|
||||
{1.729e-19f, chars_format::scientific, "1.729e-19"},
|
||||
{1.729e-18f, chars_format::scientific, "1.729e-18"},
|
||||
{1.729e-17f, chars_format::scientific, "1.729e-17"},
|
||||
{1.729e-16f, chars_format::scientific, "1.729e-16"},
|
||||
{1.729e-15f, chars_format::scientific, "1.729e-15"},
|
||||
{1.729e-14f, chars_format::scientific, "1.729e-14"},
|
||||
{1.729e-13f, chars_format::scientific, "1.729e-13"},
|
||||
{1.729e-12f, chars_format::scientific, "1.729e-12"},
|
||||
{1.729e-11f, chars_format::scientific, "1.729e-11"},
|
||||
{1.729e-10f, chars_format::scientific, "1.729e-10"},
|
||||
{1.729e-9f, chars_format::scientific, "1.729e-09"},
|
||||
{1.729e-8f, chars_format::scientific, "1.729e-08"},
|
||||
{1.729e-7f, chars_format::scientific, "1.729e-07"},
|
||||
{1.729e-6f, chars_format::scientific, "1.729e-06"},
|
||||
{1.729e-5f, chars_format::scientific, "1.729e-05"},
|
||||
{1.729e-4f, chars_format::scientific, "1.729e-04"},
|
||||
{1.729e-3f, chars_format::scientific, "1.729e-03"},
|
||||
{1.729e-2f, chars_format::scientific, "1.729e-02"},
|
||||
{1.729e-1f, chars_format::scientific, "1.729e-01"},
|
||||
{1.729e0f, chars_format::scientific, "1.729e+00"},
|
||||
{1.729e1f, chars_format::scientific, "1.729e+01"},
|
||||
{1.729e2f, chars_format::scientific, "1.729e+02"},
|
||||
{1.729e3f, chars_format::scientific, "1.729e+03"},
|
||||
{1.729e4f, chars_format::scientific, "1.729e+04"},
|
||||
{1.729e5f, chars_format::scientific, "1.729e+05"},
|
||||
{1.729e6f, chars_format::scientific, "1.729e+06"},
|
||||
{1.729e7f, chars_format::scientific, "1.729e+07"},
|
||||
{1.729e8f, chars_format::scientific, "1.729e+08"},
|
||||
{1.729e9f, chars_format::scientific, "1.729e+09"},
|
||||
{1.729e10f, chars_format::scientific, "1.729e+10"},
|
||||
{1.729e11f, chars_format::scientific, "1.729e+11"},
|
||||
{1.729e12f, chars_format::scientific, "1.729e+12"},
|
||||
{1.729e13f, chars_format::scientific, "1.729e+13"},
|
||||
{1.729e14f, chars_format::scientific, "1.729e+14"},
|
||||
{1.729e15f, chars_format::scientific, "1.729e+15"},
|
||||
{1.729e16f, chars_format::scientific, "1.729e+16"},
|
||||
{1.729e17f, chars_format::scientific, "1.729e+17"},
|
||||
{1.729e18f, chars_format::scientific, "1.729e+18"},
|
||||
{1.729e19f, chars_format::scientific, "1.729e+19"},
|
||||
{1.729e20f, chars_format::scientific, "1.729e+20"},
|
||||
{1.729e21f, chars_format::scientific, "1.729e+21"},
|
||||
{1.729e22f, chars_format::scientific, "1.729e+22"},
|
||||
{1.729e23f, chars_format::scientific, "1.729e+23"},
|
||||
{1.729e24f, chars_format::scientific, "1.729e+24"},
|
||||
{1.729e25f, chars_format::scientific, "1.729e+25"},
|
||||
{1.729e26f, chars_format::scientific, "1.729e+26"},
|
||||
{1.729e27f, chars_format::scientific, "1.729e+27"},
|
||||
{1.729e28f, chars_format::scientific, "1.729e+28"},
|
||||
{1.729e29f, chars_format::scientific, "1.729e+29"},
|
||||
{1.729e30f, chars_format::scientific, "1.729e+30"},
|
||||
{1.729e31f, chars_format::scientific, "1.729e+31"},
|
||||
{1.729e32f, chars_format::scientific, "1.729e+32"},
|
||||
{1.729e33f, chars_format::scientific, "1.729e+33"},
|
||||
{1.729e34f, chars_format::scientific, "1.729e+34"},
|
||||
{1.729e35f, chars_format::scientific, "1.729e+35"},
|
||||
{1.729e36f, chars_format::scientific, "1.729e+36"},
|
||||
{1.729e37f, chars_format::scientific, "1.729e+37"},
|
||||
{1.729e38f, chars_format::scientific, "1.729e+38"},
|
||||
|
||||
// Test all of the cases for fixed notation, including the non-Ryu fallback for large integers.
|
||||
{1.729e-4f, chars_format::fixed, "0.0001729"},
|
||||
{1.729e-3f, chars_format::fixed, "0.001729"},
|
||||
{1.729e-2f, chars_format::fixed, "0.01729"},
|
||||
{1.729e-1f, chars_format::fixed, "0.1729"},
|
||||
{1.729e0f, chars_format::fixed, "1.729"},
|
||||
{1.729e1f, chars_format::fixed, "17.29"},
|
||||
{1.729e2f, chars_format::fixed, "172.9"},
|
||||
{1.729e3f, chars_format::fixed, "1729"},
|
||||
{1.729e4f, chars_format::fixed, "17290"},
|
||||
{1.729e5f, chars_format::fixed, "172900"},
|
||||
{1.729e6f, chars_format::fixed, "1729000"},
|
||||
{1.729e7f, chars_format::fixed, "17290000"},
|
||||
{1.729e8f, chars_format::fixed, "172900000"},
|
||||
{1.729e9f, chars_format::fixed, "1728999936"},
|
||||
{1.729e10f, chars_format::fixed, "17290000384"},
|
||||
{1.729e11f, chars_format::fixed, "172900007936"},
|
||||
{1.729e12f, chars_format::fixed, "1728999981056"},
|
||||
{1.729e13f, chars_format::fixed, "17290000072704"},
|
||||
{1.729e14f, chars_format::fixed, "172899998629888"},
|
||||
{1.729e15f, chars_format::fixed, "1729000019853312"},
|
||||
{1.729e16f, chars_format::fixed, "17289999661662208"},
|
||||
{1.729e17f, chars_format::fixed, "172900007354040320"},
|
||||
{1.729e18f, chars_format::fixed, "1729000039180664832"},
|
||||
{1.729e19f, chars_format::fixed, "17289999567172927488"},
|
||||
{1.729e20f, chars_format::fixed, "172899997870752530432"},
|
||||
{1.729e21f, chars_format::fixed, "1729000013891897393152"},
|
||||
{1.729e22f, chars_format::fixed, "17290000138918973931520"},
|
||||
{1.729e23f, chars_format::fixed, "172899999137389925629952"},
|
||||
{1.729e24f, chars_format::fixed, "1729000063431493294227456"},
|
||||
{1.729e25f, chars_format::fixed, "17289999481393428335427584"},
|
||||
{1.729e26f, chars_format::fixed, "172900004037306320209051648"},
|
||||
{1.729e27f, chars_format::fixed, "1729000040373063202090516480"},
|
||||
{1.729e28f, chars_format::fixed, "17290000403730632020905164800"},
|
||||
{1.729e29f, chars_format::fixed, "172900004037306320209051648000"},
|
||||
{1.729e30f, chars_format::fixed, "1728999964815199476176193060864"},
|
||||
{1.729e31f, chars_format::fixed, "17290000252614904569076517961728"},
|
||||
{1.729e32f, chars_format::fixed, "172899990436890849544473432555520"},
|
||||
{1.729e33f, chars_format::fixed, "1729000059111413406117268687945728"},
|
||||
{1.729e34f, chars_format::fixed, "17290000281629124239827618154676224"},
|
||||
{1.729e35f, chars_format::fixed, "172899995388651006685994532152016896"},
|
||||
{1.729e36f, chars_format::fixed, "1728999993500591323992114118292144128"},
|
||||
{1.729e37f, chars_format::fixed, "17289999935005913239921141182921441280"},
|
||||
{1.729e38f, chars_format::fixed, "172899996814757931942752608835808002048"},
|
||||
|
||||
// Also test one-digit cases, where the decimal point can't appear between digits like "17.29".
|
||||
{7e-3f, chars_format::fixed, "0.007"},
|
||||
{7e-2f, chars_format::fixed, "0.07"},
|
||||
{7e-1f, chars_format::fixed, "0.7"},
|
||||
{7e0f, chars_format::fixed, "7"},
|
||||
{7e1f, chars_format::fixed, "70"},
|
||||
{7e2f, chars_format::fixed, "700"},
|
||||
{7e3f, chars_format::fixed, "7000"},
|
||||
|
||||
// Test the maximum value in fixed notation.
|
||||
{0x1.fffffep+127f, chars_format::fixed, "340282346638528859811704183484516925440"},
|
||||
|
||||
// Test highly-trimmed powers of 2.
|
||||
{0x1p118f, chars_format::fixed, "332306998946228968225951765070086144"},
|
||||
{0x1p118f, chars_format::scientific, "3.32307e+35"},
|
||||
{0x1p119f, chars_format::fixed, "664613997892457936451903530140172288"},
|
||||
{0x1p119f, chars_format::scientific, "6.64614e+35"},
|
||||
|
||||
// Test powers of 10 that are exactly representable.
|
||||
{1e0f, chars_format::fixed, "1"},
|
||||
{1e1f, chars_format::fixed, "10"},
|
||||
{1e2f, chars_format::fixed, "100"},
|
||||
{1e3f, chars_format::fixed, "1000"},
|
||||
{1e4f, chars_format::fixed, "10000"},
|
||||
{1e5f, chars_format::fixed, "100000"},
|
||||
{1e6f, chars_format::fixed, "1000000"},
|
||||
{1e7f, chars_format::fixed, "10000000"},
|
||||
{1e8f, chars_format::fixed, "100000000"},
|
||||
{1e9f, chars_format::fixed, "1000000000"},
|
||||
{1e10f, chars_format::fixed, "10000000000"},
|
||||
|
||||
// Test powers of 10 that aren't exactly representable.
|
||||
// This exercises the "adjustment" code.
|
||||
{1e11f, chars_format::fixed, "99999997952"},
|
||||
{1e12f, chars_format::fixed, "999999995904"},
|
||||
{1e13f, chars_format::fixed, "9999999827968"},
|
||||
{1e14f, chars_format::fixed, "100000000376832"},
|
||||
{1e15f, chars_format::fixed, "999999986991104"},
|
||||
{1e16f, chars_format::fixed, "10000000272564224"},
|
||||
{1e17f, chars_format::fixed, "99999998430674944"},
|
||||
{1e18f, chars_format::fixed, "999999984306749440"},
|
||||
{1e19f, chars_format::fixed, "9999999980506447872"},
|
||||
{1e20f, chars_format::fixed, "100000002004087734272"},
|
||||
{1e21f, chars_format::fixed, "1000000020040877342720"},
|
||||
{1e22f, chars_format::fixed, "9999999778196308361216"},
|
||||
{1e23f, chars_format::fixed, "99999997781963083612160"},
|
||||
{1e24f, chars_format::fixed, "1000000013848427855085568"},
|
||||
{1e25f, chars_format::fixed, "9999999562023526247432192"},
|
||||
{1e26f, chars_format::fixed, "100000002537764290115403776"},
|
||||
{1e27f, chars_format::fixed, "999999988484154753734934528"},
|
||||
{1e28f, chars_format::fixed, "9999999442119689768320106496"},
|
||||
{1e29f, chars_format::fixed, "100000001504746621987668885504"},
|
||||
{1e30f, chars_format::fixed, "1000000015047466219876688855040"},
|
||||
{1e31f, chars_format::fixed, "9999999848243207295109594873856"},
|
||||
{1e32f, chars_format::fixed, "100000003318135351409612647563264"},
|
||||
{1e33f, chars_format::fixed, "999999994495727286427992885035008"},
|
||||
{1e34f, chars_format::fixed, "9999999790214767953607394487959552"},
|
||||
{1e35f, chars_format::fixed, "100000004091847875962975319375216640"},
|
||||
{1e36f, chars_format::fixed, "999999961690316245365415600208216064"},
|
||||
{1e37f, chars_format::fixed, "9999999933815812510711506376257961984"},
|
||||
{1e38f, chars_format::fixed, "99999996802856924650656260769173209088"},
|
||||
|
||||
// These numbers have odd mantissas (unaffected by shifting)
|
||||
// that are barely within the "max shifted mantissa" limit.
|
||||
// They're exactly-representable multiples of powers of 10, and can use Ryu with zero-filling.
|
||||
{3355443e1f, chars_format::fixed, "33554430"},
|
||||
{671087e2f, chars_format::fixed, "67108700"},
|
||||
{134217e3f, chars_format::fixed, "134217000"},
|
||||
{26843e4f, chars_format::fixed, "268430000"},
|
||||
{5367e5f, chars_format::fixed, "536700000"},
|
||||
{1073e6f, chars_format::fixed, "1073000000"},
|
||||
{213e7f, chars_format::fixed, "2130000000"},
|
||||
{41e8f, chars_format::fixed, "4100000000"},
|
||||
{7e9f, chars_format::fixed, "7000000000"},
|
||||
{1e10f, chars_format::fixed, "10000000000"},
|
||||
|
||||
// These numbers have odd mantissas (unaffected by shifting)
|
||||
// that are barely above the "max shifted mantissa" limit.
|
||||
// This activates the non-Ryu fallback for large integers.
|
||||
{3355445e1f, chars_format::fixed, "33554448"},
|
||||
{671089e2f, chars_format::fixed, "67108896"},
|
||||
{134219e3f, chars_format::fixed, "134219008"},
|
||||
{26845e4f, chars_format::fixed, "268449984"},
|
||||
{5369e5f, chars_format::fixed, "536899968"},
|
||||
{1075e6f, chars_format::fixed, "1075000064"},
|
||||
{215e7f, chars_format::fixed, "2150000128"},
|
||||
{43e8f, chars_format::fixed, "4300000256"},
|
||||
{9e9f, chars_format::fixed, "8999999488"},
|
||||
{3e10f, chars_format::fixed, "30000001024"},
|
||||
|
||||
// Test the mantissa shifting logic.
|
||||
{5495808e5f, chars_format::fixed, "549580800000"}, // 5367 * 2^10
|
||||
{5497856e5f, chars_format::fixed, "549785567232"}, // 5369 * 2^10
|
||||
|
||||
// Inspect all of those numbers in scientific notation.
|
||||
// For the within-limit numbers, this verifies that Ryu is actually being used with zero-filling above.
|
||||
// For the above-limit numbers, this tests Ryu's trimming.
|
||||
{3355443e1f, chars_format::scientific, "3.355443e+07"},
|
||||
{671087e2f, chars_format::scientific, "6.71087e+07"},
|
||||
{134217e3f, chars_format::scientific, "1.34217e+08"},
|
||||
{26843e4f, chars_format::scientific, "2.6843e+08"},
|
||||
{5367e5f, chars_format::scientific, "5.367e+08"},
|
||||
{1073e6f, chars_format::scientific, "1.073e+09"},
|
||||
{213e7f, chars_format::scientific, "2.13e+09"},
|
||||
{41e8f, chars_format::scientific, "4.1e+09"},
|
||||
{7e9f, chars_format::scientific, "7e+09"},
|
||||
{1e10f, chars_format::scientific, "1e+10"},
|
||||
{3355445e1f, chars_format::scientific, "3.355445e+07"},
|
||||
{671089e2f, chars_format::scientific, "6.71089e+07"},
|
||||
{134219e3f, chars_format::scientific, "1.34219e+08"},
|
||||
{26845e4f, chars_format::scientific, "2.6845e+08"},
|
||||
{5369e5f, chars_format::scientific, "5.369e+08"},
|
||||
{1075e6f, chars_format::scientific, "1.075e+09"},
|
||||
{215e7f, chars_format::scientific, "2.15e+09"},
|
||||
{43e8f, chars_format::scientific, "4.3e+09"},
|
||||
{9e9f, chars_format::scientific, "9e+09"},
|
||||
{3e10f, chars_format::scientific, "3e+10"},
|
||||
{5495808e5f, chars_format::scientific, "5.495808e+11"},
|
||||
{5497856e5f, chars_format::scientific, "5.497856e+11"},
|
||||
|
||||
// Test the switching logic of chars_format::general.
|
||||
// C11 7.21.6.1 "The fprintf function"/8:
|
||||
// "Let P equal [...] 6 if the precision is omitted [...].
|
||||
// Then, if a conversion with style E would have an exponent of X:
|
||||
// - if P > X >= -4, the conversion is with style f [...].
|
||||
// - otherwise, the conversion is with style e [...]."
|
||||
{1e-6f, chars_format::general, "1e-06"},
|
||||
{1e-5f, chars_format::general, "1e-05"},
|
||||
{1e-4f, chars_format::general, "0.0001"},
|
||||
{1e-3f, chars_format::general, "0.001"},
|
||||
{1e-2f, chars_format::general, "0.01"},
|
||||
{1e-1f, chars_format::general, "0.1"},
|
||||
{1e0f, chars_format::general, "1"},
|
||||
{1e1f, chars_format::general, "10"},
|
||||
{1e2f, chars_format::general, "100"},
|
||||
{1e3f, chars_format::general, "1000"},
|
||||
{1e4f, chars_format::general, "10000"},
|
||||
{1e5f, chars_format::general, "100000"},
|
||||
{1e6f, chars_format::general, "1e+06"},
|
||||
{1e7f, chars_format::general, "1e+07"},
|
||||
{1.234e-6f, chars_format::general, "1.234e-06"},
|
||||
{1.234e-5f, chars_format::general, "1.234e-05"},
|
||||
{1.234e-4f, chars_format::general, "0.0001234"},
|
||||
{1.234e-3f, chars_format::general, "0.001234"},
|
||||
{1.234e-2f, chars_format::general, "0.01234"},
|
||||
{1.234e-1f, chars_format::general, "0.1234"},
|
||||
{1.234e0f, chars_format::general, "1.234"},
|
||||
{1.234e1f, chars_format::general, "12.34"},
|
||||
{1.234e2f, chars_format::general, "123.4"},
|
||||
{1.234e3f, chars_format::general, "1234"},
|
||||
{1.234e4f, chars_format::general, "12340"},
|
||||
{1.234e5f, chars_format::general, "123400"},
|
||||
{1.234e6f, chars_format::general, "1.234e+06"},
|
||||
{1.234e7f, chars_format::general, "1.234e+07"},
|
||||
{1.234e8f, chars_format::general, "1.234e+08"},
|
||||
{1.234e9f, chars_format::general, "1.234e+09"},
|
||||
{1.234e10f, chars_format::general, "1.234e+10"},
|
||||
|
||||
// Test the switching logic of the plain overload.
|
||||
// N4762 19.19.2 [charconv.to.chars]/8:
|
||||
// "The conversion specifier is f or e, chosen according to the requirement
|
||||
// for a shortest representation (see above); a tie is resolved in favor of f."
|
||||
{1e-6f, chars_format{}, "1e-06"},
|
||||
{1e-5f, chars_format{}, "1e-05"},
|
||||
{1e-4f, chars_format{}, "1e-04"},
|
||||
{1e-3f, chars_format{}, "0.001"},
|
||||
{1e-2f, chars_format{}, "0.01"},
|
||||
{1e-1f, chars_format{}, "0.1"},
|
||||
{1e0f, chars_format{}, "1"},
|
||||
{1e1f, chars_format{}, "10"},
|
||||
{1e2f, chars_format{}, "100"},
|
||||
{1e3f, chars_format{}, "1000"},
|
||||
{1e4f, chars_format{}, "10000"},
|
||||
{1e5f, chars_format{}, "1e+05"},
|
||||
{1e6f, chars_format{}, "1e+06"},
|
||||
{1e7f, chars_format{}, "1e+07"},
|
||||
{1.234e-6f, chars_format{}, "1.234e-06"},
|
||||
{1.234e-5f, chars_format{}, "1.234e-05"},
|
||||
{1.234e-4f, chars_format{}, "0.0001234"},
|
||||
{1.234e-3f, chars_format{}, "0.001234"},
|
||||
{1.234e-2f, chars_format{}, "0.01234"},
|
||||
{1.234e-1f, chars_format{}, "0.1234"},
|
||||
{1.234e0f, chars_format{}, "1.234"},
|
||||
{1.234e1f, chars_format{}, "12.34"},
|
||||
{1.234e2f, chars_format{}, "123.4"},
|
||||
{1.234e3f, chars_format{}, "1234"},
|
||||
{1.234e4f, chars_format{}, "12340"},
|
||||
{1.234e5f, chars_format{}, "123400"},
|
||||
{1.234e6f, chars_format{}, "1234000"},
|
||||
{1.234e7f, chars_format{}, "12340000"},
|
||||
{1.234e8f, chars_format{}, "123400000"},
|
||||
{1.234e9f, chars_format{}, "1.234e+09"},
|
||||
{1.234e10f, chars_format{}, "1.234e+10"},
|
||||
|
||||
// Test hexfloat corner cases.
|
||||
{0x1.728p+0f, chars_format::hex, "1.728p+0"}, // instead of "2.e5p-1"
|
||||
{0x0.000002p-126f, chars_format::hex, "0.000002p-126"}, // instead of "1p-149", min subnormal
|
||||
{0x0.fffffep-126f, chars_format::hex, "0.fffffep-126"}, // max subnormal
|
||||
{0x1p-126f, chars_format::hex, "1p-126"}, // min normal
|
||||
{0x1.fffffep+127f, chars_format::hex, "1.fffffep+127"}, // max normal
|
||||
|
||||
// Test hexfloat exponents.
|
||||
{0x1p-109f, chars_format::hex, "1p-109"},
|
||||
{0x1p-99f, chars_format::hex, "1p-99"},
|
||||
{0x1p-9f, chars_format::hex, "1p-9"},
|
||||
{0x1p+0f, chars_format::hex, "1p+0"},
|
||||
{0x1p+9f, chars_format::hex, "1p+9"},
|
||||
{0x1p+99f, chars_format::hex, "1p+99"},
|
||||
{0x1p+109f, chars_format::hex, "1p+109"},
|
||||
|
||||
// Test hexfloat hexits.
|
||||
{0x1.0123p+0f, chars_format::hex, "1.0123p+0"},
|
||||
{0x1.4567p+0f, chars_format::hex, "1.4567p+0"},
|
||||
{0x1.89abp+0f, chars_format::hex, "1.89abp+0"},
|
||||
{0x1.cdefp+0f, chars_format::hex, "1.cdefp+0"},
|
||||
|
||||
// Test hexfloat trimming.
|
||||
{0x1.00000ap+0f, chars_format::hex, "1.00000ap+0"},
|
||||
{0x1.0000ap+0f, chars_format::hex, "1.0000ap+0"},
|
||||
{0x1.000ap+0f, chars_format::hex, "1.000ap+0"},
|
||||
{0x1.00ap+0f, chars_format::hex, "1.00ap+0"},
|
||||
{0x1.0ap+0f, chars_format::hex, "1.0ap+0"},
|
||||
{0x1.ap+0f, chars_format::hex, "1.ap+0"},
|
||||
{0x1p+0f, chars_format::hex, "1p+0"},
|
||||
|
||||
// https://www.exploringbinary.com/the-shortest-decimal-string-that-round-trips-may-not-be-the-nearest/
|
||||
// This is an exhaustive list of anomalous values.
|
||||
// (See double_to_chars_test_cases.hpp for more details.)
|
||||
{0x1p90f, chars_format::scientific, "1.2379401e+27"},
|
||||
{0x1p87f, chars_format::scientific, "1.5474251e+26"},
|
||||
{0x1p-96f, chars_format::scientific, "1.2621775e-29"},
|
||||
};
|
||||
|
||||
#endif // FLOAT_TO_CHARS_TEST_CASES_HPP
|
|
@ -1,278 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef FLOATING_POINT_TEST_CASES_HPP
|
||||
#define FLOATING_POINT_TEST_CASES_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utility>
|
||||
|
||||
constexpr std::pair<const char*, uint64_t> floating_point_test_cases_double[] = {
|
||||
// Verify small exactly-representable integers:
|
||||
{"1", 0x3FF0000000000000ULL},
|
||||
{"2", 0x4000000000000000ULL},
|
||||
{"3", 0x4008000000000000ULL},
|
||||
{"4", 0x4010000000000000ULL},
|
||||
{"5", 0x4014000000000000ULL},
|
||||
{"6", 0x4018000000000000ULL},
|
||||
{"7", 0x401C000000000000ULL},
|
||||
{"8", 0x4020000000000000ULL},
|
||||
|
||||
// Verify large exactly-representable integers:
|
||||
{"9007199254740984", 0x433FFFFFFFFFFFF8ULL},
|
||||
{"9007199254740985", 0x433FFFFFFFFFFFF9ULL},
|
||||
{"9007199254740986", 0x433FFFFFFFFFFFFAULL},
|
||||
{"9007199254740987", 0x433FFFFFFFFFFFFBULL},
|
||||
{"9007199254740988", 0x433FFFFFFFFFFFFCULL},
|
||||
{"9007199254740989", 0x433FFFFFFFFFFFFDULL},
|
||||
{"9007199254740990", 0x433FFFFFFFFFFFFEULL},
|
||||
{"9007199254740991", 0x433FFFFFFFFFFFFFULL}, // 2^53 - 1
|
||||
|
||||
// Verify the smallest denormal values:
|
||||
{"5.0e-324", 0x0000000000000001ULL},
|
||||
{"1.0e-323", 0x0000000000000002ULL},
|
||||
{"1.5e-323", 0x0000000000000003ULL},
|
||||
{"2.0e-323", 0x0000000000000004ULL},
|
||||
{"2.5e-323", 0x0000000000000005ULL},
|
||||
{"3.0e-323", 0x0000000000000006ULL},
|
||||
{"3.5e-323", 0x0000000000000007ULL},
|
||||
{"4.0e-323", 0x0000000000000008ULL},
|
||||
{"4.5e-323", 0x0000000000000009ULL},
|
||||
{"5.0e-323", 0x000000000000000AULL},
|
||||
{"5.5e-323", 0x000000000000000BULL},
|
||||
{"6.0e-323", 0x000000000000000CULL},
|
||||
{"6.5e-323", 0x000000000000000DULL},
|
||||
{"7.0e-323", 0x000000000000000EULL},
|
||||
{"7.5e-323", 0x000000000000000FULL},
|
||||
|
||||
// Verify the largest denormal values:
|
||||
{"2.2250738585071935e-308", 0x000FFFFFFFFFFFF0ULL},
|
||||
{"2.2250738585071940e-308", 0x000FFFFFFFFFFFF1ULL},
|
||||
{"2.2250738585071945e-308", 0x000FFFFFFFFFFFF2ULL},
|
||||
{"2.2250738585071950e-308", 0x000FFFFFFFFFFFF3ULL},
|
||||
{"2.2250738585071955e-308", 0x000FFFFFFFFFFFF4ULL},
|
||||
{"2.2250738585071960e-308", 0x000FFFFFFFFFFFF5ULL},
|
||||
{"2.2250738585071964e-308", 0x000FFFFFFFFFFFF6ULL},
|
||||
{"2.2250738585071970e-308", 0x000FFFFFFFFFFFF7ULL},
|
||||
{"2.2250738585071974e-308", 0x000FFFFFFFFFFFF8ULL},
|
||||
{"2.2250738585071980e-308", 0x000FFFFFFFFFFFF9ULL},
|
||||
{"2.2250738585071984e-308", 0x000FFFFFFFFFFFFAULL},
|
||||
{"2.2250738585071990e-308", 0x000FFFFFFFFFFFFBULL},
|
||||
{"2.2250738585071994e-308", 0x000FFFFFFFFFFFFCULL},
|
||||
{"2.2250738585072000e-308", 0x000FFFFFFFFFFFFDULL},
|
||||
{"2.2250738585072004e-308", 0x000FFFFFFFFFFFFEULL},
|
||||
{"2.2250738585072010e-308", 0x000FFFFFFFFFFFFFULL},
|
||||
|
||||
// DevDiv#576315 "I/O library incorrect rounds floating point numbers on input"
|
||||
// DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some
|
||||
// denormals"
|
||||
// DevDiv#730414 "iostreams is still misparsing floating-point"
|
||||
// DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++
|
||||
// compiler"
|
||||
// DevDiv#961116 "floating point string conversion accuracy"
|
||||
{"2.2250738585072014e-308", 0x0010000000000000ULL}, // DBL_MIN
|
||||
{"1.7976931348623158e+308", 0x7FEFFFFFFFFFFFFFULL}, // DBL_MAX
|
||||
{"4.26144921954407e-309", 0x00031076B2F00000ULL},
|
||||
{"179.9999999999999855", 0x40667FFFFFFFFFFFULL},
|
||||
{"4.1", 0x4010666666666666ULL},
|
||||
{"0.2288884", 0x3FCD4C37103785A8ULL},
|
||||
{"0.168", 0x3FC5810624DD2F1BULL},
|
||||
{"1.68", 0x3FFAE147AE147AE1ULL},
|
||||
{"16.80000001", 0x4030CCCCCCF7BFEBULL},
|
||||
|
||||
// Test cases from Rick Regan's article, "Incorrectly Rounded Conversions in Visual C++":
|
||||
// https://www.exploringbinary.com/incorrectly-rounded-conversions-in-visual-c-plus-plus/
|
||||
|
||||
// Example 1:
|
||||
{"9214843084008499", 0x43405E6CEC57761AULL},
|
||||
|
||||
// Example 2 (2^-1 + 2^-53 + 2^-54):
|
||||
{"0.500000000000000166533453693773481063544750213623046875", 0x3FE0000000000002ULL},
|
||||
|
||||
// Example 3:
|
||||
{"30078505129381147446200", 0x44997A3C7271B021ULL},
|
||||
|
||||
// Example 4:
|
||||
{"1777820000000000000001", 0x4458180D5BAD2E3EULL},
|
||||
|
||||
// Example 5 (2^-1 + 2^-53 + 2^-54 + 2^-66):
|
||||
{"0.500000000000000166547006220929549868969843373633921146392822265625", 0x3FE0000000000002ULL},
|
||||
|
||||
// Example 6 (2^-1 + 2^-53 + 2^-54 + 2^-65):
|
||||
{"0.50000000000000016656055874808561867439493653364479541778564453125", 0x3FE0000000000002ULL},
|
||||
|
||||
// Example 7:
|
||||
{"0.3932922657273", 0x3FD92BB352C4623AULL},
|
||||
|
||||
// The following test cases are taken from other articles on Rick Regan's
|
||||
// Exploring Binary blog. These are conversions that other implementations
|
||||
// were found to perform incorrectly.
|
||||
|
||||
// https://www.exploringbinary.com/incorrectly-rounded-subnormal-conversions-in-java/
|
||||
// Example 1 (2^-1047 + 2^-1075, half-ulp above a power of two):
|
||||
{"6.6312368714697582767853966302759672433990999473553031442499717587"
|
||||
"362866301392654396180682007880487441059604205526018528897150063763"
|
||||
"256665955396033303618005191075917832333584923372080578494993608994"
|
||||
"251286407188566165030934449228547591599881603044399098682919739314"
|
||||
"266256986631577498362522745234853124423586512070512924530832781161"
|
||||
"439325697279187097860044978723221938561502254152119972830784963194"
|
||||
"121246401117772161481107528151017752957198119743384519360959074196"
|
||||
"224175384736794951486324803914359317679811223967034438033355297560"
|
||||
"033532098300718322306892013830155987921841729099279241763393155074"
|
||||
"022348361207309147831684007154624400538175927027662135590421159867"
|
||||
"638194826541287705957668068727833491469671712939495988506756821156"
|
||||
"96218943412532098591327667236328125E-316",
|
||||
0x0000000008000000ULL},
|
||||
|
||||
// Example 2 (2^-1058 - 2^-1075, half-ulp below a power of two):
|
||||
{"3.2378839133029012895883524125015321748630376694231080599012970495"
|
||||
"523019706706765657868357425877995578606157765598382834355143910841"
|
||||
"531692526891905643964595773946180389283653051434639551003566966656"
|
||||
"292020173313440317300443693602052583458034314716600326995807313009"
|
||||
"548483639755486900107515300188817581841745696521731104736960227499"
|
||||
"346384253806233697747365600089974040609674980283891918789639685754"
|
||||
"392222064169814626901133425240027243859416510512935526014211553334"
|
||||
"302252372915238433223313261384314778235911424088000307751706259156"
|
||||
"707286570031519536642607698224949379518458015308952384398197084033"
|
||||
"899378732414634842056080000272705311068273879077914449185347715987"
|
||||
"501628125488627684932015189916680282517302999531439241685457086639"
|
||||
"13273994694463908672332763671875E-319",
|
||||
0x0000000000010000ULL},
|
||||
|
||||
// Example 3 (2^-1027 + 2^-1066 + 2^-1075, half-ulp above a non-power of two):
|
||||
{"6.9533558078476771059728052155218916902221198171459507544162056079"
|
||||
"800301315496366888061157263994418800653863998640286912755395394146"
|
||||
"528315847956685600829998895513577849614468960421131982842131079351"
|
||||
"102171626549398024160346762138294097205837595404767869364138165416"
|
||||
"212878432484332023692099166122496760055730227032447997146221165421"
|
||||
"888377703760223711720795591258533828013962195524188394697705149041"
|
||||
"926576270603193728475623010741404426602378441141744972109554498963"
|
||||
"891803958271916028866544881824524095839813894427833770015054620157"
|
||||
"450178487545746683421617594966617660200287528887833870748507731929"
|
||||
"971029979366198762266880963149896457660004790090837317365857503352"
|
||||
"620998601508967187744019647968271662832256419920407478943826987518"
|
||||
"09812609536720628966577351093292236328125E-310",
|
||||
0x0000800000000100ULL},
|
||||
|
||||
// Example 4 (2^-1058 + 2^-1063 - 2^-1075, half-ulp below a non-power of two):
|
||||
{"3.3390685575711885818357137012809439119234019169985217716556569973"
|
||||
"284403145596153181688491490746626090999981130094655664268081703784"
|
||||
"340657229916596426194677060348844249897410807907667784563321682004"
|
||||
"646515939958173717821250106683466529959122339932545844611258684816"
|
||||
"333436749050742710644097630907080178565840197768788124253120088123"
|
||||
"262603630354748115322368533599053346255754042160606228586332807443"
|
||||
"018924703005556787346899784768703698535494132771566221702458461669"
|
||||
"916553215355296238706468887866375289955928004361779017462862722733"
|
||||
"744717014529914330472578638646014242520247915673681950560773208853"
|
||||
"293843223323915646452641434007986196650406080775491621739636492640"
|
||||
"497383622906068758834568265867109610417379088720358034812416003767"
|
||||
"05491726170293986797332763671875E-319",
|
||||
0x0000000000010800ULL},
|
||||
|
||||
// A number between 2^-1074 and 2^-1075, just slightly larger than 2^-1075.
|
||||
// It has bit 1075 set (the denormal rounding bit), followed by 2506 zeroes,
|
||||
// followed by one bits. It should round up to 2^-1074.
|
||||
{"2.470328229206232720882843964341106861825299013071623822127928412503"
|
||||
"37753635104375932649918180817996189898282347722858865463328355177969"
|
||||
"89819938739800539093906315035659515570226392290858392449105184435931"
|
||||
"80284993653615250031937045767824921936562366986365848075700158576926"
|
||||
"99037063119282795585513329278343384093519780155312465972635795746227"
|
||||
"66465272827220056374006485499977096599470454020828166226237857393450"
|
||||
"73633900796776193057750674017632467360096895134053553745851666113422"
|
||||
"37666786041621596804619144672918403005300575308490487653917113865916"
|
||||
"46239524912623653881879636239373280423891018672348497668235089863388"
|
||||
"58792562830275599565752445550725518931369083625477918694866799496832"
|
||||
"40497058210285131854513962138377228261454376934125320985913276672363"
|
||||
"28125001e-324",
|
||||
0x0000000000000001ULL},
|
||||
|
||||
// This value has a non-terminating binary fraction. It has a 0 at bit 54 followed by 120 ones.
|
||||
{"1.8254370818746402660437411213933955878019332885742187", 0x3FFD34FD8378EA83ULL},
|
||||
|
||||
// https://www.exploringbinary.com/incorrect-decimal-to-floating-point-conversion-in-sqlite/
|
||||
{"1e-23", 0x3B282DB34012B251ULL},
|
||||
{"8.533e+68", 0x4E3FA69165A8EEA2ULL},
|
||||
{"4.1006e-184", 0x19DBE0D1C7EA60C9ULL},
|
||||
{"9.998e+307", 0x7FE1CC0A350CA87BULL},
|
||||
{"9.9538452227e-280", 0x0602117AE45CDE43ULL},
|
||||
{"6.47660115e-260", 0x0A1FDD9E333BADADULL},
|
||||
{"7.4e+47", 0x49E033D7ECA0ADEFULL},
|
||||
{"5.92e+48", 0x4A1033D7ECA0ADEFULL},
|
||||
{"7.35e+66", 0x4DD172B70EABABA9ULL},
|
||||
{"8.32116e+55", 0x4B8B2628393E02CDULL},
|
||||
};
|
||||
|
||||
constexpr std::pair<const char*, uint32_t> floating_point_test_cases_float[] = {
|
||||
// Verify small exactly-representable integers:
|
||||
{"1", 0x3F800000U},
|
||||
{"2", 0x40000000U},
|
||||
{"3", 0x40400000U},
|
||||
{"4", 0x40800000U},
|
||||
{"5", 0x40A00000U},
|
||||
{"6", 0x40C00000U},
|
||||
{"7", 0x40E00000U},
|
||||
{"8", 0x41000000U},
|
||||
|
||||
// Verify large exactly-representable integers:
|
||||
{"16777208", 0x4B7FFFF8U},
|
||||
{"16777209", 0x4B7FFFF9U},
|
||||
{"16777210", 0x4B7FFFFAU},
|
||||
{"16777211", 0x4B7FFFFBU},
|
||||
{"16777212", 0x4B7FFFFCU},
|
||||
{"16777213", 0x4B7FFFFDU},
|
||||
{"16777214", 0x4B7FFFFEU},
|
||||
{"16777215", 0x4B7FFFFFU}, // 2^24 - 1
|
||||
|
||||
// Verify the smallest denormal values:
|
||||
{"1.4012984643248170e-45", 0x00000001U},
|
||||
{"2.8025969286496340e-45", 0x00000002U},
|
||||
{"4.2038953929744510e-45", 0x00000003U},
|
||||
{"5.6051938572992680e-45", 0x00000004U},
|
||||
{"7.0064923216240850e-45", 0x00000005U},
|
||||
{"8.4077907859489020e-45", 0x00000006U},
|
||||
{"9.8090892502737200e-45", 0x00000007U},
|
||||
{"1.1210387714598537e-44", 0x00000008U},
|
||||
{"1.2611686178923354e-44", 0x00000009U},
|
||||
{"1.4012984643248170e-44", 0x0000000AU},
|
||||
{"1.5414283107572988e-44", 0x0000000BU},
|
||||
{"1.6815581571897805e-44", 0x0000000CU},
|
||||
{"1.8216880036222622e-44", 0x0000000DU},
|
||||
{"1.9618178500547440e-44", 0x0000000EU},
|
||||
{"2.1019476964872256e-44", 0x0000000FU},
|
||||
|
||||
// Verify the largest denormal values:
|
||||
{"1.1754921087447446e-38", 0x007FFFF0U},
|
||||
{"1.1754922488745910e-38", 0x007FFFF1U},
|
||||
{"1.1754923890044375e-38", 0x007FFFF2U},
|
||||
{"1.1754925291342839e-38", 0x007FFFF3U},
|
||||
{"1.1754926692641303e-38", 0x007FFFF4U},
|
||||
{"1.1754928093939768e-38", 0x007FFFF5U},
|
||||
{"1.1754929495238232e-38", 0x007FFFF6U},
|
||||
{"1.1754930896536696e-38", 0x007FFFF7U},
|
||||
{"1.1754932297835160e-38", 0x007FFFF8U},
|
||||
{"1.1754933699133625e-38", 0x007FFFF9U},
|
||||
{"1.1754935100432089e-38", 0x007FFFFAU},
|
||||
{"1.1754936501730553e-38", 0x007FFFFBU},
|
||||
{"1.1754937903029018e-38", 0x007FFFFCU},
|
||||
{"1.1754939304327482e-38", 0x007FFFFDU},
|
||||
{"1.1754940705625946e-38", 0x007FFFFEU},
|
||||
{"1.1754942106924411e-38", 0x007FFFFFU},
|
||||
|
||||
// DevDiv#576315 "I/O library incorrect rounds floating point numbers on input"
|
||||
// DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some
|
||||
// denormals"
|
||||
// DevDiv#730414 "iostreams is still misparsing floating-point"
|
||||
// DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++
|
||||
// compiler"
|
||||
// DevDiv#961116 "floating point string conversion accuracy"
|
||||
{"1.175494351e-38", 0x00800000U}, // FLT_MIN
|
||||
{"3.402823466e+38", 0x7F7FFFFFU}, // FLT_MAX
|
||||
{"179.9999999999999855", 0x43340000U},
|
||||
{"4.1", 0x40833333U},
|
||||
{"0.2288884", 0x3E6A61B9U},
|
||||
{"0.168", 0x3E2C0831U},
|
||||
{"1.68", 0x3FD70A3DU},
|
||||
{"16.80000001", 0x41866666U},
|
||||
};
|
||||
|
||||
#endif // FLOATING_POINT_TEST_CASES_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,63 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef TEST_HPP
|
||||
#define TEST_HPP
|
||||
|
||||
#include <charconv>
|
||||
#include <limits>
|
||||
#include <stddef.h>
|
||||
#include <system_error>
|
||||
using namespace std;
|
||||
|
||||
inline constexpr float float_inf = numeric_limits<float>::infinity();
|
||||
inline constexpr float float_nan = numeric_limits<float>::quiet_NaN();
|
||||
inline constexpr float float_nan_payload = __builtin_nanf("1729");
|
||||
|
||||
inline constexpr double double_inf = numeric_limits<double>::infinity();
|
||||
inline constexpr double double_nan = numeric_limits<double>::quiet_NaN();
|
||||
inline constexpr double double_nan_payload = __builtin_nan("1729");
|
||||
|
||||
struct FloatFromCharsTestCase {
|
||||
const char* input;
|
||||
chars_format fmt;
|
||||
size_t correct_idx;
|
||||
errc correct_ec;
|
||||
float correct_value;
|
||||
};
|
||||
|
||||
struct FloatToCharsTestCase {
|
||||
float value;
|
||||
chars_format fmt;
|
||||
const char* correct;
|
||||
};
|
||||
|
||||
struct FloatPrecisionToCharsTestCase {
|
||||
float value;
|
||||
chars_format fmt;
|
||||
int precision;
|
||||
const char* correct;
|
||||
};
|
||||
|
||||
struct DoubleFromCharsTestCase {
|
||||
const char* input;
|
||||
chars_format fmt;
|
||||
size_t correct_idx;
|
||||
errc correct_ec;
|
||||
double correct_value;
|
||||
};
|
||||
|
||||
struct DoubleToCharsTestCase {
|
||||
double value;
|
||||
chars_format fmt;
|
||||
const char* correct;
|
||||
};
|
||||
|
||||
struct DoublePrecisionToCharsTestCase {
|
||||
double value;
|
||||
chars_format fmt;
|
||||
int precision;
|
||||
const char* correct;
|
||||
};
|
||||
|
||||
#endif // TEST_HPP
|
|
@ -1,45 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// to_chars requires functions in the dylib that were introduced in Mac OS 10.15.
|
||||
//
|
||||
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
|
||||
|
||||
// steady_clock requires threads.
|
||||
// UNSUPPORTED: libcpp-has-no-threads
|
||||
// UNSUPPORTED: libcpp-has-no-random-device
|
||||
// UNSUPPORTED: libcpp-has-no-localization
|
||||
|
||||
// TODO(ldionne): This test fails on Ubuntu Focal on our CI nodes (and only there), in 32 bit mode.
|
||||
// UNSUPPORTED: linux && 32bits-on-64bits
|
||||
|
||||
// XFAIL: LIBCXX-AIX-FIXME
|
||||
|
||||
// <charconv>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Work-around for sprintf_s's usage in the Microsoft tests.
|
||||
#ifndef _WIN32
|
||||
# define sprintf_s snprintf
|
||||
#endif
|
||||
|
||||
// FUNCTION TEMPLATE _Bit_cast
|
||||
template <class _To, class _From,
|
||||
std::enable_if_t<sizeof(_To) == sizeof(_From) && std::is_trivially_copyable_v<_To> &&
|
||||
std::is_trivially_copyable_v<_From>,
|
||||
int> = 0>
|
||||
[[nodiscard]] constexpr _To _Bit_cast(const _From& _From_obj) noexcept {
|
||||
return __builtin_bit_cast(_To, _From_obj);
|
||||
}
|
||||
|
||||
// Includes Microsoft's test that tests the entire header.
|
||||
|
||||
#include "test.cpp"
|
Loading…
Reference in New Issue