Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #106925 > unrolled thread
| Started by | martin.spichty@gmail.com |
|---|---|
| First post | 2016-04-13 00:41 -0700 |
| Last post | 2016-04-15 09:41 +0100 |
| Articles | 18 — 11 participants |
Back to article view | Back to comp.lang.python
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
| From | martin.spichty@gmail.com |
|---|---|
| Date | 2016-04-13 00:41 -0700 |
| Subject | Serious 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]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2016-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]
| From | Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> |
|---|---|
| Date | 2016-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]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2016-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]
| From | "ast" <nomail@com.invalid> |
|---|---|
| Date | 2016-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]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2016-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]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-04-14 09:46 +0200 |
| Subject | Accuracy 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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2016-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]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2016-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]
| From | John Pote <johnhpote@o2.co.uk> |
|---|---|
| Date | 2016-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]
| From | alister <alister.ware@ntlworld.com> |
|---|---|
| Date | 2016-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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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]
| From | blindanagram@nowhere.net |
|---|---|
| Date | 2016-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