Why 'round' does not just round numbers ?

Hi all: I just read about definitions of Prelude [1], and noticing that. In 6.4.6 Coercions and Component Extraction, it discribes like this: "round x returns the nearest integer to x, the even integer if x is equidistant between two integers." I think this is unresonable. then try it in GHC 6.8.3. Prelude> round 3.5 4 Prelude> round 2.5 2 Is there any explanation about that ? [1] The Haskell 98 Report: Predefined Types and Classes http://haskell.org/onlinereport/basic.html Regards -------------- L.Guo 2008-10-27

On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ... I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then 0.45 - (round to one place) -> 0.5 - (round to integer) -> 1 but 0.45 - (round to integer) -> 0 This is avoided by the school definition.

Henning Thielemann wrote:
On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ...
Hmm, Henning, this is strange. The two of us went to the very same school, but I know for a fact that I learnt 2.5 to round to 3, not 2 as above. ;-)
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
but
0.45 - (round to integer) -> 0
That is of course true (and was the topic of heated discussion with my fourth grade math teacher), but does not explain 2.5 -> 2. Ciao, Janis. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

On Mon, 27 Oct 2008, Janis Voigtlaender wrote:
Henning Thielemann wrote:
On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ...
Hmm, Henning, this is strange. The two of us went to the very same school, but I know for a fact that I learnt 2.5 to round to 3, not 2 as above. ;-)
I meant the school before GCG! :-] So it seems to differ between schools and even teachers. (Much like the question whether zero should be counted as natural number or not.)
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
but
0.45 - (round to integer) -> 0
That is of course true (and was the topic of heated discussion with my fourth grade math teacher), but does not explain 2.5 -> 2.
Because doing otherwise would be odd rounding. ;-)

(Janis, sorry for e-mailiing just for you on the first time.)
On Mon, Oct 27, 2008 at 8:15 AM, Janis Voigtlaender
That is of course true (and was the topic of heated discussion with my fourth grade math teacher), but does not explain 2.5 -> 2.
If you round to odd instead of round to even, then 4.5 rounds to 5, which would may need rounding again and introduce double rounding errors. For a simple example, 2.45 -> 2.4 -> 2 2.45 -> 2.5 -> 3 The Wikipedia article that was linked in this thread talks about this problem as well. -- Felipe.

It is certainly what I learnt in school. But that was another school.
On Mon, Oct 27, 2008 at 12:15 PM, Janis Voigtlaender
Henning Thielemann wrote:
On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ...
Hmm, Henning, this is strange. The two of us went to the very same school, but I know for a fact that I learnt 2.5 to round to 3, not 2 as above. ;-)
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
but
0.45 - (round to integer) -> 0
That is of course true (and was the topic of heated discussion with my fourth grade math teacher), but does not explain 2.5 -> 2.
Ciao, Janis.
-- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Lennart Augustsson wrote:
It is certainly what I learnt in school. But that was another school.
Hmm, on reflection, taking Neil's explanation into account and the fact that this rounding mode was referred to as "banker's rounding", the point may be that it was not only another school, but another world (politically, pre-'89 ;-). -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

I can't remember the method being called anything.
It was just what we were being taught. With the obvious explanation
that .5 is right in the middle so always going one way would introduce
a bias. This was circa 1969.
On Mon, Oct 27, 2008 at 3:30 PM, Janis Voigtlaender
Lennart Augustsson wrote:
It is certainly what I learnt in school. But that was another school.
Hmm, on reflection, taking Neil's explanation into account and the fact that this rounding mode was referred to as "banker's rounding", the point may be that it was not only another school, but another world (politically, pre-'89 ;-).
-- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Lennart Augustsson wrote:
I can't remember the method being called anything. It was just what we were being taught. With the obvious explanation that .5 is right in the middle so always going one way would introduce a bias. This was circa 1969.
Well, I wasn't serious about the "political" explanation. And yes, the "avoiding bias" explanation makes sense, but not the "this way of rounding makes repeated rounding safe" explanation. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

On Mon, 27 Oct 2008, Janis Voigtlaender wrote:
Lennart Augustsson wrote:
I can't remember the method being called anything. It was just what we were being taught. With the obvious explanation that .5 is right in the middle so always going one way would introduce a bias. This was circa 1969.
Well, I wasn't serious about the "political" explanation.
And yes, the "avoiding bias" explanation makes sense, but not the "this way of rounding makes repeated rounding safe" explanation.
In measured data the .5-case should be very rare - a "null set"? However I assume that .5 happens more often in practice - because of prior rounding, which was shown to be bad practice in this thread. :-)

On 28 Oct 2008, at 11:11 am, Henning Thielemann wrote:
In measured data the .5-case should be very rare - a "null set"? However I assume that .5 happens more often in practice - because of prior rounding,
Think about money. When I was a child, farthings (1/4 of a penny) had just been dropped. (By now, our smallest coin is 10c, formerly a shilling, so in ~ 50 years the value of the smallest coin has eroded by a factor of 48.) Ha'pennies (1/2 of a penny) were still around. If you were adding up a sum of money, sums ending with 1/2 were actually quite common. When the ha'penny went the way of the farthing, one still had to round sums in pounds shillings and pence to sums in pounds and shillings, and sixpence (0.5 of a shilling) was not an unlikely amount. Now that the smallest coin is 10c, supermarkets still price things in multiples of 1c, so in order to give change, they have to round to a multuple of 10c. Sums that end with 5c are not at all unusual. Considering that the point of the thread is "what should we expect rounding to do", it may be of interest that a couple of years after the death of the 5c piece, supermarkets *still* display their rounding rule at the cash registers.

On Mon, Oct 27, 2008 at 1:37 PM, Lennart Augustsson
I can't remember the method being called anything. It was just what we were being taught. With the obvious explanation that .5 is right in the middle so always going one way would introduce a bias. This was circa 1969.
By the time I was in the Swedish school system that seems to have changed. I had never heard of this method of rounding before reading this thread :-) /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

Henning Thielemann wrote:
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
But repeated rounding *is* worse than rounding in one go, under any reasonable scheme: 3.46 -> 3.5 -> 4 vs. 3.46 -> 3 That was actually the debate with that teacher. Unbelievable as that still is to me today, she advocated the 3.46 -> 3.5 -> 4 route... And yes, Henning, you are right, we didn't yet share school in fourth grade when rounding was taught. Ciao, Janis. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

On Mon, 27 Oct 2008, Janis Voigtlaender wrote:
Henning Thielemann wrote:
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
But repeated rounding *is* worse than rounding in one go, under any reasonable scheme:
3.46 -> 3.5 -> 4
With the rounding-to-even route this would be 3.46 -> 3.4 -> 3 so rounding in passes is no worse than rounding in one go for this example.
vs.
3.46 -> 3
That was actually the debate with that teacher. Unbelievable as that still is to me today, she advocated the 3.46 -> 3.5 -> 4 route ...
I also know a didact which tells teachers that 1 has no prime decomposition. Oh, I see, she may have copied that from Wikipedia: http://en.wikipedia.org/wiki/Prime_factorisation

Am Montag, 27. Oktober 2008 11:46 schrieb Henning Thielemann:
On Mon, 27 Oct 2008, Janis Voigtlaender wrote:
Henning Thielemann wrote:
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
But repeated rounding *is* worse than rounding in one go, under any reasonable scheme:
3.46 -> 3.5 -> 4
With the rounding-to-even route this would be
3.46 -> 3.4 -> 3
Wait, that cannot be. 6 > 5, so 3.46 -> 3.5 even with banker's rounding.
so rounding in passes is no worse than rounding in one go for this example.
Rounding in passes is bad per se, because there are pretty large intervals where that gives a different result from a direct rounding.
vs.
3.46 -> 3
That was actually the debate with that teacher. Unbelievable as that still is to me today, she advocated the 3.46 -> 3.5 -> 4 route ...
I also know a didact which tells teachers that 1 has no prime decomposition. Oh, I see, she may have copied that from Wikipedia: http://en.wikipedia.org/wiki/Prime_factorisation
I can believe that makes sense to somebody who considers 0 an unnatural number, an empty product must be frightening for them.

On Mon, 27 Oct 2008, Daniel Fischer wrote:
Am Montag, 27. Oktober 2008 11:46 schrieb Henning Thielemann:
On Mon, 27 Oct 2008, Janis Voigtlaender wrote:
Henning Thielemann wrote:
I think one reason is that repeated rounding should not be worse than rounding in one go. Consider the rule 'use ceiling when the first removed digit is 5'. Then
0.45 - (round to one place) -> 0.5 - (round to integer) -> 1
But repeated rounding *is* worse than rounding in one go, under any reasonable scheme:
3.46 -> 3.5 -> 4
With the rounding-to-even route this would be
3.46 -> 3.4 -> 3
Wait, that cannot be. 6 > 5, so 3.46 -> 3.5 even with banker's rounding.
You are right, my oversight. So only the method helps, that the last digit is marked, whether it was generated by rounding up or down.

Daniel Fischer
Am Montag, 27. Oktober 2008 11:46 schrieb Henning Thielemann:
I also know a didact which tells teachers that 1 has no prime decomposition. Oh, I see, she may have copied that from Wikipedia: http://en.wikipedia.org/wiki/Prime_factorisation
I can believe that makes sense to somebody who considers 0 an unnatural number, an empty product must be frightening for them.
That is just mathematical trickery and dodgery, silently defining 1 as prime by including it (even infinitely many times!) in any prime factor, denying its existence there (by defining all units to be non-prime) and then calling the whole algebra paradox-free, hoping that noone notices. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

Am Montag, 27. Oktober 2008 12:35 schrieb Achim Schneider:
Daniel Fischer
wrote: Am Montag, 27. Oktober 2008 11:46 schrieb Henning Thielemann:
I also know a didact which tells teachers that 1 has no prime decomposition. Oh, I see, she may have copied that from Wikipedia: http://en.wikipedia.org/wiki/Prime_factorisation
I can believe that makes sense to somebody who considers 0 an unnatural number, an empty product must be frightening for them.
That is just mathematical trickery and dodgery, silently defining 1 as prime by including it (even infinitely many times!) in any prime factor,
Who does such horrible things? Repeat after me: 1 is NOT a prime. Never, under no circumstances.
denying its existence there (by defining all units to be non-prime) and then calling the whole algebra paradox-free, hoping that noone notices.

Daniel Fischer
Am Montag, 27. Oktober 2008 12:35 schrieb Achim Schneider:
Daniel Fischer
wrote: Am Montag, 27. Oktober 2008 11:46 schrieb Henning Thielemann:
I also know a didact which tells teachers that 1 has no prime decomposition. Oh, I see, she may have copied that from Wikipedia: http://en.wikipedia.org/wiki/Prime_factorisation
I can believe that makes sense to somebody who considers 0 an unnatural number, an empty product must be frightening for them.
That is just mathematical trickery and dodgery, silently defining 1 as prime by including it (even infinitely many times!) in any prime factor,
Who does such horrible things? Repeat after me: 1 is NOT a prime. Never, under no circumstances.
Then chase it out of your prime factor products. You'd be the first one to break a monoid and locate unsafeCalculate#. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

Am Montag, 27. Oktober 2008 13:34 schrieb Achim Schneider:
Who does such horrible things? Repeat after me: 1 is NOT a prime. Never, under no circumstances.
Then chase it out of your prime factor products. You'd be the first one to break a monoid and locate unsafeCalculate#.
Huh? I don't understand what you are trying to say here. In which way do you use the term "prime factor product"? If you're referring the value of the product, 1 is a perfectly legitimate value, that of the empty product. If you're referring the expression \prod_{i \in I}p_i, that doesn't contain 1. So out of where shall "it" (I think that refers to 1, does it?) be chased? And what has that to do with breaking monoids?

Daniel Fischer
Am Montag, 27. Oktober 2008 13:34 schrieb Achim Schneider:
Who does such horrible things? Repeat after me: 1 is NOT a prime. Never, under no circumstances.
Then chase it out of your prime factor products. You'd be the first one to break a monoid and locate unsafeCalculate#.
Huh? I don't understand what you are trying to say here. In which way do you use the term "prime factor product"? If you're referring the value of the product, 1 is a perfectly legitimate value, that of the empty product. If you're referring the expression \prod_{i \in I}p_i, that doesn't contain 1. So out of where shall "it" (I think that refers to 1, does it?) be chased? And what has that to do with breaking monoids?
I am referring to n = product [primeFactors n] and the fact that product = foldr (*) 1 or even, less haskellish, product xs = product 1:xs -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

G'day all.
Quoting Daniel Fischer
Who does such horrible things? Repeat after me: 1 is NOT a prime. Never, under no circumstances.
The definition of "prime" is well-understood standard terminology, but that doesn't escape the fact that it's arbitrary and human-defined. I'll bet you insist on the non-triviality axiom for fields, too. Cheers, Andrew Bromage

On 2008 Oct 27, at 6:00, Henning Thielemann wrote:
On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ...
Maybe you did; I learned "5/9 rounding". -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On 27 Oct 2008, at 11:00 pm, Henning Thielemann wrote:
On Mon, 27 Oct 2008, L.Guo wrote:
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
It's the definition we learnt in school ...
Check http://en.wikipedia.org/wiki/Rounding where you will find that the version of rounding "generally taught in elementary schools" is the one used in Pascal, namely round(X) = truncate(X + 0.5*sign(X))
(The Wikipedia entry says that Pascal uses a different algorithm, but ISO 7185 says "If x is positive or zero, round(x) shall be equivalent to trunc(x +0.5); otherwise, round(x) shall be equivalent to trunc(x-0.5).")
I think one reason is that repeated rounding should not be worse than rounding in one go.
That would be nice, but while round-to-even _reduces_ the harm from double rounding, it does not eliminate it.

Hi, That is a fairly standard implementation of rounding for financial institutions. Consider sum . map round Over the list [3.5,2.5] With rounding to the nearest even integer for 0.5's you get 6, otherwise if you always round up you get 7. If you bias towards rounding up you get a general upwards trend as numbers are rounded, which is bad, while the even condition ensures that statistically it averages to the same thing. For more details see: http://en.wikipedia.org/wiki/Rounding#Round-to-even_method Thanks Neil
-----Original Message----- From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of L.Guo Sent: 27 October 2008 9:49 am To: MailList Haskell-Cafe Subject: [Haskell-cafe] Why 'round' does not just round numbers ?
Hi all:
I just read about definitions of Prelude [1], and noticing that.
In 6.4.6 Coercions and Component Extraction, it discribes like this:
"round x returns the nearest integer to x, the even integer if x is equidistant between two integers."
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
[1] The Haskell 98 Report: Predefined Types and Classes http://haskell.org/onlinereport/basic.html
Regards -------------- L.Guo 2008-10-27
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ==============================================================================

G'day all.
Quoting "Mitchell, Neil"
With rounding to the nearest even integer for 0.5's you get 6, otherwise if you always round up you get 7. If you bias towards rounding up you get a general upwards trend as numbers are rounded, which is bad, while the even condition ensures that statistically it averages to the same thing.
There are also many numeric algorithms for which the rounding pattern in the least-significant digit is somewhat systematic. A simple example might be this: x <- round(x + 0.5) x <- round(x - 0.5) x <- round(x + 0.5) x <- round(x - 0.5) ... etc If you try this procedure starting with, say, x = 1.5, you can see a clear difference between round-up and round-to-even. With round-up, the rounding error is keeps increasing as the procedure continues. With round-to-even, the error is bounded. Cheers, Andrew Bromage

G'day all. Henning Thielemann suggested:
In measured data the .5-case should be very rare - a "null set"? However I assume that .5 happens more often in practice - because of prior rounding, which was shown to be bad practice in this thread.
The usual case in floating point is usually not 0.5, but some power of 0.5 just beyond the precision of the mantissa. And this is actually one of the most common cases in rounding, due to the fact that we use binary arithmetic. Cheers, Andrew Bromage

"L.Guo"
"round x returns the nearest integer to x, the even integer if x is equidistant between two integers."
Is there any explanation about that ?
Yes. math.h, rint() and IEEE. The Right Way(tm) to round is rounding every other n.5 into a different direction: round 1.5 = 2 round 2.5 = 2 round 3.5 = 4 round 4.5 = 4 and so on. It's statistically correct, that is, but also more computationally expensive. In practise, such things rarely matter, so you just don't need to care. If you have to care, pray that you know it. You're also bound to slam your nose into much, much messier issues then, too, wishing you'd learnt higher numerics in school, kind of like learning Haskell and wishing the first grade math curriculum was based on categories instead of sets. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

Thank you all for instructions. I am not the same education route with you, so i just heard round-to-even for the very first time. Now I understand why it exists in theory. And then, in haskell, is that means, I have to use 'floor . (.5+)' instead of 'round' to get the common round function ? Or else, is there any other alter-round-function in haskell to do this ? ------------------ L.Guo 2008-10-27

Henning Thielemann
On Mon, 27 Oct 2008, L.Guo wrote:
And then, in haskell, is that means, I have to use 'floor . (.5+)' instead of 'round' to get the common round function ?
That's certainly the best to do.
Hmmm... I'm wondering whether there's a standard C way to set the rounding direction. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

"Felipe Lessa"
On Mon, Oct 27, 2008 at 10:20 AM, Achim Schneider
wrote: Hmmm... I'm wondering whether there's a standard C way to set the rounding direction.
nearbyint() and rint() may be used, and the rounding mode can be set by fesetround(). IIRC, this is C99.
Yes, they are, thanks. Because of stuff like this, I sometimes wish Haskell supported not only morphisms of the type Hask a -> Hask b but (Hask h, RoundDownwards h) => h a -> h b {-# LANGUAGE CategoryClasses #-} ? -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

There's also the ieee-utils package, which provides an IEEE monad with `setRound`: http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/html/Numeri...

George Pollard wrote:
There's also the ieee-utils package, which provides an IEEE monad with `setRound`:
http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/html/Numeri...
Hmm, this does not work well with the threaded RTS:
import Numeric.IEEE.Monad import Numeric.IEEE.RoundMode (RoundMode (..)) import Control.Monad import Control.Concurrent
main = withIeeeDo $ do replicateM_ 2 $ forkIO $ forever $ putChar '.' forkIO $ do runIEEE $ do withRoundMode Downward $ forever $ do IEEE . putStr . (++ "\n") . show =<< getRound threadDelay 1000000
When run with +RTS -N2 -RTS, the output randomly alternates between Downward and ToNearest - for me at least. The problem is that the setRound call will only affect one worker thread, while the RTS will sometimes migrate RTS threads from one worker to another. runIEEE really has to be executed in a bound thread (see forkOS documentation). Using `par` will also cause trouble - in fact even more. I think that conceptually, the cleanest approach is to provide separate data types for Double and Float in each of the rounding modes. This is quite expensive: basically, it means setting the rounding mode on each operation, and we would miss out on the code generator support for floating point math. (A primop for setting the rounding mode could help here, to some extent.) Maybe tracking the rounding mode per RTS thread would be a useful compromise between performance and usability for computations with mostly uniform rounding mode - this is what the Numeric.IEEE.Monad module seems to be aiming at. `par` would still be unusable with that approach though. Bertram

On Oct 30, 2008, at 5:21 PM, Bertram Felgenhauer wrote:
George Pollard wrote:
There's also the ieee-utils package, which provides an IEEE monad with `setRound`:
http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/ html/Numeric-IEEE-RoundMode.html
When run with +RTS -N2 -RTS, the output randomly alternates between Downward and ToNearest - for me at least.
The problem is that the setRound call will only affect one worker thread, while the RTS will sometimes migrate RTS threads from one worker to another.
runIEEE really has to be executed in a bound thread (see forkOS documentation). Using `par` will also cause trouble - in fact even more.
That's a really nice catch! Dons has pointed out to me both the very handy forkOnIO which ensures the forked thread remains bound to a single CPU, and also the -qm flag to the RTS, which prevents thread migration between capabilities. Running the example program with +RTS -N2 -qm restores the behavior to what's intended. I'll try to get around to changing the documentation to reflect this. Also, it's worth noting that the IEEE round mode has no effect on rounding done with the `round` function, as that's explicitly coded to provide the behavior seen in the report. Regards, Sterl.

But you shouldn't use the "common round function", you should use the
Haskell round function.
That's the one that is mathematically better and has hardware support.
On Mon, Oct 27, 2008 at 2:05 PM, L.Guo
Thank you all for instructions.
I am not the same education route with you, so i just heard round-to-even for the very first time.
Now I understand why it exists in theory.
And then, in haskell, is that means, I have to use 'floor . (.5+)' instead of 'round' to get the common round function ?
Or else, is there any other alter-round-function in haskell to do this ?
------------------ L.Guo 2008-10-27
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Mon, Oct 27, 2008 at 9:48 AM, L.Guo
Hi all:
I just read about definitions of Prelude [1], and noticing that.
In 6.4.6 Coercions and Component Extraction, it discribes like this:
"round x returns the nearest integer to x, the even integer if x is equidistant between two integers."
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
[1] The Haskell 98 Report: Predefined Types and Classes http://haskell.org/onlinereport/basic.html
This behaviour is not what I expect after reading the description at http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:round . Given that this behaviour has caused a bit of confusion I think a change to the documention might be in order. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

[1] The Haskell 98 Report: Predefined Types and Classes http://haskell.org/onlinereport/basic.html
This behaviour is not what I expect after reading the description at http://haskell.org/ghc/docs/latest/html/libraries/base/ Prelude.html#v:round . Given that this behaviour has caused a bit of confusion I think a change to the documention might be in order.
Given that the documentation says "round x returns the nearest integer to x", I think pretty much any behavior can be expected -- there's no single integer nearest to 2.5. The documentation certainly needs updated though. Bob

This behaviour is not what I expect after reading the description at http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:round . Given that this behaviour has caused a bit of confusion I think a change to the documention might be in order.
The authority here is the report which says "round x returns the nearest integer to x, the even integer if x is equidistant between two integers." However I agree the haddock ought to mirror the report. Jules

It's well known from numerical analysis that you can achieve the best general behavior by rounding to even in "half" the cases, and rounding to odd in "half" the cases. It's usually deterministic by looking at the digit to the right of the round point. Regards, John A. De Goes N-BRAIN, Inc. http://www.n-brain.net [n minds are better than n-1] On Oct 27, 2008, at 10:59 AM, Jules Bean wrote:
This behaviour is not what I expect after reading the description at http://haskell.org/ghc/docs/latest/html/libraries/base/ Prelude.html#v:round . Given that this behaviour has caused a bit of confusion I think a change to the documention might be in order.
The authority here is the report which says
"round x returns the nearest integer to x, the even integer if x is equidistant between two integers."
However I agree the haddock ought to mirror the report.
Jules _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

L.Guo wrote:
Hi all:
I just read about definitions of Prelude [1], and noticing that.
In 6.4.6 Coercions and Component Extraction, it discribes like this:
"round x returns the nearest integer to x, the even integer if x is equidistant between two integers."
I think this is unresonable. then try it in GHC 6.8.3.
Prelude> round 3.5 4 Prelude> round 2.5 2
Is there any explanation about that ?
This is the same exact behavior found in the FPU of most processors, except that you usually don't notice because the rounding occurs between very small values. The reason for doing it this way is that e.g. 2.5 is exactly between 2 and 3, and rounding *up* every time would cause an uneven bias toward 3. To counteract that effect, rounding to the nearest even integer is used, which causes the half of the x.5 values to round up, and the other half to round down. Pete

Peter Gavin
The reason for doing it this way is that e.g. 2.5 is exactly between 2 and 3, and rounding *up* every time would cause an uneven bias toward 3. To counteract that effect, rounding to the nearest even integer is used, which causes the half of the x.5 values to round up, and the other half to round down.
Everyone keeps providing this rationale, but of course if you want "half the values to round up and the other half down" it does just as well to round positive values up and negative values down. I think given that the Haskell 98 Report is pretty explicit about the behavior of round, we're stuck with it, but I don't like it. It's yet another tiny impediment to Haskell newbies, as demonstrated by the original post. (I'm not at all opposed to having a round-to-even function; it should just be called roundHalfEven to make it clear what it does. If it were up to me, I would probably elide the name "round" altogether in favor of roundHalfEven.) I have written floating point code that depends on consistent rounding in the past. Being able to depend on round (1 + x) = 1 + round x is sometimes useful, but not possible for round-to-even. Also note that for a common case, rounding numbers in the range -x..x, there's still a strange slight bias toward the center, since round-to-even rounds both 0.5 and -0.5 to 0. BTW, in case anyone is unclear, IEEE 854 supports a large variety of required and optional rounding modes; it takes no strong position on a "correct" rounding strategy. In particular, round-up ("round-half-up") and round-to-even ("round-half-even") are both required. However, there is an IEEE 854 subset, ANSI X3.274, that does make rounding modes other than round-up optional, presumably in conformance with common PL practice. This might make an implementation of the Report's round function on some FPU I've never heard of slightly more expensive. Bart Massey bart <at> cs.pdx.edu

On 2008-10-27, Bart Massey
Peter Gavin
writes: The reason for doing it this way is that e.g. 2.5 is exactly between 2 and 3, and rounding *up* every time would cause an uneven bias toward 3. To counteract that effect, rounding to the nearest even integer is used, which causes the half of the x.5 values to round up, and the other half to round down.
Everyone keeps providing this rationale, but of course if you want "half the values to round up and the other half down" it does just as well to round positive values up and negative values down.
Except, of course, that it is quite common to work with just positive numbers. Working just with numbers near (even + 0.5) or (odd + 0.5) is extremely rare.
I have written floating point code that depends on consistent rounding in the past. Being able to depend on round (1 + x) = 1 + round x is sometimes useful, but not possible for round-to-even.
Also not for round-up -- consider floating point values where the precision changes and it rounds differently than you, or the point where adjacent floating point values are now 2 apart. You basically can't depend on any nice behaviour once floating point enters the room. -- Aaron Denney -><-

You're assuming newbies from a bad educational system that hasn't
taught them how to round properly. :)
-- Lennart
On Mon, Oct 27, 2008 at 10:15 PM, Bart Massey
I think given that the Haskell 98 Report is pretty explicit about the behavior of round, we're stuck with it, but I don't like it. It's yet another tiny impediment to Haskell newbies, as demonstrated by the original post. (I'm not at all opposed to having a round-to-even function; it should just be called roundHalfEven to make it clear what it does. If it were up to me, I would probably elide the name "round" altogether in favor of roundHalfEven.)

Lennart Augustsson
On Mon, Oct 27 2008, Bart Massey
wrote: I think given that the Haskell 98 Report is pretty explicit about the behavior of round, we're stuck with it, but I don't like it. It's yet another tiny impediment to Haskell newbies, as demonstrated by the original post.
You're assuming newbies from a bad educational system that hasn't taught them how to round properly. :)
Naw. :-) I'm just saying that the name "round" is unfortunate, since there's no single universally accepted mathematical definition for it. For this reason many programming languages either don't provide it or provide a different version. The names "roundHalfUp" and "roundHalfEven" are much better: they each correspond to a well-known mathematical function that is codified in an IEEE standards document. If it were up to me, I'd deprecate round in Haskell' and make the documentation point to these other rounding functions. Our solution in Nickle (http://nickle.org), BTW, was to provide floating point with user-settable mantissa precision and a default precision of 256 bits. For all practical purposes we know of, this makes worrying about the edge cases for rounding pointless. Kahan has a nice paper on this that I can't find right now. Of course, this solution also makes FP computation creepingly slow, and exposes users to occasional bugs in our FP math library... :-) Bart Massey bart <at> cs.pdx.edu

On Tue, Oct 28, 2008 at 04:07:12PM +0000, Bart Massey wrote:
I'm just saying that the name "round" is unfortunate, since there's no single universally accepted mathematical definition for it. For this reason many programming languages either don't provide it or provide a different version. The names "roundHalfUp" and "roundHalfEven" are much better: they each correspond to a well-known mathematical function that is codified in an IEEE standards document.
If it were up to me, I'd deprecate round in Haskell' and make the documentation point to these other rounding functions.
Our solution in Nickle (http://nickle.org), BTW, was to provide floating point with user-settable mantissa precision and a default precision of 256 bits. For all practical purposes we know of, this makes worrying about the edge cases for rounding pointless. Kahan has a nice paper on this that I can't find right now.
Isn't it quite common to have numbers like 0.5 as input? (as an example of a number that's exactly representable in any binary floating point format, but whose rounded value depends on rounding convention. I don't feel strongly on the question, but was somewhat surprised to find that round is present, for the reasons you mention. floor (x+0.5) is not a bad way to round... no one will mistakenly thing that it'll do something smart with half-integers. David

I agree that the name is not the most descriptive one, and perhaps we
should have the more descriptive ones.
But when I hear "round", I assume it's the kind of rounding Haskell
does. And I assumed this before Haskell came about.
On Tue, Oct 28, 2008 at 6:07 PM, Bart Massey
Lennart Augustsson
writes: On Mon, Oct 27 2008, Bart Massey
wrote: I think given that the Haskell 98 Report is pretty explicit about the behavior of round, we're stuck with it, but I don't like it. It's yet another tiny impediment to Haskell newbies, as demonstrated by the original post.
You're assuming newbies from a bad educational system that hasn't taught them how to round properly. :)
Naw. :-)
I'm just saying that the name "round" is unfortunate, since there's no single universally accepted mathematical definition for it. For this reason many programming languages either don't provide it or provide a different version. The names "roundHalfUp" and "roundHalfEven" are much better: they each correspond to a well-known mathematical function that is codified in an IEEE standards document.
If it were up to me, I'd deprecate round in Haskell' and make the documentation point to these other rounding functions.
Our solution in Nickle (http://nickle.org), BTW, was to provide floating point with user-settable mantissa precision and a default precision of 256 bits. For all practical purposes we know of, this makes worrying about the edge cases for rounding pointless. Kahan has a nice paper on this that I can't find right now.
Of course, this solution also makes FP computation creepingly slow, and exposes users to occasional bugs in our FP math library... :-)
Bart Massey bart <at> cs.pdx.edu
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Mon, Oct 27, 2008 at 6:15 PM, Bart Massey
BTW, in case anyone is unclear, IEEE 854 supports a large variety of required and optional rounding modes; it takes no strong position on a "correct" rounding strategy. In particular, round-up ("round-half-up") and round-to-even ("round-half-even") are both required. However, there is an IEEE 854 subset, ANSI X3.274, that does make rounding modes other than round-up optional, presumably in conformance with common PL practice. This might make an implementation of the Report's round function on some FPU I've never heard of slightly more expensive.
I would like to see something on the lines of data RoundMode = RoundUp | RoundDown | RoundToZero | RoundHalfEven class (Real a, Fractional a) => RealFrac a where ... round :: (Integral b) => a -> b roundBy :: (Integral b) => RoundMode -> a -> b roundModes :: a -> [RoundMode] -- non-strict on argument ... -- Felipe.

Let me offer another suggestion which I think can be fitted into Haskell quite well. For the applications of rounding choice that I'm aware of, you want to choose when you write the code, not when you run it. This was actually reflected in the design of a real machine: the DEC Alpha. Floating point instructions had variants for "whatever the PSW says" and for "this particular mode". It would have been nice (had DEC survived, if the Alpha were still alive) to be able to generate the first-direction instructions, as that's rather more efficient than switching rounding modes twice. Now the Haskell Way is to do things with types. So, newtype RoundedUp t = RoundedUp t newtype RoundedDown t = RoundedDown t newtype Truncated t = Truncated t instance Floating t => Num (RoundedUp t) where ... instance Floating t => Num (RoundedDown t) where ... instance Floating t => Num (Truncated t) where ... ... Then one could write let i = round (Truncated x + Truncated y) This is just a quick sketch. I'm sure it has problems. It does, however, deal with a fairly major problem in attempting to use hardware rounding modes in Haskell, and that is laziness. Putting the rounding mode in the type means that the information is right there at each operator without having to use monadic floating point.

Bart Massey wrote:
Peter Gavin
writes: The reason for doing it this way is that e.g. 2.5 is exactly between 2 and 3, and rounding *up* every time would cause an uneven bias toward 3. To counteract that effect, rounding to the nearest even integer is used, which causes the half of the x.5 values to round up, and the other half to round down.
Everyone keeps providing this rationale, but of course if you want "half the values to round up and the other half down" it does just as well to round positive values up and negative values down.
The rational is to have half of the expected distribution of 'related' invocations round up/down, regardless of the (adversarial) distribution of input value instances. The round to zero method provides this only when the distribution of instances are symmetric about zero. Barring random number generators, these are extremely uncommon distributions in practice. The round to even method provides this guarantee so long as the adversary can't choose between Even+0.5 vs Odd+0.5 values whenever it wants. In terms of non-adversarial distributions, this covers almost all of them, and in particular it is not biased to a particular mean for the distribution. Granted, not everyone is trying to get as close to the correct answer as possible. Sometimes it's more important to guarantee one-sided error than it is to minimize the error margins. But, IME, the most-correct answer is the general goal and when people have another goal in mind they're quite aware of it. -- Live well, ~wren
participants (23)
-
Aaron Denney
-
Achim Schneider
-
ajb@spamcop.net
-
Bart Massey
-
Bertram Felgenhauer
-
Brandon S. Allbery KF8NH
-
Daniel Fischer
-
David Roundy
-
Felipe Lessa
-
George Pollard
-
Henning Thielemann
-
Janis Voigtlaender
-
John A. De Goes
-
Jules Bean
-
L.Guo
-
Lennart Augustsson
-
Magnus Therning
-
Mitchell, Neil
-
Peter Gavin
-
Richard O'Keefe
-
Sterling Clover
-
Thomas Davie
-
wren ng thornton