• Dick Hollenbeck's avatar
    // Dick Hollenbeck's KiROUND R&D · c24863c0
    Dick Hollenbeck authored
    // This provides better project control over rounding to int from double
    // than wxRound() did.  This scheme provides better logging in Debug builds
    // and it provides for compile time calculation of constants.
    
    
    #include <stdio.h>
    #include <assert.h>
    #include <limits.h>
    
    //-----<KiROUND KIT>------------------------------------------------------------
    
    /**
     * KiROUND
     * rounds a floating point number to an int using
     * "round halfway cases away from zero".
     * In Debug build an assert fires if will not fit into an int.
     */
    
    #if defined( DEBUG )
    
    // DEBUG: a macro to capture line and file, then calls this inline
    
    static inline int KiRound( double v, int line, const char* filename )
    {
        v = v < 0 ? v - 0.5 : v + 0.5;
        if( v > INT_MAX + 0.5 )
        {
            printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
        }
        else if( v < INT_MIN - 0.5 )
        {
            printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
        }
        return int( v );
    }
    
    #define KiROUND( v )    KiRound( v, __LINE__, __FILE__ )
    
    #else
    
    // RELEASE: a macro so compile can pre-compute constants.
    
    #define KiROUND( v )  int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
    
    #endif
    
    
    //-----</KiROUND KIT>-----------------------------------------------------------
    
    // Only a macro is compile time calculated, an inline function causes a static constructor
    // in a situation like this.
    // Therefore the Release build is best done with a MACRO not an inline function.
    int Computed = KiROUND( 14.3 * 8 );
    
    
    int main( int argc, char** argv )
    {
        for( double d = double(INT_MAX)-1;  d < double(INT_MAX)+8;  d += 2.0 )
        {
            int i = KiROUND( d );
    
            printf( "t: %d  %.16g\n", i, d );
        }
    
        return 0;
    }
    c24863c0
gpcb_exchange.cpp 20.1 KB