# Why is 3e1 not equivalent to 30?

I thought that 3e1 is completely equivalent to 30. However, it is not:

sage: (1/30).n(digits=30)
0.0333333333333333333333333333333
sage: (1/3e1).n(digits=30)
0.0333333333333333328707404064062


Then I thought that 3e1 is always 53-bit real number or something like that. But I was wrong again:

sage: 1/3e1.n(digits=30)
0.0333333333333333333333333333333


Now I am just confused. Is this a bug? If not, how should I understand the second input above, and where can I find it documented? (Sage 5.0)

edit retag close merge delete

Sort by » oldest newest most voted

sage: type(1/30)
<type 'sage.rings.rational.Rational'>
sage: type(1/3e1)
<type 'sage.rings.real_mpfr.RealNumber'>


In your first thing, you're approximating a rational arbitrarily. In the second, you're approximating the (default 53 bit, I think you're right) "real" number closest to 1/30 with garbage after that many bits, as you suspect.

sage: a = 1/3e1
sage: a
0.0333333333333333
sage: a.prec()
53
sage: a.n(100)
0.033333333333333332870740406406


But in the last one you are doing the same as this, more or less:

sage: b = 3e1
sage: 3e1.n(digits=30)
30.0000000000000000000000000000
sage: type(3e1.n(digits=30))
<type 'sage.rings.real_mpfr.RealNumber'>
sage: (3e1.n(digits=30)).prec()
103
sage: 1/(3e1.n(digits=30))
0.0333333333333333333333333333333


which seems appropriate to me, since 30 can be represented exactly in binary, but 1/30 can't.

more

Thanks for the explanation. I was somehow expecting that default 53-bit precision of 3e1 would come into play only when explicit approximation or printout would be requested and not immediately. So, if I define a symbolic function with a single literal constant c=3e8, and I want to be able to choose the precision after calling and getting the output, I have to define this constant as c=300000000. Am I right?

( 2012-06-01 02:56:59 -0500 )edit

Not necessarily - I understand that keeping track of all those zeroes is tricky. Try using c = Integer(3e8) instead and see what its type is - this could do what you are looking for.

( 2012-06-01 05:52:20 -0500 )edit
( 2012-06-01 09:55:50 -0500 )edit

c = Integer(3e8) is good enough for me. Tnx.

( 2012-06-05 01:09:33 -0500 )edit