Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #106925 > unrolled thread

Serious error in int() function?

Started bymartin.spichty@gmail.com
First post2016-04-13 00:41 -0700
Last post2016-04-15 09:41 +0100
Articles 18 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  Serious error in int() function? martin.spichty@gmail.com - 2016-04-13 00:41 -0700
    Re: Serious error in int() function? Marko Rauhamaa <marko@pacujo.net> - 2016-04-13 10:55 +0300
    Re: Serious error in int() function? Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2016-04-13 10:00 +0200
    Re: Serious error in int() function? Peter Otten <__peter__@web.de> - 2016-04-13 10:03 +0200
    Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-13 09:04 +0100
    Re: Serious error in int() function? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-04-13 23:51 +1200
    Re: Serious error in int() function? "ast" <nomail@com.invalid> - 2016-04-14 08:52 +0200
      Re: Serious error in int() function? Christian Gollwitzer <auriocus@gmx.de> - 2016-04-14 09:25 +0200
      Accuracy of math.sqrt(), was Re: Serious error in int() function? Peter Otten <__peter__@web.de> - 2016-04-14 09:46 +0200
      Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-14 08:59 +0100
        Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-14 09:13 +0100
          Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-14 13:07 +0100
            Re: Serious error in int() function? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2016-04-14 20:36 -0400
              Re: Serious error in int() function? Christian Gollwitzer <auriocus@gmx.de> - 2016-04-15 04:38 +0200
                Re: Serious error in int() function? John Pote <johnhpote@o2.co.uk> - 2016-04-15 12:05 +0100
                  Re: Serious error in int() function? alister <alister.ware@ntlworld.com> - 2016-04-15 11:50 +0000
              Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-15 09:41 +0100
                Re: Serious error in int() function? blindanagram@nowhere.net - 2016-04-15 09:41 +0100

#106925 — Serious error in int() function?

Frommartin.spichty@gmail.com
Date2016-04-13 00:41 -0700
SubjectSerious error in int() function?
Message-ID<52f7516c-8601-4252-ab16-bc30c59c8306@googlegroups.com>
Hi,

there may be a serious error in python's int() function:

print int(float(2.8/0.1))

yields

27

instead of 28!!

I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.

Is that known?
Best,
Martin

[toc] | [next] | [standalone]


#106926

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-04-13 10:55 +0300
Message-ID<87mvoyt02v.fsf@elektro.pacujo.net>
In reply to#106925
martin.spichty@gmail.com:

> there may be a serious error in python's int() function:
>
> print int(float(2.8/0.1))
>
> yields
>
> 27
>
> instead of 28!!

It is not an error but a normal artifact of decimal-to-binary
conversion.


Marko

[toc] | [prev] | [next] | [standalone]


#106927

FromAlain Ketterlin <alain@universite-de-strasbourg.fr.invalid>
Date2016-04-13 10:00 +0200
Message-ID<87fuuqey4s.fsf@universite-de-strasbourg.fr.invalid>
In reply to#106925
martin.spichty@gmail.com writes:

> print int(float(2.8/0.1))
>
> yields
>
> 27
>
> instead of 28!!

That's how floating-point arithmetic works: look at the result of
2.8/0.1 to see why int() is correct.

> Is that known?

Yes, it is known, and correct since you use "float". See
http://floating-point-gui.de/ for a nice explanation. Use decimal
(https://docs.python.org/2/library/decimal.html) if you need exact
representations.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#106928

FromPeter Otten <__peter__@web.de>
Date2016-04-13 10:03 +0200
Message-ID<mailman.64.1460534591.15650.python-list@python.org>
In reply to#106925
martin.spichty@gmail.com wrote:

> Hi,
> 
> there may be a serious error in python's int() function:
> 
> print int(float(2.8/0.1))
> 
> yields
> 
> 27
> 
> instead of 28!!
> 
> I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.
> 
> Is that known?

Yes. C has the same error as has every other language that uses the floating 
point numbers supported by your computer's hardware. See

https://docs.python.org/2/tutorial/floatingpoint.html

[toc] | [prev] | [next] | [standalone]


#106929

Fromblindanagram@nowhere.net
Date2016-04-13 09:04 +0100
Message-ID<570DFD89.7010808@nowhere.net>
In reply to#106925
On 13/04/2016 08:41, martin.spichty@gmail.com wrote:
> Hi,
> 
> there may be a serious error in python's int() function:
> 
> print int(float(2.8/0.1))
> 
> yields
> 
> 27
> 
> instead of 28!!
> 
> I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.
> 
> Is that known?

This arises because finite floating point arithmetic is not exact so
2.8/0.1 results in 27.999999999999996.  And, since the int() function
truncates towards zero, this results in a value of 27.

If you want the nearest integer you should use round(x) rather than int(x).

[toc] | [prev] | [next] | [standalone]


#106935

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2016-04-13 23:51 +1200
Message-ID<dn6q60FmpvfU1@mid.individual.net>
In reply to#106925
martin.spichty@gmail.com wrote:
> print int(float(2.8/0.1))
> 
> yields
> 
> 27
> 
> instead of 28!!

This is a consequence of the fact that the machine does
floating point arithmetic in binary, not decimal.

0.1 is not exactly representable as a binary floating
point number, and the result of the division comes out
very slightly less that 28:

 >>> 2.8/0.1
27.999999999999996

This is not unique to Python; you'll get the same
result from anything that uses the machine's native
floating point numbers.

When using floating point, you always need to be
prepared for slight inaccuracies. Usually you don't
notice them, because the results are rounded to some
reasonable number of decimal places before display.
But sometimes they show up, such as when using
int(), which truncates instead of rounding.

The best way to handle things like this depends on
the circumstances. If you tell us what you're trying
to achieve, we may be able to offer advice.

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#106974

From"ast" <nomail@com.invalid>
Date2016-04-14 08:52 +0200
Message-ID<570f3e30$0$665$426a74cc@news.free.fr>
In reply to#106925
<martin.spichty@gmail.com> a écrit dans le message de 
news:52f7516c-8601-4252-ab16-bc30c59c8306@googlegroups.com...
> Hi,
>
> there may be a serious error in python's int() function:
>
> print int(float(2.8/0.1))
>
> yields
>
> 27
>
> instead of 28!!
>
> I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.
>
> Is that known?
> Best,
> Martin


I have a similar question, so I post my message here.
Hope this will not annoy the OP


Is it sure that the square root of a square number is always
an integer ?

I would not like to get a result as 345.99999999

from math import sqrt

>>>sqrt(16)
4.0
>>> sqrt(16).is_integer()
True

>>> for n in range(1000000):
...         if not sqrt(n**2).is_integer():
...             print(sqrt(n**2))

it seems to work ... but does it work for all integers ?

 

[toc] | [prev] | [next] | [standalone]


#106977

FromChristian Gollwitzer <auriocus@gmx.de>
Date2016-04-14 09:25 +0200
Message-ID<nengf9$g4t$1@dont-email.me>
In reply to#106974
Am 14.04.16 um 08:52 schrieb ast:
> Is it sure that the square root of a square number is always
> an integer ?

Mathematically, yes.

> I would not like to get a result as 345.99999999
>
> from math import sqrt
>
>>>> sqrt(16)
> 4.0
>>>> sqrt(16).is_integer()
> True
>
>>>> for n in range(1000000):
> ...         if not sqrt(n**2).is_integer():
> ...             print(sqrt(n**2))
>
> it seems to work ... but does it work for all integers ?


No. sqrt uses floating point arithmetic, which in Python uses IEEE 64 
bit floating point math (the C double type). This has 53 bits of 
mantissa, that means if your square is larger than 2^53, and does not 
contain only powers of two in addition, the square root will be off.

But the good news is that there are integer square root algorithms. 
Since Python supports arbitrary large integers, you can use one of those.

An isqrt implementation wa discussed here recently:

https://groups.google.com/forum/#!topic/comp.lang.python/70D5yVj7mIY

	Christian

[toc] | [prev] | [next] | [standalone]


#106978 — Accuracy of math.sqrt(), was Re: Serious error in int() function?

FromPeter Otten <__peter__@web.de>
Date2016-04-14 09:46 +0200
SubjectAccuracy of math.sqrt(), was Re: Serious error in int() function?
Message-ID<mailman.95.1460620029.15650.python-list@python.org>
In reply to#106974
ast wrote:

> 
> <martin.spichty@gmail.com> a écrit dans le message de
> news:52f7516c-8601-4252-ab16-bc30c59c8306@googlegroups.com...
>> Hi,
>>
>> there may be a serious error in python's int() function:
>>
>> print int(float(2.8/0.1))
>>
>> yields
>>
>> 27
>>
>> instead of 28!!
>>
>> I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.
>>
>> Is that known?
>> Best,
>> Martin
> 
> 
> I have a similar question, so I post my message here.
> Hope this will not annoy the OP

Well, you "annoy" me ;)

Would you please always take the time to come up with a subject line that 
matches your question. You should also start a new thread.

> Is it sure that the square root of a square number is always
> an integer ?
> 
> I would not like to get a result as 345.99999999
> 
> from math import sqrt
> 
>>>>sqrt(16)
> 4.0
>>>> sqrt(16).is_integer()
> True
> 
>>>> for n in range(1000000):
> ...         if not sqrt(n**2).is_integer():
> ...             print(sqrt(n**2))
> 
> it seems to work ... but does it work for all integers ?

Even if you get an integer it may not be the one you are expecting:

>>> sqrt((10**22)**2) == 10**22
True
>>> sqrt((10**23)**2) == 10**23
False
>>> sqrt((10**23)**2).is_integer()
True
>>> int(sqrt((10**23)**2))
99999999999999991611392

[toc] | [prev] | [next] | [standalone]


#106980

Fromblindanagram@nowhere.net
Date2016-04-14 08:59 +0100
Message-ID<Kr2dnVKiXPpT0JLKnZ2dnUU78TXNnZ2d@brightview.co.uk>
In reply to#106974
On 14/04/2016 07:52, ast wrote:
> 
> <martin.spichty@gmail.com> a écrit dans le message de
> news:52f7516c-8601-4252-ab16-bc30c59c8306@googlegroups.com...
>> Hi,
>>
>> there may be a serious error in python's int() function:
>>
>> print int(float(2.8/0.1))
>>
>> yields
>>
>> 27
>>
>> instead of 28!!
>>
>> I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.
>>
>> Is that known?
>> Best,
>> Martin
> 
> 
> I have a similar question, so I post my message here.
> Hope this will not annoy the OP
> 
> 
> Is it sure that the square root of a square number is always
> an integer ?
> 
> I would not like to get a result as 345.99999999
> 
> from math import sqrt
> 
>>>> sqrt(16)
> 4.0
>>>> sqrt(16).is_integer()
> True
> 
>>>> for n in range(1000000):
> ...         if not sqrt(n**2).is_integer():
> ...             print(sqrt(n**2))
> 
> it seems to work ... but does it work for all integers ?

Assuming that IEEE 754 floating point arithmetic is being used, the
sqrt() function will return an exact integer square root for square
integers provided that the square root is exactly representable.

This means that the result will be correct provided it has 53 or less
bits - just short of 16 decimal digits (i.e for square numbers with less
than 32 digits).

With an integer square root function (isqrt), this program:

for exp in count(20):
  v = 2 ** exp - 1
  if isqrt(v) != sqrt(v):
    print(exp, isqrt(v), sqrt(v))
    break

terminates with:

  54 18014398509481983 1.8014398509481982e+16

showing a first error for a 54 bit square root

[toc] | [prev] | [next] | [standalone]


#106981

Fromblindanagram@nowhere.net
Date2016-04-14 09:13 +0100
Message-ID<zNSdna8abKekzJLKnZ2dnUU78fHNnZ2d@brightview.co.uk>
In reply to#106980
On 14/04/2016 08:59, blindanagram@nowhere.net wrote:
> On 14/04/2016 07:52, ast wrote:

> This means that the result will be correct provided it has 53 or less
> bits - just short of 16 decimal digits (i.e for square numbers with less
> than 32 digits).
> 
> With an integer square root function (isqrt), this program:
> 
> for exp in count(20):
>   v = 2 ** exp - 1
>   if isqrt(v) != sqrt(v):
>     print(exp, isqrt(v), sqrt(v))
>     break
> 
> terminates with:
> 
>   54 18014398509481983 1.8014398509481982e+16
> 
> showing a first error for a 54 bit square root
> 
I should also have said that the square root of integer squares with
between 15 and 30 decimal digits will only be correct if the square
numbers themselves are exactly representable in 53 bits.  So we can
expect failures for squares with 16 or more digits.


[toc] | [prev] | [next] | [standalone]


#106995

Fromblindanagram@nowhere.net
Date2016-04-14 13:07 +0100
Message-ID<3MidnT9boJ97GpLKnZ2dnUU78LPNnZ2d@brightview.co.uk>
In reply to#106981
On 14/04/2016 09:13, blindanagram@nowhere.net wrote:
> On 14/04/2016 08:59, blindanagram@nowhere.net wrote:
>> On 14/04/2016 07:52, ast wrote:
> 
>> This means that the result will be correct provided it has 53 or less
>> bits - just short of 16 decimal digits (i.e for square numbers with less
>> than 32 digits).
>>
>> With an integer square root function (isqrt), this program:
>>
>> for exp in count(20):
>>   v = 2 ** exp - 1
>>   if isqrt(v) != sqrt(v):
>>     print(exp, isqrt(v), sqrt(v))
>>     break
>>
>> terminates with:
>>
>>   54 18014398509481983 1.8014398509481982e+16
>>
>> showing a first error for a 54 bit square root
>>
> I should also have said that the square root of integer squares with
> between 15 and 30 decimal digits will only be correct if the square
> numbers themselves are exactly representable in 53 bits.  So we can
> expect failures for squares with 16 or more digits.

However, if a number with 31 or less digits is known to be the square of
an integer, the IEEE754 sqrt function will (I believe) give the correct
result.

[toc] | [prev] | [next] | [standalone]


#107018

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2016-04-14 20:36 -0400
Message-ID<mailman.121.1460680575.15650.python-list@python.org>
In reply to#106995
On Thu, 14 Apr 2016 13:07:03 +0100, blindanagram@nowhere.net declaimed the
following:

>On 14/04/2016 09:13, blindanagram@nowhere.net wrote:
>> On 14/04/2016 08:59, blindanagram@nowhere.net wrote:
>>> On 14/04/2016 07:52, ast wrote:
>> 
>>> This means that the result will be correct provided it has 53 or less
>>> bits - just short of 16 decimal digits (i.e for square numbers with less
>>> than 32 digits).
>>>
>>> With an integer square root function (isqrt), this program:
>>>
>>> for exp in count(20):
>>>   v = 2 ** exp - 1
>>>   if isqrt(v) != sqrt(v):
>>>     print(exp, isqrt(v), sqrt(v))
>>>     break
>>>
>>> terminates with:
>>>
>>>   54 18014398509481983 1.8014398509481982e+16
>>>
>>> showing a first error for a 54 bit square root
>>>
>> I should also have said that the square root of integer squares with
>> between 15 and 30 decimal digits will only be correct if the square
>> numbers themselves are exactly representable in 53 bits.  So we can
>> expect failures for squares with 16 or more digits.
>
>However, if a number with 31 or less digits is known to be the square of
>an integer, the IEEE754 sqrt function will (I believe) give the correct
>result.

	How could it EXCEPT by having ~15 significant digits and an exponent --
since that is all the data that is provided by a double precision floating
point. That is, for example, 

>>> 1000000000000000.0 * 1000000000000000.0
1e+30
>>> import math
>>> math.sqrt(1e30)
1000000000000000.0
>>> 

only has ONE significant digit -- even though it has thirty 0s before the
decimal point.

>>> 100000000000000000.0 * 100000000000000000.0
1e+34
>>> math.sqrt(1e34)
1e+17
>>> 10000000000000000.0 * 10000000000000000.0
1e+32
>>> math.sqrt(1e32)
1e+16
>>> 

-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#107021

FromChristian Gollwitzer <auriocus@gmx.de>
Date2016-04-15 04:38 +0200
Message-ID<nepk0u$pag$1@dont-email.me>
In reply to#107018
Am 15.04.16 um 02:36 schrieb Dennis Lee Bieber:
>>> I should also have said that the square root of integer squares with
>>> between 15 and 30 decimal digits will only be correct if the square
>>> numbers themselves are exactly representable in 53 bits.  So we can
>>> expect failures for squares with 16 or more digits.
>>
>> However, if a number with 31 or less digits is known to be the square of
>> an integer, the IEEE754 sqrt function will (I believe) give the correct
>> result.
>
> 	How could it EXCEPT by having ~15 significant digits and an exponent --
> since that is all the data that is provided by a double precision floating
> point. That is, for example,
>
>>>> 1000000000000000.0 * 1000000000000000.0
> 1e+30
>>>> import math
>>>> math.sqrt(1e30)
> 1000000000000000.0
>>>>
>
> only has ONE significant digit -- even though it has thirty 0s before the
> decimal point.

No, you need to count the significant digits in binary. 1e30 is not an 
even number in binary floating point.

Apfelkiste:AsynCA chris$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
obase=2
10^30
11001001111100101100100111001101000001000110011101001110110111101010\
01000000000000000000000000000000
sqrt(10^30)
11100011010111111010100100110001101000000000000000

Still, the floating point arithmetic should round to the correct answer 
if both are converted to decimal.

	Christian

[toc] | [prev] | [next] | [standalone]


#107042

FromJohn Pote <johnhpote@o2.co.uk>
Date2016-04-15 12:05 +0100
Message-ID<mailman.14.1460718334.6324.python-list@python.org>
In reply to#107021

On 15/04/2016 03:38, Christian Gollwitzer wrote:
> Am 15.04.16 um 02:36 schrieb Dennis Lee Bieber:
>>>> I should also have said that the square root of integer squares with
>>>> between 15 and 30 decimal digits will only be correct if the square
>>>> numbers themselves are exactly representable in 53 bits.  So we can
>>>> expect failures for squares with 16 or more digits.
>>>
>>> However, if a number with 31 or less digits is known to be the 
>>> square of
>>> an integer, the IEEE754 sqrt function will (I believe) give the correct
>>> result.
>>
>>     How could it EXCEPT by having ~15 significant digits and an 
>> exponent --
>> since that is all the data that is provided by a double precision 
>> floating
>> point. That is, for example,
>>
>>>>> 1000000000000000.0 * 1000000000000000.0
>> 1e+30
>>>>> import math
>>>>> math.sqrt(1e30)
>> 1000000000000000.0
>>>>>
>>
>> only has ONE significant digit -- even though it has thirty 0s before 
>> the
>> decimal point.
>
As I was taught in school and university the number of significant 
digits are the number of digits written after the point, be that 
decinal, binary or any other base. But away from the world of 
mathematics and strict engineering we often refer to the number of 
significant digits as the number of digits that have significance in the 
value of the quantity being represented. eg a temperature or voltage.
For example we might say that a 10 bit analogue to digital converter 
has, in binary, 10 significant digits and in decimal approximately 3. 
What can be confusing here is that if readings from such a converter are 
writen down as whole numbers with a decimal point
     1.0, 2.0 ..... 1023.0
then the readings are /shown /with 1 significant digit.
We could equally write them
     1.00, 2.00 ..... 1023.00
and they are now shown to 2 significant digits. Of course these trailing 
0s are of no practical 'significance' as the ADC cannot affect them. 
Indeed it would not even output them.
So context is everything. Care needs to be taken in understanding the 
use of this term by writers and readers that the context is clear, are 
binary or decimal digits being refered to, are we using 'significant' 
digits in the strict mathematical/engineering sense or a more colloquial 
sense.
Then again we might write 1023.0 in an exponent form
0·1023.10^4    ( 0 point 1023 times 10 to the power 4)
in which case we would say the reading is shown to 4 significant digits

> No, you need to count the significant digits in binary. 1e30 is not an 
> even number in binary floating point.
How so? Whether or not an integer is odd or even has nothing to do with 
its representation in binary of decimal, floating point or integer. If 
you mean the mantissa is odd that may well be true. But the exponent may 
also shift the mantissa left by on1 place or more. In which case the 
value the floating point number is holding must be even. (it is 
multiplied by 2^n where n >= 1)
My Python 2.7.9 does this
 >>> "%50.10f"%1e30
'        1000000000000000019884624838656.0000000000'
 >>>
This indicates that 1e30 is not representable in Python's floating point 
representation.

John
> Apfelkiste:AsynCA chris$ bc
> bc 1.06
> Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
> This is free software with ABSOLUTELY NO WARRANTY.
> For details type `warranty'.
> obase=2
> 10^30
> 11001001111100101100100111001101000001000110011101001110110111101010\
> 01000000000000000000000000000000
> sqrt(10^30)
> 11100011010111111010100100110001101000000000000000
>
> Still, the floating point arithmetic should round to the correct 
> answer if both are converted to decimal.
>
>     Christian
>
>

[toc] | [prev] | [next] | [standalone]


#107046

Fromalister <alister.ware@ntlworld.com>
Date2016-04-15 11:50 +0000
Message-ID<zA4Qy.239300$kw.233873@fx34.am4>
In reply to#107042
On Fri, 15 Apr 2016 12:05:18 +0100, John Pote wrote:

> On 15/04/2016 03:38, Christian Gollwitzer wrote:
>> Am 15.04.16 um 02:36 schrieb Dennis Lee Bieber:
>>>>> I should also have said that the square root of integer squares with
>>>>> between 15 and 30 decimal digits will only be correct if the square
>>>>> numbers themselves are exactly representable in 53 bits.  So we can
>>>>> expect failures for squares with 16 or more digits.
>>>>
>>>> However, if a number with 31 or less digits is known to be the square
>>>> of an integer, the IEEE754 sqrt function will (I believe) give the
>>>> correct result.
>>>
>>>     How could it EXCEPT by having ~15 significant digits and an
>>> exponent --
>>> since that is all the data that is provided by a double precision
>>> floating point. That is, for example,
>>>
>>>>>> 1000000000000000.0 * 1000000000000000.0
>>> 1e+30
>>>>>> import math math.sqrt(1e30)
>>> 1000000000000000.0
>>>>>>
>>>>>>
>>> only has ONE significant digit -- even though it has thirty 0s before
>>> the decimal point.
>>
> As I was taught in school and university the number of significant
> digits are the number of digits written after the point, be that
> decinal, binary or any other base. 

Then I would complain to your education regulator

Significant digits are the 1st X digits in the number (with rounding) 
after converting to standard form.

examples to 3 significant digits

Number	Standard form	3 Significat digits

10	1.0e1		1.00e1 = 10.0
100	1.0e2		1.00e2 = 100
3.14159	3.14159e0	3.14e0	= 3.14
0.01777	1.777e-2	1.78e-2	= 0.0178


-- 
Take your work seriously but never take yourself seriously; and do not
take what happens either to yourself or your work seriously.
		-- Booth Tarkington

[toc] | [prev] | [next] | [standalone]


#107034

Fromblindanagram@nowhere.net
Date2016-04-15 09:41 +0100
Message-ID<5710A92F.3040306@nowhere.net>
In reply to#107018
On 15/04/2016 01:36, Dennis Lee Bieber wrote:
> On Thu, 14 Apr 2016 13:07:03 +0100, blindanagram@nowhere.net declaimed the
> following:
> 
>> On 14/04/2016 09:13, blindanagram@nowhere.net wrote:
>>> On 14/04/2016 08:59, blindanagram@nowhere.net wrote:
>>>> On 14/04/2016 07:52, ast wrote:
>>>
>>>> This means that the result will be correct provided it has 53 or less
>>>> bits - just short of 16 decimal digits (i.e for square numbers with less
>>>> than 32 digits).
>>>>
>>>> With an integer square root function (isqrt), this program:
>>>>
>>>> for exp in count(20):
>>>>   v = 2 ** exp - 1
>>>>   if isqrt(v) != sqrt(v):
>>>>     print(exp, isqrt(v), sqrt(v))
>>>>     break
>>>>
>>>> terminates with:
>>>>
>>>>   54 18014398509481983 1.8014398509481982e+16
>>>>
>>>> showing a first error for a 54 bit square root
>>>>
>>> I should also have said that the square root of integer squares with
>>> between 15 and 30 decimal digits will only be correct if the square
>>> numbers themselves are exactly representable in 53 bits.  So we can
>>> expect failures for squares with 16 or more digits.
>>
>> However, if a number with 31 or less digits is known to be the square of
>> an integer, the IEEE754 sqrt function will (I believe) give the correct
>> result.
> 
> 	How could it EXCEPT by having ~15 significant digits and an exponent --
> since that is all the data that is provided by a double precision floating
> point. 

It can have up to about 30 significant digits because we know thaat it
is the square of a an integer that is representable in IEEE754 floating
point.

So when we consider its square root we only have to consider the squares
of integers that are representable and find the one that is 'nearest' to
our 30 bit integer.

When x is a representable integer the gap between (x- 1)^2, x^2 and (x +
1)^2 is approximately 2 * x and this means that ~30 digit perfect
squares will have different floating point representations because they
differ by a 15 digit value and will hence differ in their first ~15
significant digits.

[toc] | [prev] | [next] | [standalone]


#107048

Fromblindanagram@nowhere.net
Date2016-04-15 09:41 +0100
Message-ID<mailman.17.1460722036.6324.python-list@python.org>
In reply to#107034
On 15/04/2016 01:36, Dennis Lee Bieber wrote:
> On Thu, 14 Apr 2016 13:07:03 +0100, blindanagram@nowhere.net declaimed the
> following:
> 
>> On 14/04/2016 09:13, blindanagram@nowhere.net wrote:
>>> On 14/04/2016 08:59, blindanagram@nowhere.net wrote:
>>>> On 14/04/2016 07:52, ast wrote:
>>>
>>>> This means that the result will be correct provided it has 53 or less
>>>> bits - just short of 16 decimal digits (i.e for square numbers with less
>>>> than 32 digits).
>>>>
>>>> With an integer square root function (isqrt), this program:
>>>>
>>>> for exp in count(20):
>>>>   v = 2 ** exp - 1
>>>>   if isqrt(v) != sqrt(v):
>>>>     print(exp, isqrt(v), sqrt(v))
>>>>     break
>>>>
>>>> terminates with:
>>>>
>>>>   54 18014398509481983 1.8014398509481982e+16
>>>>
>>>> showing a first error for a 54 bit square root
>>>>
>>> I should also have said that the square root of integer squares with
>>> between 15 and 30 decimal digits will only be correct if the square
>>> numbers themselves are exactly representable in 53 bits.  So we can
>>> expect failures for squares with 16 or more digits.
>>
>> However, if a number with 31 or less digits is known to be the square of
>> an integer, the IEEE754 sqrt function will (I believe) give the correct
>> result.
> 
> 	How could it EXCEPT by having ~15 significant digits and an exponent --
> since that is all the data that is provided by a double precision floating
> point. 

It can have up to about 30 significant digits because we know thaat it
is the square of a an integer that is representable in IEEE754 floating
point.

So when we consider its square root we only have to consider the squares
of integers that are representable and find the one that is 'nearest' to
our 30 bit integer.

When x is a representable integer the gap between (x- 1)^2, x^2 and (x +
1)^2 is approximately 2 * x and this means that ~30 digit perfect
squares will have different floating point representations because they
differ by a 15 digit value and will hence differ in their first ~15
significant digits.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web