Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some things that are less than 5 aren't #6092

Closed
p6rt opened this issue Feb 23, 2017 · 11 comments
Closed

Some things that are less than 5 aren't #6092

p6rt opened this issue Feb 23, 2017 · 11 comments

Comments

@p6rt
Copy link

p6rt commented Feb 23, 2017

Migrated from rt.perl.org#130845 (status was 'resolved')

Searchable as RT130845$

@p6rt
Copy link
Author

p6rt commented Feb 23, 2017

From @briandfoy

Here's a curious change over in precision​:

  > 4.999999999999999 ~~ 0..^5
  True
  > 4.9999999999999999 ~~ 0..^5
  False

I figure this is an implementation detail that ties to storage, but
one of the selling points of Perl 6 is that this sort of thing isn't
a problem anymore.

  > $*PERL
  Perl 6 (6.c)
  > $*VM
  moar (2017.01)

@p6rt
Copy link
Author

p6rt commented Feb 23, 2017

From @timo

This is because the implementation of infix​:<cmp>(Rat​:D, Rat​:D) is kind
of bad​:

  multi sub infix​:<cmp>(Rational​:D \a, Rational​:D \b) is default {
  a.Num cmp b.Num
  }

We'll have to do a proper comparison of rats, rather than convert to Num
which can give wrong results like this.

On 23/02/17 04​:32, brian d foy (via RT) wrote​:

# New Ticket Created by "brian d foy"
# Please include the string​: [perl #​130845]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=130845 >

Here's a curious change over in precision​:

> 4\.999999999999999 ~~ 0\.\.^5
True
> 4\.9999999999999999 ~~ 0\.\.^5
False

I figure this is an implementation detail that ties to storage, but
one of the selling points of Perl 6 is that this sort of thing isn't
a problem anymore.

> $\*PERL
Perl 6 \(6\.c\)
> $\*VM
moar \(2017\.01\)

@p6rt
Copy link
Author

p6rt commented Feb 23, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Feb 23, 2017

From @timo

Actually, I was mistaken. The code i pointed at there already works for
this very case. observe​:

  131338 timotimo │ m​: say 4.999999999999999 cmp 5.0
  131338 +camelia │ rakudo-moar 1811b8​: OUTPUT​: «Less␤»

The real problem is this implementation of &infix​:<cmp>​:

  multi sub infix​:<cmp>(Real​:D \a, Real​:D \b) {
  (nqp​::istype(a, Rational) && nqp​::isfalse(a.denominator))
  || (nqp​::istype(b, Rational) && nqp​::isfalse(b.denominator))
  ?? a.Bridge cmp b.Bridge
  !! a === -Inf || b === Inf
  ?? Less
  !! a === Inf || b === -Inf
  ?? More
  !! a.Bridge cmp b.Bridge
  }

going via .Bridge will turn the Rat to 5e0 and the comparison goes wrong.

@p6rt
Copy link
Author

p6rt commented Feb 23, 2017

From @zoffixznet

On Wed, 22 Feb 2017 19​:32​:31 -0800, comdog wrote​:

Here's a curious change over in precision​:

> 4\.999999999999999 ~~ 0\.\.^5
True
> 4\.9999999999999999 ~~ 0\.\.^5
False

I figure this is an implementation detail that ties to storage, but
one of the selling points of Perl 6 is that this sort of thing isn't
a problem anymore.

> $\*PERL
Perl 6 \(6\.c\)
> $\*VM
moar \(2017\.01\)

There are two issues at play here​:

1) `cmp` with Rationals with Rational/Ints was busted and was using Num precision.
  This is now fixed[^1] and tested[^2], so `4.9999999999999999 ~~ 0..^5` does give True

2) My reading of the ticket suggests that you'd expect `4.99999999999999999999999 ~~ 0..^5` to give
  True as well, however, you'll notice that won't be the case, even after the fix in (1). The
  reason is such a number is too big to fit into a Rat. If you dump its components, you'll see
  the loss in precision​:

  <Zoffix> m​: dd 4.99999999999999999999999
  <camelia> rakudo-moar 9e8ecb​: OUTPUT​: «<499999999999999999999999/99999999999999991611392>␤»

  And it's that loss that would give the wrong answer when `cmp` it it or smartmatching with it.
  That behaviour is LTA and when we'd use proper uint64 for components, things would be even worse.
  There was a discussion[^3] on the topic today and one of the proposals was to create a RatStr
  allomorph in such cases which would basically behave as a non-infectious FatRat. I'll give that
  idea a go in the next few days (though I have a hunch 6.c tests would block this until 6.d).

  You don't have to wait for resolution of that issue, however, and can make a RatStr yourself, using
  angled brackets​:

  <Zoffix> m​: say <4.99999999999999999999999999999999999999999999> ~~ 0..^5
  <camelia> rakudo-moar 9e8ecb​: OUTPUT​: «True␤»

  It produces the right result.

[1] rakudo/rakudo@9e8ecb7
[2] Raku/roast@31d9af3
[3] https://irclog.perlgeek.de/perl6/2017-02-23#i_14152769

@p6rt
Copy link
Author

p6rt commented Feb 24, 2017

From @toolforger

Somewhat offtopic​:

toolforger​: p6​: say Inf cmp Inf
camelia​: rakudo-moar 320c2f​: OUTPUT​: «Same␤»

I.e. Inf compares equal to itself - is this intentional?

@p6rt
Copy link
Author

p6rt commented Feb 24, 2017

From @duncand

On 2017-02-23 10​:00 PM, Joachim Durchholz wrote​:

Somewhat offtopic​:

toolforger​: p6​: say Inf cmp Inf
camelia​: rakudo-moar 320c2f​: OUTPUT​: «Same␤»

I.e. Inf compares equal to itself - is this intentional?

Even if that isn't valid mathematically, for our purposes in a programming
language, Inf is a singleton.

I would have a serious problem with any programming language where it isn't the
case that asking "is $x the same thing as $x in every possible way" doesn't
result in TRUE for all possible values of $x.

That's one reason I seriously dislike SQL's NULL that don't equal themselves.

-- Darren Duncan

@p6rt
Copy link
Author

p6rt commented Feb 24, 2017

From @zoffixznet

On Thu, 23 Feb 2017 22​:01​:25 -0800, jo@​durchholz.org wrote​:

Somewhat offtopic​:

Feels like a bad place for offtopic discussions. You can ask questions in the same IRC channel you evaled your example.

toolforger​: p6​: say Inf cmp Inf
camelia​: rakudo-moar 320c2f​: OUTPUT​: «Same␤»

I.e. Inf compares equal to itself - is this intentional?

Yes, and we didn't invent this concept. This area is governed by IEEE 2008-753 standard, section 6.1 of which has this to say on infinities​:

  "The behavior of infinity in floating-point arithmetic is derived from the limiting cases of real arithmetic
  with operands of arbitrarily large magnitude, when such a limit exists. Infinities shall be interpreted in
  the affine sense, that is​: −∞ < {every finite number} < +∞"

It's not the only departure from mathematical result for the sake more practically useful results. Division by zero has well-defined behaviour in floating point math, and Rationals in Num view preserve it​:

  <Zoffix> m​: say <1/0> == Inf
  <camelia> rakudo-moar 320c2f​: OUTPUT​: «True␤»
  <Zoffix> m​: say <-1/0> == -Inf
  <camelia> rakudo-moar 320c2f​: OUTPUT​: «True␤»
  <Zoffix> m​: say <0/0>.Num === NaN
  <camelia> rakudo-moar 320c2f​: OUTPUT​: «True␤»

On Thu, 23 Feb 2017 22​:22​:22 -0800, darren@​DarrenDuncan.net wrote​:

I would have a serious problem with any programming language where it
isn't the
case that asking "is $x the same thing as $x in every possible way"
doesn't
result in TRUE for all possible values of $x.

Then I'd hate to tell you, but such a value exists in most languages​: a NaN​:

  <Zoffix> m​: say NaN == NaN
  <camelia> rakudo-moar 320c2f​: OUTPUT​: «False␤»

@p6rt
Copy link
Author

p6rt commented Feb 25, 2017

From @toolforger

On 24.02.2017 13​:03, Zoffix Znet via RT wrote​:

toolforger​: p6​: say Inf cmp Inf
camelia​: rakudo-moar 320c2f​: OUTPUT​: «Same␤»

I.e. Inf compares equal to itself - is this intentional?

Yes, and we didn't invent this concept.

Heh. That's what you'd expect before reading IEEE.
After understanding all details of the IEEE standard, it's where you
return (but only for infinities, not for NaNs) :-)

This area is governed by IEEE 2008-753 standard, section 6.1 of which
has this to say on infinities​:

"The behavior of infinity in floating\-point arithmetic is derived from the limiting cases of real arithmetic
with operands of arbitrarily large magnitude, when such a limit exists\. Infinities shall be interpreted in
the affine sense, that is&#8203;: −∞ \< \{every finite number\} \< \+∞"

While that paragraph does not define how Inf relates to Inf, I see
elsewhere that IEEE indeed defines Inf == Inf (and -Inf == -Inf).

I thought infinities were just a slightly tamed version of NaNs, but
that was a misconception on my side.

It's not the only departure from mathematical result for the sake more practically useful results.

I know :-)

Good thing that we have === so we can compare at the representational level.

@p6rt
Copy link
Author

p6rt commented Jul 13, 2017

From @zoffixznet

On Wed, 22 Feb 2017 19​:32​:31 -0800, comdog wrote​:

Here's a curious change over in precision​:

> 4\.999999999999999 ~~ 0\.\.^5
True
> 4\.9999999999999999 ~~ 0\.\.^5
False

I figure this is an implementation detail that ties to storage, but
one of the selling points of Perl 6 is that this sort of thing isn't
a problem anymore.

> $\*PERL
Perl 6 \(6\.c\)
> $\*VM
moar \(2017\.01\)

The remaining issues are now fixed, in so far as this now gives True, even when you didn't use the angle brackets​:

  say 4.99999999999999999999999999999999999999999999 ~~ 0..^5

However, what `4.99999999999999999999999999999999999999999999` exactly is will likely change slightly in the future, once we have properly working uint64 and our Rats use it as type for the denominator. One of the proposals is for such literals to end up as RatStr, so you'd basically have the same behaviour as is shown earlier on the ticket where using angle brackets to make a RatStr fixes the noise issue.

@p6rt p6rt closed this as completed Jul 13, 2017
@p6rt
Copy link
Author

p6rt commented Jul 13, 2017

@zoffixznet - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant