Skip to content

Commit 163c538

Browse files
committed
fix: don't fail on overflow
1 parent 384ea25 commit 163c538

2 files changed

Lines changed: 21 additions & 3 deletions

File tree

cpp/src/arrow/util/value_parsing.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,21 @@ bool StringToFloat(const char* s, size_t length, char decimal_point, float* out)
3535
::arrow_vendored::fast_float::chars_format::general, decimal_point};
3636
const auto res =
3737
::arrow_vendored::fast_float::from_chars_advanced(s, s + length, *out, options);
38-
return res.ec == std::errc() && res.ptr == s + length;
38+
const bool is_valid_number =
39+
res.ec == std::errc() || res.ec == std::errc::result_out_of_range;
40+
const bool consumed_entire_string = res.ptr == s + length;
41+
return is_valid_number && consumed_entire_string;
3942
}
4043

4144
bool StringToFloat(const char* s, size_t length, char decimal_point, double* out) {
4245
::arrow_vendored::fast_float::parse_options options{
4346
::arrow_vendored::fast_float::chars_format::general, decimal_point};
4447
const auto res =
4548
::arrow_vendored::fast_float::from_chars_advanced(s, s + length, *out, options);
46-
return res.ec == std::errc() && res.ptr == s + length;
49+
const bool is_valid_number =
50+
res.ec == std::errc() || res.ec == std::errc::result_out_of_range;
51+
const bool consumed_entire_string = res.ptr == s + length;
52+
return is_valid_number && consumed_entire_string;
4753
}
4854

4955
// Half float
@@ -53,7 +59,10 @@ bool StringToFloat(const char* s, size_t length, char decimal_point, Float16* ou
5359
float temp_out;
5460
const auto res =
5561
::arrow_vendored::fast_float::from_chars_advanced(s, s + length, temp_out, options);
56-
const bool ok = res.ec == std::errc() && res.ptr == s + length;
62+
const bool is_valid_number =
63+
res.ec == std::errc() || res.ec == std::errc::result_out_of_range;
64+
const bool consumed_entire_string = res.ptr == s + length;
65+
const bool ok = is_valid_number && consumed_entire_string;
5766
if (ok) {
5867
*out = Float16::FromFloat(temp_out);
5968
}

cpp/src/arrow/util/value_parsing_test.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ TEST(StringConversion, ToFloat) {
141141
AssertConversion<FloatType>("0", 0.0f);
142142
AssertConversion<FloatType>("-0.0", -0.0f);
143143
AssertConversion<FloatType>("-1e20", -1e20f);
144+
AssertConversion<FloatType>("4e38", std::numeric_limits<float>::infinity());
145+
AssertConversion<FloatType>("-4e38", -std::numeric_limits<float>::infinity());
146+
AssertConversion<FloatType>("1e-46", 0.0f);
144147
AssertConversion<FloatType>("+Infinity", std::numeric_limits<float>::infinity());
145148
AssertConversion<FloatType>("-Infinity", -std::numeric_limits<float>::infinity());
146149
AssertConversion<FloatType>("Infinity", std::numeric_limits<float>::infinity());
@@ -166,6 +169,9 @@ TEST(StringConversion, ToDouble) {
166169
AssertConversion<DoubleType>("0", 0);
167170
AssertConversion<DoubleType>("-0.0", -0.0);
168171
AssertConversion<DoubleType>("-1e100", -1e100);
172+
AssertConversion<DoubleType>("2e308", std::numeric_limits<double>::infinity());
173+
AssertConversion<DoubleType>("-2e308", -std::numeric_limits<double>::infinity());
174+
AssertConversion<DoubleType>("1e-325", 0.0);
169175
AssertConversion<DoubleType>("+Infinity", std::numeric_limits<double>::infinity());
170176
AssertConversion<DoubleType>("-Infinity", -std::numeric_limits<double>::infinity());
171177
AssertConversion<DoubleType>("Infinity", std::numeric_limits<double>::infinity());
@@ -185,6 +191,9 @@ TEST(StringConversion, ToHalfFloat) {
185191
AssertConversion<HalfFloatType>("0", Float16(0.0f));
186192
AssertConversion<HalfFloatType>("-0.0", Float16(-0.0f));
187193
AssertConversion<HalfFloatType>("-1e15", Float16(-1e15));
194+
AssertConversion<HalfFloatType>("7e4", Float16::FromBits(0x7c00));
195+
AssertConversion<HalfFloatType>("-7e4", Float16::FromBits(0xfc00));
196+
AssertConversion<HalfFloatType>("1e-9", Float16(0.0f));
188197
AssertConversion<HalfFloatType>("+Infinity", Float16::FromBits(0x7c00));
189198
AssertConversion<HalfFloatType>("-Infinity", Float16::FromBits(0xfc00));
190199
AssertConversion<HalfFloatType>("Infinity", Float16::FromBits(0x7c00));

0 commit comments

Comments
 (0)