// Dick Hollenbeck's KiROUND R&D

// 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;
}
This commit is contained in:
Dick Hollenbeck
2012-04-19 01:55:45 -05:00
parent 487ac04a1b
commit c53c5b47ea
60 changed files with 314 additions and 272 deletions
+7 -7
View File
@@ -160,7 +160,7 @@ void PS_PLOTTER::arc( wxPoint centre, int StAngle, int EndAngle, int radius,
// Calculate start point.
user_to_device_coordinates( centre );
radius = wxRound( user_to_device_size( radius ) );
radius = KiROUND( user_to_device_size( radius ) );
if( plotMirror )
fprintf( output_file, "%d %d %d %g %g arc%d\n", centre.x, centre.y,
radius, (double) -EndAngle / 10, (double) -StAngle / 10,
@@ -216,8 +216,8 @@ void PS_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor
pix_size.x = aImage.GetWidth();
pix_size.y = aImage.GetHeight();
wxSize drawsize; // requested size of image
drawsize.x = wxRound( aScaleFactor * pix_size.x );
drawsize.y = wxRound( aScaleFactor * pix_size.y );
drawsize.x = KiROUND( aScaleFactor * pix_size.x );
drawsize.y = KiROUND( aScaleFactor * pix_size.y );
// calculate the bottom left corner position of bitmap
wxPoint start = aPos;
@@ -405,14 +405,14 @@ bool PS_PLOTTER::start_plot( FILE* fout )
if( pageInfo.IsCustom() )
fprintf( output_file, "%%%%DocumentMedia: Custom %d %d 0 () ()\n",
wxRound( psPageSize.x * 10 * CONV_SCALE ),
wxRound( psPageSize.y * 10 * CONV_SCALE ) );
KiROUND( psPageSize.x * 10 * CONV_SCALE ),
KiROUND( psPageSize.y * 10 * CONV_SCALE ) );
else // a standard paper size
fprintf( output_file, "%%%%DocumentMedia: %s %d %d 0 () ()\n",
TO_UTF8( pageInfo.GetType() ),
wxRound( psPageSize.x * 10 * CONV_SCALE ),
wxRound( psPageSize.y * 10 * CONV_SCALE ) );
KiROUND( psPageSize.x * 10 * CONV_SCALE ),
KiROUND( psPageSize.y * 10 * CONV_SCALE ) );
if( pageInfo.IsPortrait() )
fprintf( output_file, "%%%%Orientation: Portrait\n" );