4444#define YY_DOUBLE_SUPPORTED 0
4545#endif
4646
47+ #include "champagne_lemire/champagne_lemire.h"
48+
4749template<arithmetic_float T>
4850struct BenchArgs {
4951 using Type = T;
@@ -317,6 +319,25 @@ int schubfach(T d, std::span<char>& buffer) {
317319 return schubfach::Dtoa(buffer.data(), d) - buffer.data();
318320}
319321
322+ template<arithmetic_float T>
323+ int dragonboxlm(T d, std::span<char>& buffer) {
324+ char * output = buffer.data();
325+ output[0] = '-';
326+ if(std::signbit(d)) {
327+ output++;
328+ }
329+ // to_decimal requires a finite non-zero value.
330+ if (d == 0.0) {
331+ std::memcpy(output, "0.", 2);
332+ return 2 + (std::signbit(d) ? 1 : 0);
333+ }
334+ auto decimal = jkj::dragonbox::to_decimal(d, jkj::dragonbox::policy::sign::ignore, jkj::dragonbox::policy::cache::full);
335+ auto exponent = decimal.exponent;
336+ auto mantissa = decimal.significand;
337+ return champagne_lemire::to_chars(mantissa, exponent, output) + (std::signbit(d) ? 1 : 0);
338+ }
339+
340+
320341template<arithmetic_float T>
321342int dragonbox(T d, std::span<char>& buffer) {
322343 const char* end_ptr = jkj::dragonbox::to_chars(d, buffer.data());
@@ -333,15 +354,16 @@ int ryu(T d, std::span<char>& buffer) {
333354
334355template<arithmetic_float T>
335356int teju_jagua(T d, std::span<char>& buffer) {
336- if(d == 0.0) {
337- std::copy_n("0E0", 3, buffer.data());
338- return 3;
339- }
340357 const auto fields = teju::traits_t<T>::teju(d);
341- const bool sign = std::signbit(d);
342- return to_chars(fields.mantissa, fields.exponent, sign, buffer.data());
358+ char * output = buffer.data();
359+ output[0] = '-';
360+ if(std::signbit(d)) {
361+ output++;
362+ }
363+ return champagne_lemire::to_chars(fields.mantissa, fields.exponent, output) + (std::signbit(d) ? 1 : 0);
343364}
344365
366+
345367template<arithmetic_float T>
346368int double_conversion(T d, std::span<char>& buffer) {
347369 using namespace double_conversion;
@@ -586,6 +608,7 @@ std::vector<BenchArgs<T>> initArgs(bool use_errol = false, size_t repeat = 0, si
586608 args.emplace_back("grisu3" , wrap(s::grisu3<T>) , std::is_same_v<T, double>);
587609 args.emplace_back("grisu_exact" , wrap(s::grisu_exact<T>) , true);
588610 args.emplace_back("schubfach" , wrap(s::schubfach<T>) , true);
611+ args.emplace_back("dragonboxlm" , wrap(s::dragonboxlm<T>) , true);
589612 args.emplace_back("dragonbox" , wrap(s::dragonbox<T>) , true);
590613 args.emplace_back("ryu" , wrap(s::ryu<T>) , true);
591614 args.emplace_back("teju_jagua" , wrap(s::teju_jagua<T>) , true);
0 commit comments