Skip to content

Commit ce04599

Browse files
committed
change dragon4 implementation
1 parent d42289d commit ce04599

File tree

7 files changed

+35
-23
lines changed

7 files changed

+35
-23
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build
22
build_debug
33
build_script
4+
compile_commands.json
45
.cache

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ numbers, i.e., converting them from an IEEE 754 binary representation to a
66
string decimal representation.
77

88
Currently, the following approaches are compared:
9-
- [dragon4](https://github.com/abolz/Drachennest/blob/master/src/dragon4.cc)
9+
- [dragon4](https://github.com/ahaldane/Dragon4)
1010
- [std::to_string](https://en.cppreference.com/w/cpp/string/basic_string/to_string)
1111
- [fmt::format](https://github.com/fmtlib/fmt)
1212
- [netlib](https://github.com/jwiegley/gdtoa)

benchmarks/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,5 @@ if(teju_has_float128)
7676
endif()
7777
target_link_libraries(benchmark PUBLIC dragonbox::dragonbox_to_chars)
7878
target_link_libraries(benchmark PUBLIC dragon_schubfach_lib)
79+
target_link_libraries(benchmark PUBLIC dragon4_lib)
7980
target_include_directories(benchmark PUBLIC ${grisu-exact_SOURCE_DIR})

benchmarks/algorithms.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
#include <span>
2323

2424
#include "cpp/common/traits.hpp" // Teju Jagua
25+
#include "PrintFloat.h" // Dragon4
2526
#include "double-conversion/double-conversion.h"
26-
#include "dragon4.h"
2727
#include "dragonbox/dragonbox_to_chars.h"
2828
#include "grisu2.h"
2929
#include "grisu3.h"
@@ -73,17 +73,14 @@ struct BenchArgs {
7373
unsigned char testRepeat{100};
7474
};
7575

76-
// No dragon4 implementation optimized for float instead of double ?
7776
template<arithmetic_float T>
7877
int dragon4(T d, std::span<char>& buffer) {
79-
using IEEE754Type
80-
= std::conditional_t<std::is_same_v<T, float>, IEEE754f, IEEE754d>;
81-
const IEEE754Type fields = decode_ieee754(d);
82-
83-
uint64_t dm;
84-
int dexp;
85-
dragon4::Dragon4(dm, dexp, fields.mantissa, fields.exponent, true, true);
86-
return to_chars(dm, dexp, fields.sign, buffer.data());
78+
if constexpr (std::is_same_v<T, float>)
79+
return PrintFloat32(buffer.data(), buffer.size(), d,
80+
PrintFloatFormat_Positional, -1);
81+
else
82+
return PrintFloat64(buffer.data(), buffer.size(), d,
83+
PrintFloatFormat_Positional, -1);
8784
}
8885

8986
// No errol3 implementation optimized for float instead of double ?

benchmarks/benchmark.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,6 @@ int main(int argc, char **argv) {
145145
cxxopts::value<bool>()->default_value("false"))
146146
("t,test", "Test the algorithms and find their properties.",
147147
cxxopts::value<bool>()->default_value("false"))
148-
("d,dragon", "Enable dragon4 (current impl. triggers some asserts).",
149-
#ifdef NDEBUG
150-
cxxopts::value<bool>()->default_value("true"))
151-
#else // NDEBUG
152-
// dragon4 is not safe in debug mode: some asserts fire.
153-
cxxopts::value<bool>()->default_value("false"))
154-
#endif
155148
("e,errol", "Enable errol3 (current impl. returns invalid values, e.g., for 0).",
156149
cxxopts::value<bool>()->default_value("false"))
157150
("h,help", "Print usage.");
@@ -189,7 +182,7 @@ int main(int argc, char **argv) {
189182
auto initArgs = [&](auto type) {
190183
using T = decltype(type);
191184
std::array<BenchArgs<T>, Benchmarks::COUNT> args;
192-
args[Benchmarks::DRAGON4] = { "dragon4" , Benchmarks::dragon4<T> , result["dragon"].as<bool>() , 10 };
185+
args[Benchmarks::DRAGON4] = { "dragon4" , Benchmarks::dragon4<T> , true , 10 };
193186
args[Benchmarks::ERROL3] = { "errol3" , Benchmarks::errol3<T> , result["errol"].as<bool>() };
194187
args[Benchmarks::TO_STRING] = { "std::to_string" , Benchmarks::to_string<T> , ERROL_SUPPORTED };
195188
args[Benchmarks::FMT_FORMAT] = { "fmt::format" , Benchmarks::fmt_format<T> , true };

benchmarks/ieeeToString.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#include "ieeeToString.h"
22

3+
#include <bit>
34
#include <cassert>
45
#include <cstring>
56

67
#include "ryu/digit_table.h" // For DIGIT_TABLE
78
#include "ryu/common.h" // For decimalLength9
89

910
IEEE754f decode_ieee754(float f) {
10-
const uint32_t& bits = reinterpret_cast<const uint32_t&>(f);
11+
const uint32_t bits = std::bit_cast<uint32_t>(f);
1112

1213
IEEE754f decomposed;
1314
decomposed.exponent = (bits >> FloatMantissaBits) & ((1 << FloatExponentBits) - 1);
@@ -17,7 +18,7 @@ IEEE754f decode_ieee754(float f) {
1718
}
1819

1920
IEEE754d decode_ieee754(double f) {
20-
const uint64_t& bits = reinterpret_cast<const uint64_t&>(f);
21+
const uint64_t bits = std::bit_cast<uint64_t>(f);
2122

2223
IEEE754d decomposed;
2324
decomposed.exponent = (bits >> DoubleMantissaBits) & ((1ull << DoubleExponentBits) - 1);

dependencies/CMakeLists.txt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,27 @@ FetchContent_Declare(
7878
FetchContent_MakeAvailable(dragonbox)
7979

8080
FetchContent_Declare(
81-
drachennest # for schubfach and dragon4
81+
dragon4
82+
GIT_REPOSITORY https://github.com/ahaldane/Dragon4.git
83+
GIT_TAG 670a3827651c68c9f329d394898b1204cb5ec46f
84+
GIT_SHALLOW TRUE
85+
)
86+
FetchContent_GetProperties(dragon4)
87+
if(NOT dragon4)
88+
FetchContent_Populate(dragon4) # Downloads code to ${dragon4_SOURCE_DIR}
89+
endif()
90+
set(dragon4_SOURCE_DIR ${dragon4_SOURCE_DIR} PARENT_SCOPE)
91+
add_library(dragon4_lib STATIC
92+
${dragon4_SOURCE_DIR}/Dragon4.cpp
93+
${dragon4_SOURCE_DIR}/Math.cpp
94+
${dragon4_SOURCE_DIR}/PrintFloat.cpp
95+
)
96+
target_include_directories(dragon4_lib PUBLIC
97+
${dragon4_SOURCE_DIR}
98+
)
99+
100+
FetchContent_Declare(
101+
drachennest # for schubfach
82102
GIT_REPOSITORY https://github.com/abolz/Drachennest.git
83103
GIT_TAG e6714a39ad331b4489d0b6aaf3968635bff4eb5e
84104
GIT_SHALLOW TRUE
@@ -94,7 +114,6 @@ add_library(dragon_schubfach_lib STATIC
94114
${drachennest_SOURCE_DIR}/src/schubfach_64.cc
95115
${drachennest_SOURCE_DIR}/src/grisu3.cc
96116
${drachennest_SOURCE_DIR}/src/grisu2.cc
97-
98117
)
99118
target_include_directories(dragon_schubfach_lib PUBLIC
100119
${drachennest_SOURCE_DIR}/src

0 commit comments

Comments
 (0)