-2

I was solving a problem where I had to determine whether the given number is a Fibonacci number or not.

It involves a step where we have to check if 5*n*n-4 or 5*n*n+4 (n is given number and is always greater than 0) is a perfect square or not. If anyone of those terms or both are perfect squares then it is Fibonacci number else not.

I used the below statements to check for a perfect square.

def isPerfectSquare(n):
    x = 5*n**2-4
    y = 5*n**2+4
    r1 = int(math.sqrt(x))
    r2 = int(math.sqrt(y))
    return r1*r1==x or r2*r2==y
}

But this method showed wrong answer for 4 of the test cases.

Whereas When I used this(below) method it passed all the test cases.

def isPerfectSquare(n):
    r1 = math.sqrt(5*n**2-4)
    r2 = math.sqrt(5*n**2+4)
    return r1%1==0 or r2%1==0
}

What is the difference between the above two methods in finding a perfect square?

Does it also affect the time complexity of the program?

Ketan Sahu
  • 127
  • 1
  • 11
  • You might want to post your test cases. Otherwise, people would have to guess what the problematic test cases are. Whoever fails to guess will be unable to answer your question, so posting the relevant test cases may increase the chance for you to get an answer. – anatolyg May 17 '20 at 12:16
  • If the second one passes all test cases then you have a serious problem with your test cases. Because `x%1==0` is always true. – interjay May 17 '20 at 12:20
  • I checked the second one. 0%1 ok, 1%1 ok, must be right. – stark May 17 '20 at 13:06
  • @stark You forgot to check it for a randomly chosen number, e.g. 100 :) – anatolyg May 17 '20 at 13:13
  • The similarity between the functions is that neither is guaranteed to work (produce a correct result) for all possible values of `num`. The difference is probably that your test cases happen to work with the second. Unfortunately, this is no more than a sign that your testing is inadequate, since both functions will fail in some cases and not others - there will be some test cases where one or the other fails, some where both succeed, and some where both fail. – Peter May 17 '20 at 13:26
  • Both implementations of `isPerfectSquare` do not check whether the input is negative. [A domain error occurs](https://en.cppreference.com/w/cpp/numeric/math/sqrt) if the argument is negative, it's possible that the result of the function will be `NAN`. You cannot reliably cast this value to an integer, therefore, the results of either implementation of`isPerfectSquare` are undefined for negative values. This may or may not be the reason for your test cases failing. – dreamlax May 17 '20 at 13:31
  • @interjay it is not always true, you should take some examples and check. I had the same doubt initially. – Ketan Sahu May 18 '20 at 06:34
  • @anatolyg I solved this question on an online platform and they don't reveal the test cases. So I can't really post any of the test case on which it was failing. – Ketan Sahu May 18 '20 at 06:38
  • @Peter I don't know if Hackerrank (online coding platform) do inadequate testing but that's what I got, it didn't pass for first function and passed all test cases for second function. – Ketan Sahu May 18 '20 at 06:44
  • @dreamlax sorry I didn't mention that the constraint of n, 1<=n=<10^10. Now since n is always greater than equal to 1 so neither of 5*n*n-4 or 5*n*n+r will produce a negative value and thus when it is passed to the function the argument will always be positive. – Ketan Sahu May 18 '20 at 06:48
  • About your last comment: https://wandbox.org/permlink/HTBzFTIyxmKnSPuf . Please note that signed integer overflow is UB. – Bob__ May 18 '20 at 09:36
  • Also: https://wandbox.org/permlink/w82RV06z4krYWCAv – Bob__ May 18 '20 at 09:41
  • So what examples of numbers do you have where `x % 1 != 0`? – interjay May 18 '20 at 11:47
  • @interjay here you go: https://onlinegdb.com/SkjpOUeoI My bad that I wrote the data type as long long int it should be float to give the result that I wanted to show. I'll correct that in the question. – Ketan Sahu May 18 '20 at 18:52
  • @Bob__ here you go: https://onlinegdb.com/SkjpOUeoI Here I'm printing the examples that are not giving zero on dividing with 1. – Ketan Sahu May 18 '20 at 18:56
  • 2
    Please note that operator `%` applied to real numbers in Python **is not equal** to operator `%` applied to two integer values in C++. A comparable operation would be [`std::fmod`](https://en.cppreference.com/w/cpp/numeric/math/fmod). – Bob__ May 18 '20 at 19:06
  • @Bob__ okay cool. But for now, can you tell why and how are the above two codes different (I have put the python codes that were confusing me)? – Ketan Sahu May 18 '20 at 19:14
  • What happens if you use `round()` instead of `int()` or `int(round(...))`? – Bob__ May 18 '20 at 19:20
  • I didn't check that. Do you want me to check it on those test cases and see if they pass? – Ketan Sahu May 18 '20 at 19:25

1 Answers1

0

long long will automatically round up your number so that is why it fails some of the tests try storing the sqrt in a double or long double

SzymonO
  • 432
  • 3
  • 15