ICU-21957 Update double-conversion to 256ac809561b756645e73ab7127c2aaaeabaa427

See #2179
This commit is contained in:
Shane Carr 2022-09-08 23:58:39 +00:00 committed by Shane F. Carr
parent b9fdd2a7cf
commit e4df304367
20 changed files with 146 additions and 121 deletions

View file

@ -150,7 +150,7 @@ void Bignum::AssignHexString(Vector<const char> value) {
DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= kBigitSize + 4); // TODO: static_assert
// Accumulates converted hex digits until at least kBigitSize bits.
// Works with non-factor-of-four kBigitSizes.
uint64_t tmp = 0; // Accumulates converted hex digits until at least
uint64_t tmp = 0;
for (int cnt = 0; !value.is_empty(); value.pop_back()) {
tmp |= (HexCharValue(value.last()) << cnt);
if ((cnt += 4) >= kBigitSize) {
@ -160,7 +160,8 @@ void Bignum::AssignHexString(Vector<const char> value) {
}
}
if (tmp > 0) {
RawBigit(used_bigits_++) = tmp;
DOUBLE_CONVERSION_ASSERT(tmp <= kBigitMask);
RawBigit(used_bigits_++) = static_cast<Bignum::Chunk>(tmp & kBigitMask);
}
Clamp();
}
@ -217,7 +218,7 @@ void Bignum::AddBignum(const Bignum& other) {
carry = sum >> kBigitSize;
++bigit_pos;
}
used_bigits_ = (std::max)(bigit_pos, static_cast<int>(used_bigits_));
used_bigits_ = static_cast<int16_t>(std::max(bigit_pos, static_cast<int>(used_bigits_)));
DOUBLE_CONVERSION_ASSERT(IsClamped());
}
@ -253,7 +254,7 @@ void Bignum::ShiftLeft(const int shift_amount) {
if (used_bigits_ == 0) {
return;
}
exponent_ += (shift_amount / kBigitSize);
exponent_ += static_cast<int16_t>(shift_amount / kBigitSize);
const int local_shift = shift_amount % kBigitSize;
EnsureCapacity(used_bigits_ + 1);
BigitsShiftLeft(local_shift);
@ -431,7 +432,7 @@ void Bignum::Square() {
DOUBLE_CONVERSION_ASSERT(accumulator == 0);
// Don't forget to update the used_digits and the exponent.
used_bigits_ = product_length;
used_bigits_ = static_cast<int16_t>(product_length);
exponent_ *= 2;
Clamp();
}
@ -752,8 +753,8 @@ void Bignum::Align(const Bignum& other) {
for (int i = 0; i < zero_bigits; ++i) {
RawBigit(i) = 0;
}
used_bigits_ += zero_bigits;
exponent_ -= zero_bigits;
used_bigits_ += static_cast<int16_t>(zero_bigits);
exponent_ -= static_cast<int16_t>(zero_bigits);
DOUBLE_CONVERSION_ASSERT(used_bigits_ >= 0);
DOUBLE_CONVERSION_ASSERT(exponent_ >= 0);

View file

@ -71,7 +71,7 @@ bool DoubleToStringConverter::HandleSpecialValues(
StringBuilder* result_builder) const {
Double double_inspect(value);
if (double_inspect.IsInfinite()) {
if (infinity_symbol_ == NULL) return false;
if (infinity_symbol_ == DOUBLE_CONVERSION_NULLPTR) return false;
if (value < 0) {
result_builder->AddCharacter('-');
}
@ -79,7 +79,7 @@ bool DoubleToStringConverter::HandleSpecialValues(
return true;
}
if (double_inspect.IsNan()) {
if (nan_symbol_ == NULL) return false;
if (nan_symbol_ == DOUBLE_CONVERSION_NULLPTR) return false;
result_builder->AddString(nan_symbol_);
return true;
}

View file

@ -495,7 +495,7 @@ double StringToDoubleConverter::StringToIeee(
current = next_non_space;
}
if (infinity_symbol_ != NULL) {
if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) {
if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensitivity)) {
return junk_string_value_;
@ -513,7 +513,7 @@ double StringToDoubleConverter::StringToIeee(
}
}
if (nan_symbol_ != NULL) {
if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensitivity)) {
return junk_string_value_;

View file

@ -43,6 +43,13 @@
#include <cstdlib>
#include <cstring>
// For pre-C++11 compatibility
#if __cplusplus >= 201103L
#define DOUBLE_CONVERSION_NULLPTR nullptr
#else
#define DOUBLE_CONVERSION_NULLPTR NULL
#endif
// ICU PATCH: Use U_ASSERT instead of <assert.h>
#include "uassert.h"
#ifndef DOUBLE_CONVERSION_ASSERT
@ -254,9 +261,9 @@ inline int StrLength(const char* string) {
template <typename T>
class Vector {
public:
Vector() : start_(NULL), length_(0) {}
Vector() : start_(DOUBLE_CONVERSION_NULLPTR), length_(0) {}
Vector(T* data, int len) : start_(data), length_(len) {
DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL));
DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != DOUBLE_CONVERSION_NULLPTR));
}
// Returns a vector using the same backing storage as this one,
@ -339,7 +346,7 @@ class StringBuilder {
void AddSubstring(const char* s, int n) {
DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length());
DOUBLE_CONVERSION_ASSERT(static_cast<size_t>(n) <= strlen(s));
memmove(&buffer_[position_], s, n);
memmove(&buffer_[position_], s, static_cast<size_t>(n));
position_ += n;
}

View file

@ -1,34 +0,0 @@
name: CMake
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Debug
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Configure CMake
# Configure CMake in a 'build' subdirectory.
run: cmake -B ${{github.workspace}}/build -DBUILD_TESTING=ON
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}/build
# Execute all tests.
run: test/cctest/cctest

View file

@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0)
project(double-conversion VERSION 3.2.0)
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
if(BUILD_SHARED_LIBS AND MSVC)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
@ -116,3 +118,13 @@ install(
NAMESPACE "${namespace}"
DESTINATION "${config_install_dir}"
)
if (MSVC AND BUILD_SHARED_LIBS)
# Install companion PDB for Visual Studio
install(
FILES $<TARGET_PDB_FILE:double-conversion>
TYPE BIN
OPTIONAL
)
endif()

View file

@ -1,3 +1,6 @@
2022-01-16:
Install Visual Studio debugger (pdb) files.
2022-01-10:
Fix quiet NANs on MIPS* and PA-RISC architectures.
Update version number.

View file

@ -136,7 +136,7 @@ void Bignum::AssignHexString(Vector<const char> value) {
DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= kBigitSize + 4); // TODO: static_assert
// Accumulates converted hex digits until at least kBigitSize bits.
// Works with non-factor-of-four kBigitSizes.
uint64_t tmp = 0; // Accumulates converted hex digits until at least
uint64_t tmp = 0;
for (int cnt = 0; !value.is_empty(); value.pop_back()) {
tmp |= (HexCharValue(value.last()) << cnt);
if ((cnt += 4) >= kBigitSize) {
@ -146,7 +146,8 @@ void Bignum::AssignHexString(Vector<const char> value) {
}
}
if (tmp > 0) {
RawBigit(used_bigits_++) = tmp;
DOUBLE_CONVERSION_ASSERT(tmp <= kBigitMask);
RawBigit(used_bigits_++) = static_cast<Bignum::Chunk>(tmp & kBigitMask);
}
Clamp();
}
@ -203,7 +204,7 @@ void Bignum::AddBignum(const Bignum& other) {
carry = sum >> kBigitSize;
++bigit_pos;
}
used_bigits_ = (std::max)(bigit_pos, static_cast<int>(used_bigits_));
used_bigits_ = static_cast<int16_t>(std::max(bigit_pos, static_cast<int>(used_bigits_)));
DOUBLE_CONVERSION_ASSERT(IsClamped());
}
@ -239,7 +240,7 @@ void Bignum::ShiftLeft(const int shift_amount) {
if (used_bigits_ == 0) {
return;
}
exponent_ += (shift_amount / kBigitSize);
exponent_ += static_cast<int16_t>(shift_amount / kBigitSize);
const int local_shift = shift_amount % kBigitSize;
EnsureCapacity(used_bigits_ + 1);
BigitsShiftLeft(local_shift);
@ -417,7 +418,7 @@ void Bignum::Square() {
DOUBLE_CONVERSION_ASSERT(accumulator == 0);
// Don't forget to update the used_digits and the exponent.
used_bigits_ = product_length;
used_bigits_ = static_cast<int16_t>(product_length);
exponent_ *= 2;
Clamp();
}
@ -738,8 +739,8 @@ void Bignum::Align(const Bignum& other) {
for (int i = 0; i < zero_bigits; ++i) {
RawBigit(i) = 0;
}
used_bigits_ += zero_bigits;
exponent_ -= zero_bigits;
used_bigits_ += static_cast<int16_t>(zero_bigits);
exponent_ -= static_cast<int16_t>(zero_bigits);
DOUBLE_CONVERSION_ASSERT(used_bigits_ >= 0);
DOUBLE_CONVERSION_ASSERT(exponent_ >= 0);

View file

@ -56,7 +56,7 @@ bool DoubleToStringConverter::HandleSpecialValues(
StringBuilder* result_builder) const {
Double double_inspect(value);
if (double_inspect.IsInfinite()) {
if (infinity_symbol_ == NULL) return false;
if (infinity_symbol_ == DOUBLE_CONVERSION_NULLPTR) return false;
if (value < 0) {
result_builder->AddCharacter('-');
}
@ -64,7 +64,7 @@ bool DoubleToStringConverter::HandleSpecialValues(
return true;
}
if (double_inspect.IsNan()) {
if (nan_symbol_ == NULL) return false;
if (nan_symbol_ == DOUBLE_CONVERSION_NULLPTR) return false;
result_builder->AddString(nan_symbol_);
return true;
}

View file

@ -474,7 +474,7 @@ double StringToDoubleConverter::StringToIeee(
current = next_non_space;
}
if (infinity_symbol_ != NULL) {
if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) {
if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensitivity)) {
return junk_string_value_;
@ -492,7 +492,7 @@ double StringToDoubleConverter::StringToIeee(
}
}
if (nan_symbol_ != NULL) {
if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensitivity)) {
return junk_string_value_;

View file

@ -34,6 +34,13 @@
#include <cstdlib>
#include <cstring>
// For pre-C++11 compatibility
#if __cplusplus >= 201103L
#define DOUBLE_CONVERSION_NULLPTR nullptr
#else
#define DOUBLE_CONVERSION_NULLPTR NULL
#endif
#include <cassert>
#ifndef DOUBLE_CONVERSION_ASSERT
#define DOUBLE_CONVERSION_ASSERT(condition) \
@ -241,9 +248,9 @@ inline int StrLength(const char* string) {
template <typename T>
class Vector {
public:
Vector() : start_(NULL), length_(0) {}
Vector() : start_(DOUBLE_CONVERSION_NULLPTR), length_(0) {}
Vector(T* data, int len) : start_(data), length_(len) {
DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL));
DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != DOUBLE_CONVERSION_NULLPTR));
}
// Returns a vector using the same backing storage as this one,
@ -326,7 +333,7 @@ class StringBuilder {
void AddSubstring(const char* s, int n) {
DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length());
DOUBLE_CONVERSION_ASSERT(static_cast<size_t>(n) <= strlen(s));
memmove(&buffer_[position_], s, n);
memmove(&buffer_[position_], s, static_cast<size_t>(n));
position_ += n;
}

View file

@ -33,6 +33,15 @@
CcTest* CcTest::last_ = NULL;
// The windows compiler doesn't like to use `strdup`, and claims it's a
// deprecated name.
// For simplicity just implement it ourselves.
static char* Strdup(const char* str) {
size_t len = strlen(str);
char* result = reinterpret_cast<char*>(malloc(len + 1));
memcpy(result, str, len + 1);
return result;
}
CcTest::CcTest(TestFunction* callback, const char* test_file,
const char* test_name, const char* test_dependency,
@ -45,9 +54,9 @@ CcTest::CcTest(TestFunction* callback, const char* test_file,
basename = strrchr(const_cast<char *>(test_file), '\\');
}
if (!basename) {
basename = strdup(test_file);
basename = Strdup(test_file);
} else {
basename = strdup(basename + 1);
basename = Strdup(basename + 1);
}
// Drop the extension, if there is one.
char *extension = strrchr(basename, '.');
@ -93,7 +102,7 @@ int main(int argc, char* argv[]) {
print_run_count = false;
} else {
char* arg_copy = strdup(arg);
char* arg_copy = Strdup(arg);
char* testname = strchr(arg_copy, '/');
if (testname) {
// Split the string in two by nulling the slash and then run

View file

@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "double-conversion/utils.h"
@ -69,11 +70,43 @@ static inline void CheckHelper(const char* file,
#define CHECK_EQ(a, b) CheckEqualsHelper(__FILE__, __LINE__, #a, a, #b, b)
static inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
const char* expected,
const char* value_source,
const char* value) {
template<typename T> inline void PrintfValue(T x);
template<> inline void PrintfValue(int x) { printf("%d", x); }
template<> inline void PrintfValue(unsigned int x) { printf("%u", x); }
template<> inline void PrintfValue(short x) { printf("%hd", x); }
template<> inline void PrintfValue(unsigned short x) { printf("%hu", x); }
template<> inline void PrintfValue(int64_t x) { printf("%" PRId64, x); }
template<> inline void PrintfValue(uint64_t x) { printf("%" PRIu64, x); }
template<> inline void PrintfValue(float x) { printf("%.30e", static_cast<double>(x)); }
template<> inline void PrintfValue(double x) { printf("%.30e", x); }
template<> inline void PrintfValue(bool x) { printf("%s", x ? "true" : "false"); }
template<typename T1, typename T2>
inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
T1 expected,
const char* value_source,
T2 value) {
// If expected and value are NaNs then expected != value.
if (expected != value && (expected == expected || value == value)) {
printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n",
file, line, expected_source, value_source);
printf("# Expected: ");
PrintfValue(expected);
printf("\n");
printf("# Found: ");
PrintfValue(value);
printf("\n");
abort();
}
}
template<>
inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
const char* expected,
const char* value_source,
const char* value) {
if ((expected == NULL && value != NULL) ||
(expected != NULL && value == NULL)) {
abort();
@ -88,36 +121,15 @@ static inline void CheckEqualsHelper(const char* file, int line,
}
}
static inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
int expected,
const char* value_source,
int value) {
if (expected != value) {
printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n"
"# Expected: %d\n"
"# Found: %d\n",
file, line, expected_source, value_source, expected, value);
abort();
}
template<>
inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
const char* expected,
const char* value_source,
char* value) {
CheckEqualsHelper(file, line, expected_source, expected, value_source, static_cast<const char*>(value));
}
static inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
double expected,
const char* value_source,
double value) {
// If expected and value are NaNs then expected != value.
if (expected != value && (expected == expected || value == value)) {
printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n"
"# Expected: %.30e\n"
"# Found: %.30e\n",
file, line, expected_source, value_source, expected, value);
abort();
}
}
class CcTest {
public:
typedef void (TestFunction)();

View file

@ -43,7 +43,7 @@ using namespace double_conversion;
// Removes trailing '0' digits.
// Can return the empty string if all digits are 0.
static void TrimRepresentation(Vector<char> representation) {
int len = strlen(representation.start());
int len = static_cast<int>(strlen(representation.start()));
int i;
for (i = len - 1; i >= 0; --i) {
if (representation[i] != '0') break;

View file

@ -39,12 +39,14 @@ using namespace double_conversion;
static const int kBufferSize = 1024;
static void AssignHexString(Bignum* bignum, const char* str) {
bignum->AssignHexString(Vector<const char>(str, strlen(str)));
int len = static_cast<int>(strlen(str));
bignum->AssignHexString(Vector<const char>(str, len));
}
static void AssignDecimalString(Bignum* bignum, const char* str) {
bignum->AssignDecimalString(Vector<const char>(str, strlen(str)));
int len = static_cast<int>(strlen(str));
bignum->AssignDecimalString(Vector<const char>(str, len));
}

View file

@ -2072,14 +2072,14 @@ static double StrToD(const char* str, int flags, double empty_string_value,
uc16 separator = StringToDoubleConverter::kNoSeparator) {
StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
NULL, NULL, separator);
double result = converter.StringToDouble(str, strlen(str),
int len = static_cast<int>(strlen(str));
double result = converter.StringToDouble(str, len,
processed_characters_count);
*processed_all =
((strlen(str) == static_cast<unsigned>(*processed_characters_count)));
uc16 buffer16[256];
DOUBLE_CONVERSION_ASSERT(strlen(str) < DOUBLE_CONVERSION_ARRAY_SIZE(buffer16));
int len = strlen(str);
for (int i = 0; i < len; i++) {
buffer16[i] = str[i];
}
@ -4186,25 +4186,25 @@ static float StrToF16(const uc16* str16, int length, int flags,
bool* processed_all) {
StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
NULL, NULL);
double result =
float result =
converter.StringToFloat(str16, length, processed_characters_count);
*processed_all = (length == *processed_characters_count);
return result;
}
static double StrToF(const char* str, int flags, double empty_string_value,
int* processed_characters_count, bool* processed_all) {
static float StrToF(const char* str, int flags, double empty_string_value,
int* processed_characters_count, bool* processed_all) {
StringToDoubleConverter converter(flags, empty_string_value, Single::NaN(),
NULL, NULL);
float result = converter.StringToFloat(str, strlen(str),
int len = static_cast<int>(strlen(str));
float result = converter.StringToFloat(str, len,
processed_characters_count);
*processed_all =
((strlen(str) == static_cast<unsigned>(*processed_characters_count)));
uc16 buffer16[256];
DOUBLE_CONVERSION_ASSERT(strlen(str) < DOUBLE_CONVERSION_ARRAY_SIZE(buffer16));
int len = strlen(str);
for (int i = 0; i < len; i++) {
buffer16[i] = str[i];
}

View file

@ -66,7 +66,7 @@ static void DoubleToAscii(double v, DtoaMode test_mode, int requested_digits,
// Removes trailing '0' digits.
static void TrimRepresentation(Vector<char> representation) {
int len = strlen(representation.start());
int len = static_cast<int>(strlen(representation.start()));
int i;
for (i = len - 1; i >= 0; --i) {
if (representation[i] != '0') break;
@ -229,13 +229,13 @@ TEST(DtoaVariousDoubles) {
DoubleToAscii(-2147483648.0, SHORTEST, 0,
buffer, &sign, &length, &point);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_EQ("2147483648", buffer.start());
CHECK_EQ(10, point);
DoubleToAscii(-2147483648.0, SHORTEST_SINGLE, 0,
buffer, &sign, &length, &point);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_EQ("21474836", buffer.start());
CHECK_EQ(10, point);
@ -243,7 +243,7 @@ TEST(DtoaVariousDoubles) {
DoubleToAscii(-2147483648.0, FIXED, 2, buffer, &sign, &length, &point);
CHECK_GE(2, length - point);
TrimRepresentation(buffer);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_EQ("2147483648", buffer.start());
CHECK_EQ(10, point);
@ -251,19 +251,19 @@ TEST(DtoaVariousDoubles) {
buffer, &sign, &length, &point);
CHECK_GE(5, length);
TrimRepresentation(buffer);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_EQ("21475", buffer.start());
CHECK_EQ(10, point);
DoubleToAscii(-3.5844466002796428e+298, SHORTEST, 0,
buffer, &sign, &length, &point);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_EQ("35844466002796428", buffer.start());
CHECK_EQ(299, point);
DoubleToAscii(-3.5844466002796428e+298, PRECISION, 10,
buffer, &sign, &length, &point);
CHECK_EQ(1, sign);
CHECK_EQ(true, sign);
CHECK_GE(10, length);
TrimRepresentation(buffer);
CHECK_EQ("35844466", buffer.start());
@ -307,7 +307,7 @@ TEST(DtoaVariousDoubles) {
DoubleToAscii(4128420500802942e-24, SHORTEST, 0,
buffer, &sign, &length, &point);
CHECK_EQ(0, sign);
CHECK_EQ(false, sign);
CHECK_EQ("4128420500802942", buffer.start());
CHECK_EQ(-8, point);

View file

@ -43,7 +43,7 @@ static const int kBufferSize = 100;
// Removes trailing '0' digits.
static void TrimRepresentation(Vector<char> representation) {
int len = strlen(representation.start());
int len = static_cast<int>(strlen(representation.start()));
int i;
for (i = len - 1; i >= 0; --i) {
if (representation[i] != '0') break;

View file

@ -88,18 +88,18 @@ TEST(Single_AsDiyFp) {
DiyFp diy_fp = Single(ordered).AsDiyFp();
CHECK_EQ(0x2 - 0x7F - 23, diy_fp.e());
// The 23 mantissa bits, plus the implicit 1 in bit 24 as a uint32_t.
CHECK_EQ(0xA34567, diy_fp.f());
CHECK_EQ(0xA34567u, diy_fp.f());
uint32_t min_float32 = 0x00000001;
diy_fp = Single(min_float32).AsDiyFp();
CHECK_EQ(-0x7F - 23 + 1, diy_fp.e());
// This is a denormal; so no hidden bit.
CHECK_EQ(1, diy_fp.f());
CHECK_EQ(1u, diy_fp.f());
uint32_t max_float32 = 0x7f7fffff;
diy_fp = Single(max_float32).AsDiyFp();
CHECK_EQ(0xFE - 0x7F - 23, diy_fp.e());
CHECK_EQ(0x00ffffff, diy_fp.f());
CHECK_EQ(0x00ffffffu, diy_fp.f());
}
@ -459,5 +459,9 @@ TEST(SignalingNanSingle) {
CHECK(nan.IsNan());
CHECK(nan.IsQuietNan());
CHECK(Single(std::numeric_limits<float>::quiet_NaN()).IsQuietNan());
#ifndef _MSC_VER
// Visual studio has a bug for generating signaling NaNs:
// https://developercommunity.visualstudio.com/t/stdnumeric-limitssignaling-nan-returns-quiet-nan/155064
CHECK(Single(std::numeric_limits<float>::signaling_NaN()).IsSignalingNan());
#endif
}

View file

@ -37,7 +37,8 @@
using namespace double_conversion;
static Vector<const char> StringToVector(const char* str) {
return Vector<const char>(str, strlen(str));
int len = static_cast<int>(strlen(str));
return Vector<const char>(str, len);
}