On Feb 12, 12:12 pm, Joel VanderWerf <v... / path.berkeley.edu> wrote: > Sam Kong wrote: > > Hi Joel, > > > On Feb 11, 11:37 am, Joel VanderWerf <v... / path.berkeley.edu> wrote: > >> Sam Kong wrote: > >>> Hello, > >>> I'm solving a math problem in Ruby. > >>> I need to determine if a number is a perfect square. > >>> If the number is small, you may do like the following. > >>> def perfect_square? n > >>> sqrt = n ** 0.5 > >>> sqrt - sqrt.to_i == 0 > >>> end > >>> But Float number has limitation on precision. > >>> Thus the function won't work correctly for big numbers like > >>> (123456789123456789). > >>> How would you solve such a case? > >>> It should be fast as well as correct because I will use it repeatedly. > >> Easy: compare integers rather than floats. > > >> x = 123456789123456789 > > >> sqrt = Math::sqrt(x) > >> p(x == sqrt.floor**2) > > > Yes. Your approach is better than mine. > > But it gives a wrong answer for big numbers like 55833579873437812. > > Wrong how? > > irb(main):001:0> x = 55833579873437812 > => 55833579873437812 > irb(main):002:0> sqrt = Math::sqrt(x) > => 236291303.0 > irb(main):003:0> sqrt.floor**2 - x > => -3 > > Ok, I can see that one problem with my approach is that I should have > used #round instead of #floor. I think even if you use #round, the problem won't go away. Float type cannot generate correct result due to its limited precision. Sam > > -- > vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407