# HG changeset patch # User Grumpy7 # Date 1370087520 -7200 # Node ID 71ba92960bc542cec037443b1b930130c7df22e3 # Parent d98415be04ca13ea517b49cc2356c98e1105458d banker's rounding template made as fast as before and a bit more safe diff -r d98415be04ca -r 71ba92960bc5 Math.h --- a/Math.h Fri May 31 23:38:43 2013 +0200 +++ b/Math.h Sat Jun 01 13:52:00 2013 +0200 @@ -1,5 +1,7 @@ #pragma once - +#include +#include +#include /* 186 */ @@ -37,76 +39,44 @@ #include #include -namespace rounding -{ - - //-------------------------------------------------------------------------- - // round down - // Bias: -Infinity - using std::floor; - - //-------------------------------------------------------------------------- - // round up - // Bias: +Infinity - using std::ceil; +template +int bankersRounding( + const FloatType& value + ) { + assert("Method unsupported for this type" && false); + return value; +} - //-------------------------------------------------------------------------- - // symmetric round up - // Bias: away from zero - template - FloatType ceil0( const FloatType& value ) +template<> static int bankersRounding(const float& inValue) +{ + union Cast { - FloatType result = std::ceil( std::fabs( value ) ); - return (value < 0.0) ? -result : result; - } - - //-------------------------------------------------------------------------- - // Common rounding: round half up - // Bias: +Infinity - template - FloatType roundhalfup( const FloatType& value ) - { - return std::floor( value +0.5 ); - } + double d; + long l; + }; + volatile Cast c; + c.d = inValue + 6755399441055744.0; + return c.l; +} - //-------------------------------------------------------------------------- - // symmetric round half up - // Bias: away from zero - template - FloatType roundhalfup0( const FloatType& value ) - { - FloatType result = roundhalfup( std::fabs( value ) ); - return (value < 0.0) ? -result : result; - } - - //-------------------------------------------------------------------------- - // round half even (banker's rounding) - // Bias: none - template - FloatType bankersRounding( - const FloatType& value, - const FloatType& epsilon = ROUNDING_EPSILON - ) { - if (value < 0.0) return -bankersRounding ( -value, epsilon ); +#pragma push_macro("max") +#undef max - FloatType ipart; - std::modf( value, &ipart ); - - // If 'value' is exctly halfway between two integers - if (abs((value -(ipart +0.5))) < epsilon) - { - // If 'ipart' is even then return 'ipart' - if (std::fmod( ipart, 2.0 ) < epsilon) - return ipart; +template<> static int bankersRounding(const double& inValue) +{ + double maxValue = std::numeric_limits::max(); + assert(maxValue - 6755399441055744.0 >= inValue); + union Cast + { + double d; + long l; + }; + volatile Cast c; + c.d = inValue + 6755399441055744.0; + return c.l; +} - // Else return the nearest even integer - return ceil0( ipart +0.5 ); - } - // Otherwise use the usual round to closest - // (Either symmetric half-up or half-down will do0 - return roundhalfup0( value ); - } +#pragma pop_macro("max") -} extern struct stru193_math *stru_5C6E00; \ No newline at end of file diff -r d98415be04ca -r 71ba92960bc5 mm7_2.cpp --- a/mm7_2.cpp Fri May 31 23:38:43 2013 +0200 +++ b/mm7_2.cpp Sat Jun 01 13:52:00 2013 +0200 @@ -2236,9 +2236,7 @@ float a6bj; // [sp+A0h] [bp+18h]@218 unsigned int a6r; // [sp+A0h] [bp+18h]@218 int dstdiffmult; - - using namespace rounding; - + int probablyBitDepth = this->field_20.field_C; switch(probablyBitDepth) {