On Mon, Jan 30, 2012 at 05:22:47PM +0900, Robert Klemme wrote:
> On Mon, Jan 30, 2012 at 6:56 AM, Chad Perrin <code / apotheon.net> wrote:
> > On Mon, Jan 30, 2012 at 10:03:04AM +0900, Gary Wright wrote:
> >>
> >> On Jan 29, 2012, at 2:26 AM, Jon Lambert wrote:
> >>
> >> > On Jan 27, 2012, at 3:26 PM, Gary Wright wrote:
> >> >> What 'value' do you expect for this expression:
> >> >>
> >> >> BigDecimal("1.0") / BigDecimal("3.0")
> >> >
> >> > Decimal math operations need use a default rounding context or require one to set a
> >> > rounding context before performing an operation.
> >> >
> >> > Do you round towards +infinity, -infinity,
> >> > towards 0, away from 0,
> >> > to nearest (and if equidistant, round down),
> >> > to nearest (and if equidistant, round up), or
> >> > to nearest (and if equidistant, round so that the last digit is even) aka. bankers rounding?
> >> >
> >> > Only then can you know what to expect.
> >>
> >> Agree 100%.  was just trying to illustrate that even if you have some
> >> wonderfully crafted big decimal literal syntax, you still need to address
> >> the context issues you just listed.
> >>
> >> 1.0D / 3.0D
> >>
> >> Might be easier to type but it is only part (perhaps a small part) of the puzzle.
> >
> > The point of offering something other than "all you get is floats and
> > libraries", of course, is that a simple set of such rules is a lot easier
> > to deal with than the floating point mess that is common now.
> 
> It seems many people use the "floating point mess" without major
> issues.  So it cannot be as bad as you make it sound.

"Many" is a relative term -- and "without major issues" is even more
relative.  When your definition of "without major issues" is "reinventing
the more-useful-comparison-method all over the world all the time" or
"lots of people unaware of edge-case unexpected values", I'm inclined to
disagree with your definition.


> >
> > t's a lot
> > easier to deal with "it truncates decimals past the Nth place" or any
> > other such simple rule than "Uh . . . it's probably going to do some
> > weird shit when you start doing math -- weird shit that requires you to
> > do binary math to predict the outcome. ou really just shouldn't use
> > it. se some verbose library syntax instead. ou like typing -- right?"
> 
> Any other _efficient_ floating point math would have to choose a
> limited representation.  You would get unexpected (for those who are
> not aware of numerics anyway) rounding issues anyway.  That would not
> be any better than the situation today, which has the advantage of a
> long established standard, so it is known to many.  Having an
> arbitrary precision math as default would make many applications
> slower than necessary which do not need that high precision math.

I don't know whether you have been reading the ongoing discussion
subthread involving me, or whether you have the old emails handy -- or
if, conversely, you have been ignoring this particular branch for a while
and deleting the messages unread until now.  An examination of the
discussion so far would reveal that I'm not even arguing that the Float
class should necessarily be replaced by any fixed point types as the
default type for decimal literals.  All I'm trying to do is point out the
flaws in keeping on with things exactly as they are.  Considering the
long tradition of using IEEE-standard floating point numbers behind a
literal representation like 1.1, I have actually been suggesting
something like adding at least one additional comparison method to the
Float class that can be used to perform comparisons up to a given fixed
precision, or do a ratio comparison, or something well-understood that
does not require the programmer to do binary math on the fly to be able
to accurately keep track of the results of Float#== comparisons all the
time or reinvent such comparison methods regularly.

From a usability perspective, leaving it up to the programmer, assuming
all programmers are aware of the difficulties involved in floating point
accuracy and expecting them to implement work-arounds is a really stinky
language design smell, in my opinion.


> 
> If you need to do precise math all the time there are other tools
> better suited for that.  You'll even find free / open source ones:
> http://en.wikipedia.org/wiki/Computer_algebra_system

Are you aware of how silly it is to tell people that wanting to do math
that doesn't surprise them in Ruby is just a non-starter, and they should
go use something else?


> 
> So at the moment I believe the current situation is the best
> compromise.  If you have suggestions for improvements which do not
> make things worse for many when avoiding the unexpected behavior I am
> curious to hear them.  For a new language the situation is totally
> different of course.

I think the "best compromise" would be, as I said more than once in this
subthread of discussion, to add a couple more comparison methods to the
Float class, providing easier mental modelling of how math works within a
program, where they're more likely to be noticed and will not require
everyone to create his or her own.  I really, *really* don't understand
the resistance to this simple idea.  Even if people sometimes have to
create yet another method for specialized purposes, one more comparison
method designed to abstract away the fuzzy edges of the binary arithmetic
behind the scenes for 98% of common cases would be a *huge* improvement,
where right now the situation is that Float#== can easily bite people in
somewhere in the neighborhood of 98% of common cases (reversing the
likelihood of a sane solution).

Just to be perfectly clear, I'm not suggesting we replace Float#==; I'm
suggesting with supplement it.  Semantically speaking, the way Float#==
works now (as I understand it) makes perfect sense (note that I have not
actually read the source for Ruby's Float#==, so I'm not sure it doesn't
make less sense than I think).  What doesn't make sense to me is that
being the only option in the class.

Can someone please explain to me in clear, direct terms why there is
opposition to the simple expedient of adding at least one additional
comparison method to Float to address the vast majority of casual use
cases without having to resort to reimplementing such comparison methods
over and over again or bringing in additional libraries with onerous
syntactic verbosity?

-- 
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]