1. round.e
- Posted by Ad Rienks <Ad_Rienks at COMPUSERVE.COM> Aug 11, 1998
- 450 views
- Last edited Aug 12, 1998
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
2. round.e
- Posted by Ad Rienks <Ad_Rienks at COMPUSERVE.COM> Aug 12, 1998
- 462 views
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