Back when I was first learning J, I wrote my own "definitive" rounding
routine
in which I allow an option to specify any of the three options I thought
relevant:
when the last digit is at the halfway point,
1) round up,
2) round down,
3) use "banker's rounding" - round up or down depending on the parity of the
preceding digit.

I still like this routine, not the least because of the way it allows
specification of
the rounding precision - as an amount, not as a number of digits.  This is
much
more flexible and, perhaps, more intuitive.  For instance, you might want to
round
dollars and cents to the nearest nickel:
  0.05 roundNums 3.92 3.93 3.925 3.875 3.825 NB. Banker's is default
3.9 3.95 3.9 3.9 3.8
  (0.05;'B') roundNums 3.92 3.93 3.925 3.875 3.825
3.9 3.95 3.9 3.9 3.8
  (0.05;'U') roundNums 3.92 3.93 3.925 3.875 3.825
3.9 3.95 3.95 3.9 3.85
  (0.05;'D') roundNums 3.92 3.93 3.925 3.875 3.825
3.9 3.95 3.9 3.85 3.8

roundNums=: 3 : 0
NB.* roundNums: round numbers y. to precision x., e.g.
NB. 0.1 roundNums 1.23 3.14159 2.718 -> 1.2 3.1 2.7.
NB. Optional 2nd left argument is single letter specifying
NB. type of rounding: Up, Down, or Banker's. Default
NB. banker's rounding (round halves up or down depending on
NB. parity of next (scaled) digit) tends to randomize bias.
  1 roundNums y.
:
  RT=. 'B' NB. Default to Banker's rounding
  TO=. x. NB. Precision to which to round.
  if. (2=#x.)*.1=L. x. do. 'TO RT'=. x. end.
  scaled=. y.%TO NB. For Banker's: round down if last digit even,
  if. 'B'=RT do. RN=. 0.5*(0~:2|<.scaled)+.0.5~:1|scaled NB. up if odd.
  elseif. 'D'=RT do. RN=. (0.5=1|scaled){0.5 _0.5 NB. Round halves down.
  elseif. 'U'=RT do. RN=. 0.5 NB. Round halves up.
  end.
  TO*<.scaled+RN
NB.EG 0.05 roundNums 1.41 2.72 3.14 NB. Round to nearest 5 cents.
)

The advantage of banker's rounding is that it avoids systematic bias.


On 3/19/07, Joey K Tuttle <[EMAIL PROTECTED]> wrote:

Oh, you mean like this -

    0j2 ": 295r1000 2995r10000
0.30 0.30

    0j20 ": 295r1000 2995r10000
0.29500000000000000000 0.29950000000000000000

I agree with your expectations - but seems that already works...

Pocket calculators are authoritative about math rulse? This is
any old 4 function chip, or some specific one?

- joey


At 12:35 AM +0800 3/20/07, bill lam wrote:
>I agree that technically 0.295 could be rounded to 0.29, but I think
>that most people (programmer or non-programmer) will expect that
>rounding the quotient (295/1000) to 2 decimal places is 0.30
>
>I also double checked with a pocket calculator.
>
>Joey K Tuttle wrote:
>>It would be a shame to slow down ": ... consider
>>
>>    0j20 ": 0.295 0.2995
>>0.29499999999999998446 0.29949999999999998845
>>
>>I suppose that 8!:x implements the "standard rule" that
>>rounding a number ending (but not really in this case) 5
>>depends on whether the prior digit is odd or even. Much
>>of this seems arbitrary at best.
>>
>>- joey
>>
>>
>>At 8:45 AM -0700 3/19/07, Roger Hui wrote:
>>>The difference is that the dyad ": depends on the
>>>C library routines whereas 8!:x do the programming
>>>themselves and take more care.  I'll look into it.
>>>It is likely that a fix will make ": slower.
>>>
>>>Thanks for the report.
>>>
>>>
>>>
>>>----- Original Message -----
>>>From: bill lam <[EMAIL PROTECTED]>
>>>Date: Sunday, March 18, 2007 11:14 pm
>>>Subject: [Jprogramming] dyad ": rounding error
>>>
>>>>  On both J504 and J601, dyad ": sometimes does not round properly
>>>>  on some
>>>>  numbers, eg.
>>>>     0j2 ":  0.295
>>>>  0.29
>>>>     0j3 ":  0.2995
>>>>  0.299
>>>>
>>>>  incidentally 8!:x family of J601 does not have this problem,
>>>>     '0.2' (8!:0) 0.295
>>>>  +----+
>>>>  |0.30|
>>>>  +----+
>>>>     '0.2' (8!:1) 0.295
>>>>  +----+
>>>>  |0.30|
>>>>  +----+
>>>>     '0.2' (8!:2) 0.295
>>>>  0.30
>>>>     '0.3' (8!:2) 0.2995
>>>>  0.300
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm




--
Devon McCormick, CFA
^me^ at acm.
org is my
preferred e-mail
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to