Opened 5 years ago

Closed 5 years ago

# critical bug in comparison between RealField and QQ

Reported by: Owned by: Paul Zimmermann critical sage-duplicate/invalid/wontfix coercion Jeroen Demeyer N/A

```sage: RealField(2)(1) >= 5/4
True
```

This is clearly wrong.

The reason is that `5/4` is first converted to a 2-bit floating-point number, which is `1` in mode to nearest, then the comparison is made.

### comment:1 Changed 5 years ago by Frédéric Chapoton

```sage: t
1.0
```
Version 1, edited 5 years ago by Frédéric Chapoton (previous) (next) (diff)

### comment:2 Changed 5 years ago by Paul Zimmermann

I did not ask `t >= RealField(2)(5/4)`, but `t >= 5/4`. Does the following convince you? Note that 6*t is exactly representable in 2-bit precision.

```sage: t = RealField(2)(1)
sage: t >= 7/6
True
sage: 6*t >= 7
False
```

### comment:3 Changed 5 years ago by Frédéric Chapoton

Well, comparison happens after coercion, and coercion can only lose precision. If you want comparison that makes sense, you should avoid using such a small precision.

### comment:4 Changed 5 years ago by Paul Zimmermann

where is it documented that comparison happens after coercion? Is the user warned about that? And why is the coercion done in the direction QQ to RealField? and not the converse, which would not lose any information?

### comment:5 Changed 5 years ago by Frédéric Chapoton

Coercion is supposed to be exact (mathematically), so it can not guess anything from an approximate real number. Going from R to QQ is a conversion.

```sage: R = RealField(2)
sage: R.coerce_map_from(QQ)

Generic map:
From: Rational Field
To:   Real Field with 2 bits of precision
sage: QQ.coerce_map_from(R)
```

### comment:7 Changed 5 years ago by Paul Zimmermann

the issue can be simplified to:

```sage: RealField(2)(7) == 10
True
```

### comment:8 Changed 5 years ago by Jeroen Demeyer

Component: basic arithmetic → coercion modified (diff)

The behaviour that you see is by design, so by definition it's a feature and not a bug.

Note also that what you see is consistent with subtraction, which is a good thing:

```sage: RealField(2)(1) - 5/4
0.00
```

I don't see a simple fix here... it would require substantial changes to the coercion model.

### comment:9 follow-up:  10 Changed 5 years ago by Paul Zimmermann

I don't see a simple fix here...

why no simply forbid comparison involving floating-point numbers, if it can result in mathematically wrong results? Then the user would have to do:

```sage: RealField(2)(7).exact_rational() == 10
False
```

### comment:10 in reply to:  9 Changed 5 years ago by Jeroen Demeyer

I don't see a simple fix here...

why no simply forbid comparison involving floating-point numbers

I don't think that's realistic. I'm pretty sure that a lot of stuff in Sage would break if we did that.

### comment:11 follow-up:  12 Changed 5 years ago by Travis Scrimshaw

I don't quite see it as a mathematically wrong result as it is correct up to the estimate bounds. If we did that, then I feel this would have to return `False` by the same argument:

```sage: bool(pi.n() == pi)
True
```

since `pi.n()` is an inexact floating point number. Also, we have this doctest in `exact_rational`:

```sage: RR(3^60).exact_rational() - 3^60
6125652559
```

### comment:12 in reply to:  11 Changed 5 years ago by Paul Zimmermann

I don't quite see it as a mathematically wrong result as it is correct up to the estimate bounds. If we did that, then I feel this would have to return `False` by the same argument:

```sage: bool(pi.n() == pi)
True
```

since `pi.n()` is an inexact floating point number.

it would indeed be correct to return False, since `pi.n()` is a well-defined rational number, namely `884279719003555/2^48`, and it is well known that `pi` is not rational, thus we cannot get equality.

Anyway, since I'm alone to consider this as a bug, I will simply use `exact_rational` whenever I want correct comparisons with floating-point numbers.

### comment:13 Changed 5 years ago by Jeroen Demeyer

Milestone: sage-8.1 → sage-duplicate/invalid/wontfix → wontfix new → closed
Note: See TracTickets for help on using tickets.