1. round.e

Hello fellow Euphorians,

As a result of previous discussions about rounding numbers, I have been
experimenting and I think I found a good solution to the problem.
Rounding by cutting off, division and-or multiplication did not work for
me.
The results were often not as exact as I needed.
You should know, I=B4m in the accounting business and very strict on thes=
e
sort of things. For others like me I donate this following routine.

-- round.e, version 1.1.2, August 12, 1998
-- Ad Rienks    (c) kwisoft 1998
-- donated to the Euphoria public domain
-- rounds an atom to x decimals, like a calculator
-- can be adapted to a precision of 8 decimals
-- above that, I'm not sure if precision is correct
-- bugs, comments, test results to:
-- Ad_Rienks at compuserve.com

include get.e
include graphics.e

with trace
-- trace(1)

function round2(atom a, integer p)
integer dot, negative, round
sequence format
object s, result
    if integer(a) then
        -- no need processing it further
        return a
    end if
    negative =3D 0
    if a < 0 then
        negative =3D 1
        a =3D -a
    end if
    -- take 2 extra decimals,
    -- to avoid unwanted rounding by sprintf()
    format =3D "%." & sprintf("%d", p + 2) & 'f'
    s =3D sprintf(format, a)
    dot =3D find('.', s)
    round =3D 0
    if find(s[dot + p + 1], "56789") then
        round =3D 1
    end if
    s =3D s[1..dot + p]
    result =3D value(s)
    result =3D result[2]
    if round then
        result =3D result + power(10, -p)
    end if
    if negative then
        result =3D - result
    end if
    return result
end function    -- round2

---------------------------------- Tests  ------------------------------
-- Test 0
? round2(100, 0)
if getc(0) then =

end if

-- Test 1
atom test
integer precision
sequence format

precision =3D 8
format =3D "%." & sprintf("%d", precision + 2) & 'f'
clear_screen()
puts(1, "\tTest 1\t('q' to quit)\n\n")
while 1 do
    test =3D rand(1e9) / 1e9 - .5
    printf(1, format & " rounded to %d decimals: " & format & '\n',
            {test, precision, round2(test, precision)})
    if wait_key() =3D 'q' then
        exit
    end if  =

end while

-- Test 2
sequence pos

precision =3D 2
format =3D "%." & sprintf("%d", precision + 2) & 'f'
clear_screen()
puts(1, "\tTest 2\t('q' to quit)\n\n")
for n =3D -.1 to .1 by .001 do
    printf(1, format & " rounded to %d decimals: " & format & '\n', =

            {n, precision, round2(n, precision)})
    pos =3D get_position()
    if pos[1] =3D 25 then
        if wait_key() =3D 'q' then
            exit
        end if
        scroll(22, 3, 24)
        position(3, 1)
    end if
end for

-- Test 3
atom a, b

precision =3D 2
clear_screen()
puts(1, "\tTest 3\t('q' to quit)\n\n")

while 1 do
    a =3D rand(100000) / 10000 - 5
    b =3D rand(1000) / 100 - 5
    printf(1, "%f x %f =3D %f (to %d decimals)\n",
        {a, b, round2(a * b, precision), precision})
    if wait_key() =3D 'q' then
        exit
    end if
end while
clear_screen()

Regards,
Ad Rienks

new topic     » topic index » view message » categorize

2. round.e

Hello,

I=B4m the first to respond to my own round2-function. U C, I tricked myse=
lf
again, a bit.
The key to this lies in the following lines

    -- take 2 extra decimals,
    -- to avoid unwanted rounding by sprintf()
    format =3D "%." & sprintf("%d", p + 2) & 'f'

Now, if you will round 0.49495 to 2 decimals, you would like to have 0.49=

as a result,
but you get 0.50. Sprintf does that. However, if you need a greater
precision, you can acquire that by taking more extra decimals. Thought I
should report this to you.

Regards,
Ad Rienks

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu