Opened 7 years ago

Last modified 5 years ago

#16769 new defect

Conversion RR -> QQ wrong for exact integers

Reported by: jdemeyer Owned by:
Priority: major Milestone: sage-6.4
Component: basic arithmetic Keywords:
Cc: Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by jdemeyer)

This real number can be exactly represented by the integer (and also rational) 2^54, so this is off by one:

sage: QQ(RR(2^54))
18014398509481983

The underlying function called by QQ() is simplest_rational:

sage: RR(2^54).simplest_rational()
18014398509481983

It must be said that this result agrees with the definition of "simplest rational", so perhaps the definition is wrong.

Change History (6)

comment:1 Changed 7 years ago by jdemeyer

  • Description modified (diff)

comment:2 Changed 7 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4

comment:3 follow-up: Changed 5 years ago by ajagekar.akshay

RR(2^54) is an exact integer although not an instance of Integer here. Conversion of RealNumber to Rational should yield its integral value. What if we check whether RR(2^54) or any RealNumber in general is an exact integer before returning it as Rational ?

Last edited 5 years ago by ajagekar.akshay (previous) (diff)

comment:4 in reply to: ↑ 3 ; follow-up: Changed 5 years ago by jdemeyer

Replying to ajagekar.akshay:

RR(2^54) is an exact integer although not an instance of Integer here. Conversion of RealNumber to Rational should yield its integral value. What if we check whether RR(2^54) or any RealNumber in general is an exact integer before returning it as Rational ?

That would solve this particular case but I'm doubting if that is general enough.

comment:5 in reply to: ↑ 4 Changed 5 years ago by ajagekar.akshay

Replying to jdemeyer:

Replying to ajagekar.akshay:

RR(2^54) is an exact integer although not an instance of Integer here. Conversion of RealNumber to Rational should yield its integral value. What if we check whether RR(2^54) or any RealNumber in general is an exact integer before returning it as Rational ?

That would solve this particular case but I'm doubting if that is general enough.

Can you give some examples where this will not work ?

comment:6 Changed 5 years ago by nbruin

Any element of RR of absolute value at least 252 can be expressed "exactly" as an integer:

sage: a=RR(2^52)
sage: s,m,e=a.sign_mantissa_exponent()
sage: s,m,e
(1, 4503599627370496, 0)
sage: s*m*2^e == a
True

simply because e will be non-negative for such numbers. Indeed, any float can be expressed exactly as a rational number: it's the number s*m*2^e that is used internally. The reason why we're not using that is basically this:

sage: a=RR(1/3)
sage: s,m,e=a.sign_mantissa_exponent()
sage: s*m*2^e
6004799503160661/18014398509481984

It's much nicer to get 1/3 back.

Indeed, the definition of "simplest rational" doesn't seem so useful anymore by the time you enter the range where the denominator is guaranteed to be 1. However, depending on getting an exact number back after going through RR is almost certainly a bug somewhere. So I don't think we should go out of our way to guarantee it. If you absolutely want access to the internal representation, there's sign_mantissa_exponent anyway.

The key is, the map ZZ->RR is not injective. So any section in the other direction is not going to compose to the identity on ZZ. It's basically an implementation detail that ZZ(2^54) maps to an element in RR that internally is represented by something that amounts to exactly that integer.

Note: See TracTickets for help on using tickets.