blob: c16d42ce5cfe2d4cd844977275f95a36343c2de6 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "arrow/util/formatting.h"
#include "arrow/util/config.h"
#include "arrow/util/double_conversion.h"
#include "arrow/util/logging.h"
namespace arrow {
using util::double_conversion::DoubleToStringConverter;
static constexpr int kMinBufferSize = DoubleToStringConverter::kBase10MaximalLength + 1;
namespace internal {
namespace detail {
const char digit_pairs[] =
"0001020304050607080910111213141516171819"
"2021222324252627282930313233343536373839"
"4041424344454647484950515253545556575859"
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";
} // namespace detail
struct FloatToStringFormatter::Impl {
Impl()
: converter_(DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN, "inf", "nan",
'e', -6, 10, 6, 0) {}
Impl(int flags, const char* inf_symbol, const char* nan_symbol, char exp_character,
int decimal_in_shortest_low, int decimal_in_shortest_high,
int max_leading_padding_zeroes_in_precision_mode,
int max_trailing_padding_zeroes_in_precision_mode)
: converter_(flags, inf_symbol, nan_symbol, exp_character, decimal_in_shortest_low,
decimal_in_shortest_high, max_leading_padding_zeroes_in_precision_mode,
max_trailing_padding_zeroes_in_precision_mode) {}
DoubleToStringConverter converter_;
};
FloatToStringFormatter::FloatToStringFormatter() : impl_(new Impl()) {}
FloatToStringFormatter::FloatToStringFormatter(
int flags, const char* inf_symbol, const char* nan_symbol, char exp_character,
int decimal_in_shortest_low, int decimal_in_shortest_high,
int max_leading_padding_zeroes_in_precision_mode,
int max_trailing_padding_zeroes_in_precision_mode)
: impl_(new Impl(flags, inf_symbol, nan_symbol, exp_character,
decimal_in_shortest_low, decimal_in_shortest_high,
max_leading_padding_zeroes_in_precision_mode,
max_trailing_padding_zeroes_in_precision_mode)) {}
FloatToStringFormatter::~FloatToStringFormatter() {}
int FloatToStringFormatter::FormatFloat(float v, char* out_buffer, int out_size) {
DCHECK_GE(out_size, kMinBufferSize);
// StringBuilder checks bounds in debug mode for us
util::double_conversion::StringBuilder builder(out_buffer, out_size);
bool result = impl_->converter_.ToShortestSingle(v, &builder);
DCHECK(result);
ARROW_UNUSED(result);
return builder.position();
}
int FloatToStringFormatter::FormatFloat(double v, char* out_buffer, int out_size) {
DCHECK_GE(out_size, kMinBufferSize);
util::double_conversion::StringBuilder builder(out_buffer, out_size);
bool result = impl_->converter_.ToShortest(v, &builder);
DCHECK(result);
ARROW_UNUSED(result);
return builder.position();
}
} // namespace internal
} // namespace arrow