Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Round-Half-Up

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Round-Half-Up

    Code:
    #COMPILE EXE
    #DIM ALL
    '---------------------------------------------------
    ' Round-Half-Up - Round EXT to LONG
    '---------------------------------------------------
    ' The tricky point is what "up" means for negative numbers. Does it mean increasing
    ' in size towards negative infinity? Or does it mean increasing towards positive
    ' infinity? If it means increasing towards negative infinity then the algorithm
    ' is 'symmetric' with respect to zero for positive and negative values. If it means
    ' increasing towards positive infinity then the algorithm is 'asymmetric' with
    ' respect to zero for positive and negative values.
    ' .NET Math.Round(x, System.MidpointRounding.AwayFromZero) is symmetric.
    ' Python round() is symmetric.
    ' MATHLAB round() is symmetric.
    ' Java round() is assymmetric.
    '---------------------------------------------------
    FUNCTION RoundHalfUp_S (BYVAL extVal AS EXT) AS LONG
        ' symmetric implementation (-5.5 rounds to -6)
        FUNCTION = FIX(extVal + (SGN(extVal) * 0.5##))
    END FUNCTION
    '---------------------------------------------------
    FUNCTION RoundHalfUp_A(BYVAL extVal AS EXT) AS LONG
        ' asymmetric implementation (-5.5 rounds to -5).
        FUNCTION = FIX(extVal + IIF(SGN(extVal)=1, 0.5##, 0.0##))
    END FUNCTION
    '---------------------------------------------------
    FUNCTION PBMAIN() AS LONG
    
        LOCAL x AS EXT
    
        STDOUT "Symmetric"
        FOR x = 9.5## TO -9.5## STEP -0.5##
            STDOUT FORMAT$(x, "0.0") & " = " & FORMAT$(RoundHalfUp_S(x), "0")
        NEXT x
    
        STDOUT
    
        STDOUT "Asymmetric"
        FOR x = 9.5## TO -9.5## STEP -0.5##
            STDOUT FORMAT$(x, "0.0") & " = " & FORMAT$(RoundHalfUp_A(x), "0")
        NEXT x
    
        STDOUT $CRLF & "Press any key to exit ... ";
        WAITKEY$
        STDOUT
    
    END FUNCTION
    Last edited by Greg Lyon; 16 Jun 2008, 03:18 PM. Reason: Modified the asymmetric function, corrected spelling errors

  • #2
    Round-Half-Up ASM Version

    ASM version.

    Code:
    #COMPILE EXE
    #DIM ALL
    '---------------------------------------------------
    ' Round-Half-Up - Round EXT to LONG
    '---------------------------------------------------
    ' The tricky point is what "up" means for negative numbers. Does it mean increasing
    ' in size towards negative infinity? Or does it mean increasing towards positive
    ' infinity? If it means increasing towards negative infinity then the algorithm
    ' is 'symmetric' with respect to zero for positive and negative values. If it means
    ' increasing towards positive infinity then the algorithm is 'asymmetric' with
    ' respect to zero for positive and negative values.
    ' .NET Math.Round(x, System.MidpointRounding.AwayFromZero) is symmetric.
    ' Python round() is symmetric.
    ' MATHLAB round() is symmetric.
    ' Java round() is assymmetric.
    '
    ' I got the idea for this code from: http://ldesoras.free.fr/doc/articles/rounding_en.pdf
    ' Greg Lyon
    '--------------------------------------------------
    FUNCTION RoundHalfUp_A(BYREF e AS EXT) AS LONG
        ' Asymmetric implementation (-5.5 rounds to -5).
        #REGISTER NONE
    
        LOCAL OneHalf AS EXT
        LOCAL i AS LONG
    
        OneHalf = 0.5##
    
        ! mov eax, e
        ! finit
        ! fld TBYTE PTR [eax]
        ! fadd st(0), st(0)
        ! fld OneHalf
        ! fadd
        ! fistp i
        ! sar i, 1
    
        FUNCTION = i
    
    END FUNCTION
    '---------------------------------------------------
    FUNCTION RoundHalfUp_S(BYREF e AS EXT) AS LONG
        ' Symmetric implementation (-5.5 rounds to -6)
        #REGISTER NONE
    
        LOCAL OneHalf AS EXT
        LOCAL i AS LONG
    
        OneHalf  = 0.5##
    
        ! mov eax, e
        ! finit
        ! fld TBYTE PTR [eax]
        ! fadd st(0), st(0)
        ! fld OneHalf
    
        ! mov eax, e
        ! add eax, 9
        ! movzx edx, DWORD PTR [eax]
        ! bt edx, 7
        ! jnc positive
        ! fchs
    
      positive:
        ! fadd
        ! fistp i
        ! sar i, 1
    
        FUNCTION = i
    
    END FUNCTION
    '----------------------------------------------------
    FUNCTION PBMAIN() AS LONG
    
        LOCAL x AS EXT
    
        STDOUT "Symmetric"
        FOR x = 9.5## TO -9.5## STEP -0.5##
            STDOUT FORMAT$(x, "0.0") & " = " & FORMAT$(RoundHalfUp_S(x), "0")
        NEXT x
        
        STDOUT
        
        STDOUT "Asymmetric"
        FOR x = 9.5## TO -9.5## STEP -0.5##
            STDOUT FORMAT$(x, "0.0") & " = " & FORMAT$(RoundHalfUp_A(x), "0")
        NEXT x
    
        STDOUT $CRLF & "Press any key to exit ... ";
        WAITKEY$
        STDOUT
    
    END FUNCTION
    '---------------------------------------------------
    Last edited by Greg Lyon; 22 Jun 2008, 10:13 PM. Reason: Corrected spelling errors, added credit

    Comment

    Working...
    X