Files
harbour-core/contrib/hbnf/round.prg
vszakats 9687850865 2013-03-16 02:10 UTC+0100 Viktor Szakats (harbour syenar.net)
* (all files)
    * stripped svn header
    * minor cleanups
    ; use following command to find out the history of files:
       git log
       git log --follow
       git blame
       git annotate
2013-03-16 02:11:42 +01:00

103 lines
3.0 KiB
Plaintext

/*
* Author....: David Husnian
* CIS ID....: ?
*
* This is an original work by David Husnian and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* Rev 1.2 15 Aug 1991 23:05:30 GLENN
* Forest Belt proofread/edited/cleaned up doc
*
* Rev 1.1 14 Jun 1991 19:52:48 GLENN
* Minor edit to file header
*
* Rev 1.0 01 Apr 1991 01:02:08 GLENN
* Nanforum Toolkit
*
*/
#define NEAREST_DECIMAL "D"
#define NEAREST_FRACTION "F"
#define NEAREST_WHOLE_NUMBER "W"
#define ROUND_DOWN "D"
#define ROUND_NORMAL "N"
#define ROUND_UP "U"
FUNCTION ft_Round( nNumber, nRoundToAmount, cRoundType, cRoundDirection, ;
nAcceptableError )
LOCAL nResult := Abs( nNumber ) // The Result of the Rounding
__defaultNIL( @nRoundToAmount, 2 )
__defaultNIL( @cRoundType, NEAREST_DECIMAL )
__defaultNIL( @cRoundDirection, ROUND_NORMAL )
__defaultNIL( @nAcceptableError, 1 / ( nRoundToAmount ^ 2 ) )
// Are We Rounding to the Nearest Whole
// Number or to Zero Decimal Places??
IF !( Left( cRoundType, 1 ) == NEAREST_WHOLE_NUMBER ) .AND. ;
( nRoundToAmount := Int( nRoundToAmount ) ) != 0
// No, Are We Rounding to the Nearest
// Decimal Place??
IF Left( cRoundType, 1 ) == NEAREST_DECIMAL
// Yes, Convert to Nearest Fraction
nRoundToAmount := 10 ^ nRoundToAmount
ENDIF
// Are We Already Within the Acceptable
// Error Factor??
IF Abs( Int( nResult * nRoundToAmount ) - ( nResult * nRoundToAmount ) ) > nAcceptableError
// No, Are We Rounding Down??
nResult -= iif( Left( cRoundDirection, 1 ) == ROUND_DOWN, ;
; // Yes, Make Downward Adjustment
1 / nRoundToAmount / 2, ;
; // Are We Rounding Up??
iif( Left( cRoundDirection, 1 ) == ROUND_UP, ;
; // Yes, Make Upward Adjustment
-1 / nRoundToAmount / 2, ;
; // No, Rounding Normal, No Adjustment
0 ) )
// Do the Actual Rounding
nResult := Int( ( nRoundToAmount * nResult ) + .5 + nAcceptableError ) / ;
nRoundToAmount
ENDIF
ELSE
// Yes, Round to Nearest Whole Number
// or to Zero Places
nRoundToAmount := Max( nRoundToAmount, 1 )
DO CASE // Do "Whole" Rounding
CASE Left( cRoundDirection, 1 ) == ROUND_UP
nResult := ( Int( nResult / nRoundToAmount ) * nRoundToAmount ) + ;
nRoundToAmount
CASE Left( cRoundDirection, 1 ) == ROUND_DOWN
nResult := Int( nResult / nRoundToAmount ) * nRoundToAmount
OTHERWISE // Round Normally
nResult := Int( ( nResult + nRoundToAmount / 2 ) / nRoundToAmount ) * ;
nRoundToAmount
ENDCASE
ENDIF
IF nNumber < 0 // Was the Number Negative??
nResult := -nResult // Yes, Make the Result Negative Also
ENDIF
RETURN nResult