diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 331490e..97e3b4c 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -138,6 +138,24 @@ namespace bx return float( (0.0f < _a) - (0.0f > _a) ); } + inline BX_CONSTEXPR_FUNC bool signbit(float _a) + { +#if BX_COMPILER_MSVC + return _signbit(_a); +#else + return __builtin_signbit(_a); +#endif // BX_COMPILER_MSVC + } + + inline BX_CONSTEXPR_FUNC float copysign(float _value, float _sign) + { +#if BX_COMPILER_MSVC + return _copysign(_value, _sign); +#else + return __builtin_copysign(_value, _sign); +#endif // BX_COMPILER_MSVC + } + inline BX_CONSTEXPR_FUNC float abs(float _a) { return _a < 0.0f ? -_a : _a; diff --git a/include/bx/math.h b/include/bx/math.h index 26d68ef..7441a28 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -174,10 +174,27 @@ namespace bx /// /// @param[in] _a Value. /// - /// @returns -1 if `_a` less than zero, 0 if `_a` is equal to 0, or +1 if `_a` is greater than zero. + /// @returns -1 if `_a` is less than zero, 0 if `_a` is equal to 0, or +1 if `_a` is greater than zero. /// BX_CONSTEXPR_FUNC float sign(float _a); + /// Returns `true` if the velue `_a` is negative. + /// + /// @param[in] _a Value. + /// + /// @returns `true` if `_a` is less than zero, otherwise returns `false`. + /// + BX_CONSTEXPR_FUNC bool signbit(float _a); + + /// Returns value with the magnitude `_value`, and the sign of `_sign`. + /// + /// @param[in] _value Value. + /// @param[in] _sign Sign. + /// + /// @returns Value with the magnitude `_value`, and the sign of `_sign`. + /// + BX_CONSTEXPR_FUNC float copysign(float _value, float _sign); + /// Returns the absolute of _a. /// BX_CONSTEXPR_FUNC float abs(float _a); diff --git a/tests/math_test.cpp b/tests/math_test.cpp index b4f63fd..88f63c3 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -303,9 +303,31 @@ TEST_CASE("atan2", "") TEST_CASE("sign", "") { - REQUIRE(-1 == bx::sign(-0.1389f) ); - REQUIRE( 0 == bx::sign( 0.0000f) ); - REQUIRE( 1 == bx::sign( 0.1389f) ); + STATIC_REQUIRE(-1 == bx::sign(-0.1389f) ); + STATIC_REQUIRE( 0 == bx::sign( 0.0000f) ); + STATIC_REQUIRE( 1 == bx::sign( 0.1389f) ); + + REQUIRE(-1 == bx::sign(-bx::kFloatInfinity) ); + REQUIRE( 1 == bx::sign( bx::kFloatInfinity) ); +} + +TEST_CASE("signbit", "") +{ + STATIC_REQUIRE( bx::signbit(-0.1389f) ); + STATIC_REQUIRE(!bx::signbit( 0.0000f) ); + STATIC_REQUIRE(!bx::signbit( 0.1389f) ); + + REQUIRE( bx::signbit(-bx::kFloatInfinity) ); + REQUIRE(!bx::signbit( bx::kFloatInfinity) ); +} + +TEST_CASE("copysign", "") +{ + STATIC_REQUIRE( 0.1389f == bx::copysign(-0.1389f, +1389) ); + STATIC_REQUIRE(-0.0000f == bx::copysign( 0.0000f, -1389) ); + STATIC_REQUIRE(-0.1389f == bx::copysign( 0.1389f, -1389) ); + + REQUIRE(-bx::kFloatInfinity == bx::copysign(bx::kFloatInfinity, -1389) ); } TEST_CASE("ToBits", "")