From ac47b863b0f9ff469697851dcd4a14056f778966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Mon, 12 Nov 2018 19:20:31 -0800 Subject: [PATCH] Switch to C++14. --- include/bx/inline/math.inl | 54 ++++++++++++------------- include/bx/math.h | 74 +++++++++++++++++----------------- scripts/toolchain.lua | 28 ++++++------- src/math.cpp | 80 ++++++++++++++++--------------------- tests/string_test.cpp | 81 +++++++++++++++++++++++++------------- 5 files changed, 164 insertions(+), 153 deletions(-) diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 1016c83..9aaa9b6 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -23,25 +23,25 @@ namespace bx return _rad * 180.0f / kPi; } - inline BX_CONST_FUNC uint32_t floatToBits(float _a) + inline constexpr BX_CONST_FUNC uint32_t floatToBits(float _a) { union { float f; uint32_t ui; } u = { _a }; return u.ui; } - inline BX_CONST_FUNC float bitsToFloat(uint32_t _a) + inline constexpr BX_CONST_FUNC float bitsToFloat(uint32_t _a) { union { uint32_t ui; float f; } u = { _a }; return u.f; } - inline BX_CONST_FUNC uint64_t doubleToBits(double _a) + inline constexpr BX_CONST_FUNC uint64_t doubleToBits(double _a) { union { double f; uint64_t ui; } u = { _a }; return u.ui; } - inline BX_CONST_FUNC double bitsToDouble(uint64_t _a) + inline constexpr BX_CONST_FUNC double bitsToDouble(uint64_t _a) { union { uint64_t ui; double f; } u = { _a }; return u.f; @@ -58,37 +58,37 @@ namespace bx return result; } - inline BX_CONST_FUNC bool isNan(float _f) + inline constexpr BX_CONST_FUNC bool isNan(float _f) { const uint32_t tmp = floatToBits(_f) & INT32_MAX; return tmp > UINT32_C(0x7f800000); } - inline BX_CONST_FUNC bool isNan(double _f) + inline constexpr BX_CONST_FUNC bool isNan(double _f) { const uint64_t tmp = doubleToBits(_f) & INT64_MAX; return tmp > UINT64_C(0x7ff0000000000000); } - inline BX_CONST_FUNC bool isFinite(float _f) + inline constexpr BX_CONST_FUNC bool isFinite(float _f) { const uint32_t tmp = floatToBits(_f) & INT32_MAX; return tmp < UINT32_C(0x7f800000); } - inline BX_CONST_FUNC bool isFinite(double _f) + inline constexpr BX_CONST_FUNC bool isFinite(double _f) { const uint64_t tmp = doubleToBits(_f) & INT64_MAX; return tmp < UINT64_C(0x7ff0000000000000); } - inline BX_CONST_FUNC bool isInfinite(float _f) + inline constexpr BX_CONST_FUNC bool isInfinite(float _f) { const uint32_t tmp = floatToBits(_f) & INT32_MAX; return tmp == UINT32_C(0x7f800000); } - inline BX_CONST_FUNC bool isInfinite(double _f) + inline constexpr BX_CONST_FUNC bool isInfinite(double _f) { const uint64_t tmp = doubleToBits(_f) & INT64_MAX; return tmp == UINT64_C(0x7ff0000000000000); @@ -104,22 +104,22 @@ namespace bx return -floor(-_a); } - inline BX_CONST_FUNC float lerp(float _a, float _b, float _t) + inline constexpr BX_CONST_FUNC float lerp(float _a, float _b, float _t) { return _a + (_b - _a) * _t; } - inline BX_CONST_FUNC float abs(float _a) - { - return _a < 0.0f ? -_a : _a; - } - - inline BX_CONST_FUNC float sign(float _a) + inline constexpr BX_CONST_FUNC float sign(float _a) { return _a < 0.0f ? -1.0f : 1.0f; } - inline BX_CONST_FUNC float square(float _a) + inline constexpr BX_CONST_FUNC float abs(float _a) + { + return _a < 0.0f ? -_a : _a; + } + + inline constexpr BX_CONST_FUNC float square(float _a) { return _a * _a; } @@ -237,17 +237,17 @@ namespace bx #endif // BX_CONFIG_SUPPORTS_SIMD } - inline BX_CONST_FUNC float trunc(float _a) + inline constexpr BX_CONST_FUNC float trunc(float _a) { return float(int(_a) ); } - inline BX_CONST_FUNC float fract(float _a) + inline constexpr BX_CONST_FUNC float fract(float _a) { return _a - trunc(_a); } - inline BX_CONST_FUNC float mad(float _a, float _b, float _c) + inline constexpr BX_CONST_FUNC float mad(float _a, float _b, float _c) { return _a * _b + _c; } @@ -257,7 +257,7 @@ namespace bx return _a - _b * floor(_a / _b); } - inline BX_CONST_FUNC bool equal(float _a, float _b, float _epsilon) + inline constexpr BX_CONST_FUNC bool equal(float _a, float _b, float _epsilon) { // Reference: // https://web.archive.org/web/20181103180318/http://realtimecollisiondetection.net/blog/?p=89 @@ -283,27 +283,27 @@ namespace bx return result; } - inline BX_CONST_FUNC float step(float _edge, float _a) + inline constexpr BX_CONST_FUNC float step(float _edge, float _a) { return _a < _edge ? 0.0f : 1.0f; } - inline BX_CONST_FUNC float pulse(float _a, float _start, float _end) + inline constexpr BX_CONST_FUNC float pulse(float _a, float _start, float _end) { return step(_a, _start) - step(_a, _end); } - inline BX_CONST_FUNC float smoothStep(float _a) + inline constexpr BX_CONST_FUNC float smoothStep(float _a) { return square(_a)*(3.0f - 2.0f*_a); } - inline BX_CONST_FUNC float bias(float _time, float _bias) + inline constexpr BX_CONST_FUNC float bias(float _time, float _bias) { return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f); } - inline BX_CONST_FUNC float gain(float _time, float _gain) + inline constexpr BX_CONST_FUNC float gain(float _time, float _gain) { if (_time < 0.5f) { diff --git a/include/bx/math.h b/include/bx/math.h index 4d9fce3..3f5c25c 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -13,21 +13,21 @@ namespace bx { - extern const float kPi; - extern const float kPi2; - extern const float kInvPi; - extern const float kPiHalf; - extern const float kPiQuarter; - extern const float kSqrt2; - extern const float kLogNat10; - extern const float kInvLogNat2; - extern const float kLogNat2Hi; - extern const float kLogNat2Lo; - extern const float kE; - extern const float kNearZero; + constexpr float kPi = 3.1415926535897932384626433832795f; + constexpr float kPi2 = 6.2831853071795864769252867665590f; + constexpr float kInvPi = 1.0f/kPi; + constexpr float kPiHalf = 1.5707963267948966192313216916398f; + constexpr float kPiQuarter = 0.7853981633974483096156608458199f; + constexpr float kSqrt2 = 1.4142135623730950488016887242097f; + constexpr float kLogNat10 = 2.3025850929940456840179914546844f; + constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f; + constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f; + constexpr float kLogNat2Lo = 1.90821492927058770002e-10f; + constexpr float kE = 2.7182818284590452353602874713527f; + constexpr float kNearZero = 1.0f/float(1 << 28); + constexpr float kFloatMin = 1.175494e-38f; + constexpr float kFloatMax = 3.402823e+38f; extern const float kInfinity; - extern const float kFloatMin; - extern const float kFloatMax; /// typedef float (*LerpFn)(float _a, float _b, float _t); @@ -62,19 +62,19 @@ namespace bx /// Reinterprets the bit pattern of _a as uint32_t. /// - BX_CONST_FUNC uint32_t floatToBits(float _a); + constexpr BX_CONST_FUNC uint32_t floatToBits(float _a); /// Reinterprets the bit pattern of _a as float. /// - BX_CONST_FUNC float bitsToFloat(uint32_t _a); + constexpr BX_CONST_FUNC float bitsToFloat(uint32_t _a); /// Reinterprets the bit pattern of _a as uint64_t. /// - BX_CONST_FUNC uint64_t doubleToBits(double _a); + constexpr BX_CONST_FUNC uint64_t doubleToBits(double _a); /// Reinterprets the bit pattern of _a as double. /// - BX_CONST_FUNC double bitsToDouble(uint64_t _a); + constexpr BX_CONST_FUNC double bitsToDouble(uint64_t _a); /// Returns sortable floating point value. /// @@ -82,27 +82,27 @@ namespace bx /// Returns true if _f is a number that is NaN. /// - BX_CONST_FUNC bool isNan(float _f); + constexpr BX_CONST_FUNC bool isNan(float _f); /// Returns true if _f is a number that is NaN. /// - BX_CONST_FUNC bool isNan(double _f); + constexpr BX_CONST_FUNC bool isNan(double _f); /// Returns true if _f is not infinite and is not a NaN. /// - BX_CONST_FUNC bool isFinite(float _f); + constexpr BX_CONST_FUNC bool isFinite(float _f); /// Returns true if _f is not infinite and is not a NaN. /// - BX_CONST_FUNC bool isFinite(double _f); + constexpr BX_CONST_FUNC bool isFinite(double _f); /// Returns true if _f is infinite and is not a NaN. /// - BX_CONST_FUNC bool isInfinite(float _f); + constexpr BX_CONST_FUNC bool isInfinite(float _f); /// Returns true if _f is infinite and is not a NaN. /// - BX_CONST_FUNC bool isInfinite(double _f); + constexpr BX_CONST_FUNC bool isInfinite(double _f); /// Returns the largest integer value not greater than _f. /// @@ -118,19 +118,19 @@ namespace bx /// Returns linear interpolation between two values _a and _b. /// - BX_CONST_FUNC float lerp(float _a, float _b, float _t); + constexpr BX_CONST_FUNC float lerp(float _a, float _b, float _t); /// Returns the sign of _a. /// - BX_CONST_FUNC float sign(float _a); + constexpr BX_CONST_FUNC float sign(float _a); /// Returns the absolute of _a. /// - BX_CONST_FUNC float abs(float _a); + constexpr BX_CONST_FUNC float abs(float _a); /// Returns the square of _a. /// - BX_CONST_FUNC float square(float _a); + constexpr BX_CONST_FUNC float square(float _a); /// Returns the cosine of the argument _a. /// @@ -211,23 +211,23 @@ namespace bx /// Returns the nearest integer not greater in magnitude than _a. /// - BX_CONST_FUNC float trunc(float _a); + constexpr BX_CONST_FUNC float trunc(float _a); /// Returns the fractional (or decimal) part of _a, which is greater than or equal to 0 /// and less than 1. /// - BX_CONST_FUNC float fract(float _a); + constexpr BX_CONST_FUNC float fract(float _a); /// Returns result of multipla and add (_a * _b + _c). /// - BX_CONST_FUNC float mad(float _a, float _b, float _c); + constexpr BX_CONST_FUNC float mad(float _a, float _b, float _c); /// Returns the floating-point remainder of the division operation _a/_b. /// BX_CONST_FUNC float mod(float _a, float _b); /// - BX_CONST_FUNC bool equal(float _a, float _b, float _epsilon); + constexpr BX_CONST_FUNC bool equal(float _a, float _b, float _epsilon); /// BX_CONST_FUNC bool equal(const float* _a, const float* _b, uint32_t _num, float _epsilon); @@ -236,23 +236,23 @@ namespace bx BX_CONST_FUNC float wrap(float _a, float _wrap); /// - BX_CONST_FUNC float step(float _edge, float _a); + constexpr BX_CONST_FUNC float step(float _edge, float _a); /// - BX_CONST_FUNC float pulse(float _a, float _start, float _end); + constexpr BX_CONST_FUNC float pulse(float _a, float _start, float _end); /// - BX_CONST_FUNC float smoothStep(float _a); + constexpr BX_CONST_FUNC float smoothStep(float _a); // References: // - Bias And Gain Are Your Friend // http://blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend/ // - http://demofox.org/biasgain.html /// - BX_CONST_FUNC float bias(float _time, float _bias); + constexpr BX_CONST_FUNC float bias(float _time, float _bias); /// - BX_CONST_FUNC float gain(float _time, float _gain); + constexpr BX_CONST_FUNC float gain(float _time, float _gain); /// BX_CONST_FUNC float angleDiff(float _a, float _b); diff --git a/scripts/toolchain.lua b/scripts/toolchain.lua index af8f7a3..479b228 100644 --- a/scripts/toolchain.lua +++ b/scripts/toolchain.lua @@ -648,7 +648,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } linkoptions { "-Wl,--gc-sections", @@ -737,7 +737,7 @@ function toolchain(_buildDir, _libDir) -- "-Wuseless-cast", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } links { "rt", @@ -794,7 +794,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } links { "rt", @@ -813,7 +813,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } links { "rt", @@ -854,7 +854,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } linkoptions { "-no-canonical-prefixes", @@ -873,7 +873,7 @@ function toolchain(_buildDir, _libDir) "__STEAMLINK__=1", -- There is no special prefedined compiler symbol to detect SteamLink, faking it. } buildoptions { - "-std=c++11", + "-std=c++14", "-Wfatal-errors", "-Wunused-value", "-Wundef", @@ -989,7 +989,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } configuration { "freebsd" } @@ -1049,10 +1049,10 @@ function toolchain(_buildDir, _libDir) configuration { "osx" } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } buildoptions_objcpp { - "-std=c++11", + "-std=c++14", } buildoptions { "-Wfatal-errors", @@ -1067,10 +1067,10 @@ function toolchain(_buildDir, _libDir) "-lc++", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } buildoptions_objcpp { - "-std=c++11", + "-std=c++14", } buildoptions { "-Wfatal-errors", @@ -1215,7 +1215,7 @@ function toolchain(_buildDir, _libDir) "$(SCE_ORBIS_SDK_DIR)/target/include_common", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } configuration { "rpi" } @@ -1234,7 +1234,7 @@ function toolchain(_buildDir, _libDir) "-Wundef", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } includedirs { "/opt/vc/include", @@ -1266,7 +1266,7 @@ function toolchain(_buildDir, _libDir) "--sysroot=$(FREEDOM_E_SDK)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/riscv64-unknown-elf", } buildoptions_cpp { - "-std=c++11", + "-std=c++14", } configuration {} -- reset configuration diff --git a/src/math.cpp b/src/math.cpp index cffe8c6..bff1f22 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -9,35 +9,21 @@ namespace bx { - const float kPi = 3.1415926535897932384626433832795f; - const float kPi2 = 6.2831853071795864769252867665590f; - const float kInvPi = 1.0f/kPi; - const float kPiHalf = 1.5707963267948966192313216916398f; - const float kPiQuarter = 0.7853981633974483096156608458199f; - const float kSqrt2 = 1.4142135623730950488016887242097f; - const float kLogNat10 = 2.3025850929940456840179914546844f; - const float kInvLogNat2 = 1.4426950408889634073599246810019f; - const float kLogNat2Hi = 0.6931471805599453094172321214582f; - const float kLogNat2Lo = 1.90821492927058770002e-10f; - const float kE = 2.7182818284590452353602874713527f; - const float kNearZero = 1.0f/float(1 << 28); - const float kFloatMin = 1.175494e-38f; - const float kFloatMax = 3.402823e+38f; - const float kInfinity = bitsToFloat(UINT32_C(0x7f800000) ); + const float kInfinity = bitsToFloat(UINT32_C(0x7f800000) ); namespace { - static const float kSinC2 = -0.16666667163372039794921875f; - static const float kSinC4 = 8.333347737789154052734375e-3f; - static const float kSinC6 = -1.9842604524455964565277099609375e-4f; - static const float kSinC8 = 2.760012648650445044040679931640625e-6f; - static const float kSinC10 = -2.50293279435709337121807038784027099609375e-8f; + constexpr float kSinC2 = -0.16666667163372039794921875f; + constexpr float kSinC4 = 8.333347737789154052734375e-3f; + constexpr float kSinC6 = -1.9842604524455964565277099609375e-4f; + constexpr float kSinC8 = 2.760012648650445044040679931640625e-6f; + constexpr float kSinC10 = -2.50293279435709337121807038784027099609375e-8f; - static const float kCosC2 = -0.5f; - static const float kCosC4 = 4.166664183139801025390625e-2f; - static const float kCosC6 = -1.388833043165504932403564453125e-3f; - static const float kCosC8 = 2.47562347794882953166961669921875e-5f; - static const float kCosC10 = -2.59630184018533327616751194000244140625e-7f; + constexpr float kCosC2 = -0.5f; + constexpr float kCosC4 = 4.166664183139801025390625e-2f; + constexpr float kCosC6 = -1.388833043165504932403564453125e-3f; + constexpr float kCosC8 = 2.47562347794882953166961669921875e-5f; + constexpr float kCosC10 = -2.59630184018533327616751194000244140625e-7f; } // namespace @@ -86,10 +72,10 @@ namespace bx namespace { - static const float kAcosC0 = 1.5707288f; - static const float kAcosC1 = -0.2121144f; - static const float kAcosC2 = 0.0742610f; - static const float kAcosC3 = -0.0187293f; + constexpr float kAcosC0 = 1.5707288f; + constexpr float kAcosC1 = -0.2121144f; + constexpr float kAcosC2 = 0.0742610f; + constexpr float kAcosC3 = -0.0187293f; } // namespace @@ -109,12 +95,12 @@ namespace bx namespace { - static const float kAtan2C0 = -0.013480470f; - static const float kAtan2C1 = 0.057477314f; - static const float kAtan2C2 = -0.121239071f; - static const float kAtan2C3 = 0.195635925f; - static const float kAtan2C4 = -0.332994597f; - static const float kAtan2C5 = 0.999995630f; + constexpr float kAtan2C0 = -0.013480470f; + constexpr float kAtan2C1 = 0.057477314f; + constexpr float kAtan2C2 = -0.121239071f; + constexpr float kAtan2C3 = 0.195635925f; + constexpr float kAtan2C4 = -0.332994597f; + constexpr float kAtan2C5 = 0.999995630f; } // namespace @@ -175,11 +161,11 @@ namespace bx namespace { - static const float kExpC0 = 1.66666666666666019037e-01f; - static const float kExpC1 = -2.77777777770155933842e-03f; - static const float kExpC2 = 6.61375632143793436117e-05f; - static const float kExpC3 = -1.65339022054652515390e-06f; - static const float kExpC4 = 4.13813679705723846039e-08f; + constexpr float kExpC0 = 1.66666666666666019037e-01f; + constexpr float kExpC1 = -2.77777777770155933842e-03f; + constexpr float kExpC2 = 6.61375632143793436117e-05f; + constexpr float kExpC3 = -1.65339022054652515390e-06f; + constexpr float kExpC4 = 4.13813679705723846039e-08f; } // namespace @@ -209,13 +195,13 @@ namespace bx namespace { - static const float kLogC0 = 6.666666666666735130e-01f; - static const float kLogC1 = 3.999999999940941908e-01f; - static const float kLogC2 = 2.857142874366239149e-01f; - static const float kLogC3 = 2.222219843214978396e-01f; - static const float kLogC4 = 1.818357216161805012e-01f; - static const float kLogC5 = 1.531383769920937332e-01f; - static const float kLogC6 = 1.479819860511658591e-01f; + constexpr float kLogC0 = 6.666666666666735130e-01f; + constexpr float kLogC1 = 3.999999999940941908e-01f; + constexpr float kLogC2 = 2.857142874366239149e-01f; + constexpr float kLogC3 = 2.222219843214978396e-01f; + constexpr float kLogC4 = 1.818357216161805012e-01f; + constexpr float kLogC5 = 1.531383769920937332e-01f; + constexpr float kLogC6 = 1.479819860511658591e-01f; } // namespace diff --git a/tests/string_test.cpp b/tests/string_test.cpp index b261ee9..b7c4ed8 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -318,15 +318,16 @@ TEST_CASE("toString double", "") REQUIRE(testToString(-79.39773355813419, "-79.39773355813419") ); } -static bool testFromString(double _value, const char* _input) +template +static bool testFromString(Ty _value, const char* _input) { char tmp[1024]; bx::toString(tmp, BX_COUNTOF(tmp), _value); - double lhs; + Ty lhs; bx::fromString(&lhs, tmp); - double rhs; + Ty rhs; bx::fromString(&rhs, _input); if (lhs == rhs) @@ -338,33 +339,57 @@ static bool testFromString(double _value, const char* _input) return false; } +TEST_CASE("fromString float", "") +{ + REQUIRE(testFromString(std::numeric_limits::min(), "1.175494351e-38") ); + REQUIRE(testFromString(std::numeric_limits::lowest(), "-3.402823466e+38") ); + REQUIRE(testFromString(std::numeric_limits::max(), "3.402823466e+38") ); +} + TEST_CASE("fromString double", "") { - REQUIRE(testFromString(0.0, "0.0") ); - REQUIRE(testFromString(-0.0, "-0.0") ); - REQUIRE(testFromString(1.0, "1.0") ); - REQUIRE(testFromString(-1.0, "-1.0") ); - REQUIRE(testFromString(1.2345, "1.2345") ); - REQUIRE(testFromString(1.2345678, "1.2345678") ); - REQUIRE(testFromString(0.123456789012, "0.123456789012") ); - REQUIRE(testFromString(1234567.8, "1234567.8") ); - REQUIRE(testFromString(-79.39773355813419, "-79.39773355813419") ); - REQUIRE(testFromString(0.000001, "0.000001") ); - REQUIRE(testFromString(0.0000001, "1e-7") ); - REQUIRE(testFromString(1e30, "1e30") ); - REQUIRE(testFromString(1.234567890123456e30, "1.234567890123456e30") ); - REQUIRE(testFromString(-5e-324, "-5e-324") ); - REQUIRE(testFromString(2.225073858507201e-308, "2.225073858507201e-308") ); - REQUIRE(testFromString(2.2250738585072014e-308, "2.2250738585072014e-308") ); - REQUIRE(testFromString(1.7976931348623157e308, "1.7976931348623157e308") ); - REQUIRE(testFromString(0.00000123123123, "0.00000123123123") ); - REQUIRE(testFromString(0.000000123123123, "1.23123123e-7") ); - REQUIRE(testFromString(123123.123, "123123.123") ); - REQUIRE(testFromString(1231231.23, "1231231.23") ); - REQUIRE(testFromString(0.000000000123123, "1.23123e-10") ); - REQUIRE(testFromString(0.0000000001, "1e-10") ); - REQUIRE(testFromString(-270.000000, "-270.0") ); - REQUIRE(testFromString(2.2250738585072011e-308, "2.2250738585072011e-308") ); + REQUIRE(testFromString(0.0, "0.0") ); + REQUIRE(testFromString(-0.0, "-0.0") ); + REQUIRE(testFromString(1.0, "1.0") ); + REQUIRE(testFromString(-1.0, "-1.0") ); + REQUIRE(testFromString(1.2345, "1.2345") ); + REQUIRE(testFromString(1.2345678, "1.2345678") ); + REQUIRE(testFromString(0.123456789012, "0.123456789012") ); + REQUIRE(testFromString(123456.789, "123456.789") ); + REQUIRE(testFromString(1234567.8, "1234567.8") ); + REQUIRE(testFromString(-79.39773355813419, "-79.39773355813419") ); + REQUIRE(testFromString(0.000001, "0.000001") ); + REQUIRE(testFromString(0.0000001, "1e-7") ); + REQUIRE(testFromString(1e30, "1e30") ); + REQUIRE(testFromString(1.234567890123456e30, "1.234567890123456e30") ); + REQUIRE(testFromString(-5e-324, "-5e-324") ); + REQUIRE(testFromString(2.225073858507201e-308, "2.225073858507201e-308") ); + REQUIRE(testFromString(2.2250738585072014e-308, "2.2250738585072014e-308") ); + REQUIRE(testFromString(1.7976931348623157e308, "1.7976931348623157e308") ); + REQUIRE(testFromString(0.00000123123123, "0.00000123123123") ); + REQUIRE(testFromString(0.000000123123123, "1.23123123e-7") ); + REQUIRE(testFromString(123123.123, "123123.123") ); + REQUIRE(testFromString(1231231.23, "1231231.23") ); + REQUIRE(testFromString(0.000000000123123, "1.23123e-10") ); + REQUIRE(testFromString(0.0000000001, "1e-10") ); + REQUIRE(testFromString(-270.000000, "-270.0") ); + REQUIRE(testFromString(2.2250738585072011e-308, "2.2250738585072011e-308") ); // https://web.archive.org/web/20181112222123/https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ + REQUIRE(testFromString(2.2250738585072009e-308, "2.2250738585072009e-308") ); // Max subnormal double + REQUIRE(testFromString(4.9406564584124654e-324, "4.9406564584124654e-324") ); // Min denormal + REQUIRE(testFromString(1.7976931348623157e+308, "1.7976931348623157e+308") ); // Max double + +// warning: magnitude of floating-point constant too small for type 'double'; minimum is 4.9406564584124654E-324 +// REQUIRE(testFromString(1e-10000, "0.0") ); // Must underflow +// integer literal is too large to be represented in any integer type +// REQUIRE(testFromString(18446744073709551616, "18446744073709551616.0") ); // 2^64 (max of uint64_t + 1, force to use double) +// REQUIRE(testFromString(-9223372036854775809, "-9223372036854775809.0") ); // -2^63 - 1(min of int64_t + 1, force to use double) + + REQUIRE(testFromString(0.9868011474609375, "0.9868011474609375") ); // https://github.com/miloyip/rapidjson/issues/120 + REQUIRE(testFromString(123e34, "123e34") ); + REQUIRE(testFromString(45913141877270640000.0, "45913141877270640000.0") ); + REQUIRE(testFromString(std::numeric_limits::min(), "2.2250738585072014e-308") ); + REQUIRE(testFromString(std::numeric_limits::lowest(), "-1.7976931348623158e+308") ); + REQUIRE(testFromString(std::numeric_limits::max(), "1.7976931348623158e+308") ); } static bool testFromString(int32_t _value, const char* _input)