Skip to content

Commit 6f4fcba

Browse files
authored
Merge pull request #30 from fastfloat/float64
adding 64-bit float checks + fix to netlib
2 parents 7d0ab1e + e6159be commit 6f4fcba

File tree

6 files changed

+4289915
-7
lines changed

6 files changed

+4289915
-7
lines changed

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ cmake --build build
3333
./build/benchmarks/benchmark
3434
```
3535

36+
Some functionality might be disabled under some systems. For example, under macOS with
37+
libc++, some tests might be omitted because it does not yet fully support C++17.
38+
3639
We also support Visual Studio, please refer to the cmake documentation.
3740

3841
You may use docker to run these benchmarks easily on a variety of platforms: see https://github.com/lemire/docker_programming_station
@@ -64,12 +67,31 @@ Serialize strings generated from floats in (0,1):
6467
## Exhaustive 32-bit check
6568

6669
We also include an exhaustive check of all 32-bit floats, to verify
67-
that we can produce the shortest string representation.
70+
that we can produce the shortest string representation (measured by
71+
the number of significant digits).
72+
73+
Under Linux, you may run the following check:
6874

6975
```
76+
cmake -B build .
77+
cmake --build build --config Release
7078
./build/benchmarks/exhaustivefloat32
7179
```
7280

81+
## Thorough 64-bit check
82+
83+
We also include a thorough check of many 64-bit floats, to verify
84+
that we can produce the shortest string representation (measured by
85+
the number of significant digits).
86+
87+
Under Linux, you may run the following check:
88+
89+
```
90+
cmake -B build .
91+
cmake --build build --config Release
92+
./build/benchmarks/thoroughfloat64
93+
```
94+
7395
## Other existing benchmarks
7496

7597
- [dtoa Benchmark](https://github.com/miloyip/dtoa-benchmark)

benchmarks/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ if(TO_CHARS_OK AND FROM_CHARS_OK)
9393
add_executable(exhaustivefloat32
9494
exhaustivefloat32.cpp
9595
)
96+
9697
target_link_libraries(exhaustivefloat32 PUBLIC benchmark_deps)
98+
add_executable(thoroughfloat64
99+
thoroughfloat64.cpp
100+
)
101+
set(THOROUGH_DATA_FILE "${CMAKE_SOURCE_DIR}/data/thoroughnumbers.txt")
102+
target_compile_definitions(thoroughfloat64 PRIVATE THOROUGH_DATA_FILE="${THOROUGH_DATA_FILE}")
103+
104+
target_link_libraries(thoroughfloat64 PUBLIC benchmark_deps)
97105
endif(TO_CHARS_OK AND FROM_CHARS_OK)
98106

benchmarks/algorithms.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ int netlib(T d, std::span<char>& buffer) {
128128
int decpt, sign;
129129
char* rve;
130130
char* result = dtoa(d, 0, 0, &decpt, &sign, &rve);
131+
131132
if (result) {
132133
int i = 0;
133134
if (sign)
@@ -141,17 +142,40 @@ int netlib(T d, std::span<char>& buffer) {
141142
// Number is < 1 (e.g., 0.000123)
142143
buffer[i++] = '0';
143144
buffer[i++] = '.';
144-
std::fill_n(buffer.data() + i, -decpt, '0'); // Add leading zeros
145-
i += -decpt;
145+
// Adding lots of zeroes so can create a really large output:
146+
//std::fill_n(buffer.data() + i, -decpt, '0'); // Add leading zeros
147+
//i += -decpt;
146148
}
147-
149+
auto write_exponent = [&buffer, &i](int value) {
150+
if (value >= 100) {
151+
buffer[i++] = '0' + value / 100;
152+
value %= 100;
153+
buffer[i++] = '0' + value / 10;
154+
value %= 10;
155+
buffer[i++] = '0' + value;
156+
} else if (value >= 10) {
157+
buffer[i++] = '0' + value / 10;
158+
value %= 10;
159+
buffer[i++] = '0' + value;
160+
} else {
161+
buffer[i++] = '0' + value;
162+
}
163+
};
148164
// Fractional part (if any remaining digits)
149165
const int remaining_digits = rve - (result + std::max(0, decpt));
150166
if (remaining_digits > 0) {
151167
if (decpt > 0)
152168
buffer[i++] = '.';
153169
std::copy_n(result + std::max(0, decpt), remaining_digits, buffer.data() + i);
154170
i += remaining_digits;
171+
if(decpt < 0) {
172+
buffer[i++] = 'E';
173+
buffer[i++] = '-';
174+
write_exponent(-decpt);
175+
}
176+
} else if (remaining_digits < 0) {
177+
buffer[i++] = 'E';
178+
write_exponent(-remaining_digits);
155179
}
156180

157181
freedtoa(result);

benchmarks/exhaustivefloat32.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@ void run_exhaustive32(bool errol) {
117117
}
118118
if(*backRef != d) {
119119
incorrect = true;
120-
fmt::print(" ref mismatch: d = {}, backRef = {}", d, *backRef);
120+
fmt::print(" ref mismatch: d = {}, backRef = {}; svRef = {}, svAlgo = {}", float_to_hex(d), *backRef, svRef, svAlgo);
121121
fflush(stdout);
122122
break;
123123
}
124124
if(*backAlgo != d) {
125125
incorrect = true;
126-
fmt::print(" algo mismatch: d = {}, backAlgo = {}, parsing the output with std::from_chars does not recover the original", d, *backAlgo);
126+
fmt::print(" algo mismatch: d = {}, backAlgo = {}; svRef = {}, svAlgo = {}, parsing the output with std::from_chars does not recover the original", float_to_hex(d), *backAlgo, svRef, svAlgo);
127127
fflush(stdout);
128128
break;
129129
}
@@ -135,7 +135,7 @@ void run_exhaustive32(bool errol) {
135135
break;
136136
}
137137
}
138-
printf("\n");
138+
fmt::print("\n");
139139
fmt::println("{:20} {:20}", algo.name, incorrect == 0 ? "yes" : "no");
140140
}
141141
}

0 commit comments

Comments
 (0)