Replace std::stof with std::strtof.

std::stof can throw std::out_of_range if the input is not actually
representable. We had similar code in Skia which was using stof to
test that a stringized float would round-trip successfully, and it
would throw an exception on some older versions of libc++ for edge-
case inputs like FLT_MIN.

std::stof is documented as using strtof to do its conversion, so this
shouldn't change your results in practice; it just removes the part
where it could potentially throw for some inputs.

Tangentially, have you ever seen a case where the scientific-notation
path gets used? According to brucedawson@, nine digits should always
safely round-trip (in 2013, testing gcc and MSVC). See
https://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/

Change-Id: Ie215fb8502dd8c554020c6f73432f91e3d756563
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/104500
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2022-10-03 15:05:54 +00:00 committed by Dawn LUCI CQ
parent 324e446f9c
commit 5f9996dc9c
1 changed files with 2 additions and 1 deletions

View File

@ -15,6 +15,7 @@
#include "src/tint/writer/float_to_string.h" #include "src/tint/writer/float_to_string.h"
#include <cmath> #include <cmath>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <iomanip> #include <iomanip>
@ -35,7 +36,7 @@ std::string FloatToString(float f) {
// If this string can be parsed without loss of information, use it // If this string can be parsed without loss of information, use it
auto float_equal_no_warning = std::equal_to<float>(); auto float_equal_no_warning = std::equal_to<float>();
if (float_equal_no_warning(std::stof(fixed.str()), f)) { if (float_equal_no_warning(std::strtof(fixed.str().c_str(), nullptr), f)) {
auto str = fixed.str(); auto str = fixed.str();
while (str.length() >= 2 && str[str.size() - 1] == '0' && str[str.size() - 2] != '.') { while (str.length() >= 2 && str[str.size() - 1] == '0' && str[str.size() - 2] != '.') {
str.pop_back(); str.pop_back();