From: John W Higgins Date: 2017-02-19T21:47:54-08:00 Subject: [ruby-core:79623] Re: [Ruby trunk Feature#13219] bug in Math.sqrt(n).to_i, to compute integer squareroot, new word to accurately fix it --===============1079726400== Content-Type: multipart/alternative; boundary=001a11416550451f8a0548efcfeb --001a11416550451f8a0548efcfeb Content-Type: text/plain; charset=UTF-8 On Sun, Feb 19, 2017 at 8:27 PM, wrote: > I don't think it was the intent of Matz to create math methods that give > correct results > some of the time, but not tell users under what conditions they wouldn't > give correct results. > Unless you had my use cases, it was probably never tested to cover giving > correct results for them. > You assume that the answer is incorrect due to an error - it is as correct as the underlying numeric expression allows. Shockingly 0.1 + 0.2 = 0.30000000000000004 on my system in both Ruby and Python - and it's not an error. It's called a floating point number and it has limitations. You happen to hit the limitation at the other end of the scale. The answer you seek for the square root of 10**35 is 316227766016837933 but a floating number cannot hold that value. 316227766016837933.to_f.to_i gives 316227766016837952 which is exactly the answer it provides to the square root call. Floating point even offers methods called next_float and prev_float. 316227766016837952.next_float.to_i = 316227766016838016 316227766016837952.prev_float.to_i = 316227766016837888 That means the only number one can express between 316227766016838016 and 316227766016837888 is 316227766016837952. That is the limitation of an IEEE 754 floating point. There is no option around it when you use functions that return floats. It's not an error - you are using a tool that is less precise than you need. No different then walking into a chemistry lab with my kitchen measuring cup and wondering why I can't get exact liquid measurements - you have hit the limit of what your tools can provide you. In terms of BigDecimal being slower than your "unitasker" (single use) function - sure - but there is probably not a line of Ruby that would not be faster if completely optimized for a single use. The standard tool for the work you wish to accomplish is BigDecimal/BigMath - you are using the wrong tool here. John P.S. Creating your own gem with specialized methods is a great option - even better if you/someone can work up the C variant of your concept. But that again does not imply that anything at all is wrong with neither Math nor BigMath at all. They accomplish exactly what they are designed for. --001a11416550451f8a0548efcfeb Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

= On Sun, Feb 19, 2017 at 8:27 PM, <jzakiya@gmail.com> wrote:=
I don't think= it was the intent of Matz to create math methods that give correct results=
some of the time, but not tell users under what conditions they wouldn'= t give correct results.
Unless you had my use cases, it was probably never tested to cover giving c= orrect results for them.


You assume that the answer is incorrect due to an error - = it is as correct as the underlying numeric expression allows.

=
Shockingly 0.1 + 0.2 =3D 0.30000000000000004 on = my system in both Ruby and Python - and it's not an error. It's cal= led a floating point number and it has limitations. You happen to hit the l= imitation at the other end of the scale.

The answer you seek for the square root of 10**35 is 3162277660168379= 33 but a floating number cannot hold that value.

316227766016837933.to_f.to_i gives 316227766016837952 which i= s exactly the answer it provides to the square root call.

Floating point even offers methods called next_float= and prev_float.

316227766016837952= .next_float.to_i =3D 316227766016838016
316227766016837952.prev_float.to= _i =3D 316227766016837888

That mean= s the only number one can express between 316227766016838016 and 3162277660= 16837888 is 316227766016837952. That is the limitation of an IEEE 754 float= ing point. There is no option around it when you use functions that return = floats. It's not an error - you are using a tool that is less precise t= han you need. No different then walking into a chemistry lab with my kitche= n measuring cup and wondering why I can't get exact liquid measurements= - you have hit the limit of what your tools can provide you.

=
In terms of BigDecimal being slower than your &q= uot;unitasker" (single use) function - sure - but there is probably no= t a line of Ruby that would not be faster if completely optimized for a sin= gle use.

The standard tool for the = work you wish to accomplish is BigDecimal/BigMath - you are using the wrong= tool here.

John

P.S. Creating your own gem with specialized methods i= s a great option - even better if you/someone can work up the C variant of = your concept. But that again does not imply that anything at all is wrong w= ith neither Math nor BigMath at all. They accomplish exactly what they are = designed for.

--001a11416550451f8a0548efcfeb-- --===============1079726400== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline Unsubscribe: --===============1079726400==--