Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we assume that x == (int)sqrt(x * x) for all positive integers?

Tags:

java

c++

c

math

In C++ the sqrt function operates only with double values.

If we use integers (unsigned long long) can we be sure that

x == sqrt(x * x)

for any positive x where x * x <= MAXIMUM_VALUE?

Is it depend on the machine architecture and compiler?

like image 686
Jegors Čemisovs Avatar asked Feb 16 '21 15:02

Jegors Čemisovs


People also ask

Does math sqrt return a double or int?

Math. sqrt() method returns a double value which is the square root of the given value and is a correctly rounded positive number. If the argument is NaN and negative number (or negative infinity) Math. sqrt() method returns NaN i.e. Not a Number.

How do you check if a number has an integer square root?

If an integer has square-root, then the last digit is either 0 (even number of zeros) or 1 or 9 ( and the tenth digit must be even) or 4 or 6 ( and the number consisting of the last two digits is divisible by 4) or 5 (and the tenth digit must be 2).

Is the square root of a positive integer always integer?

Which is the same thing as saying if positive integer n has a square root, the root is either integer or irrational. But we have not actually proven that positive integer n actually has any square root at all.

What is the integer square root of X?

Introduction For a natural number x (i.e. x ∈ {0,1,2,3,...}), the integer square root of x is defined as the natural number r such that r2 ≤ x < ( r + 1) 2. It is the greatest r such that r2 ≤ x, or equivalently, the least r such that ( r + 1) 2 > x.

How do you prove that X is an integer?

A generalisation of Euclid's lemma states that if n divides a b and n is coprime to a, then n divides b. Using this lemma, it is easy to prove directly that if x is rational and x 2 is an integer, then x is an integer. Suppose that ( p q) 2 = m, where p and q are coprime. Then p 2 = m q 2, so q divides p 2.

Which integer has a rational square root without any prime factors?

But the only positive integer without prime factors is 1 so b = 1 and n = a 2 so n = a. So either for any integer either n is a perfect square with an integer square root, or n does not have a rational square root.


1 Answers

In Java, Math.sqrt(x) takes a double value. You stated that x is such that x * x is below Integer.MAX_VALUE. Every integer is perfectly representable in double - double in java is explicitly defined as an iEEE-754 style double with a 52-bit mantissa; therefore in java a double can perfectly represent all integral values between -2^52 and +2^52, which easily covers all int values (as that is defined as signed 32-bit on java), but it does not cover all long values. (Defined as signed 64-bit; 64 is more than 52, so no go).

Thus, x * x loses no precision when it ends up getting converted from int to double. Then, Math.sqrt() on this number will give a result that is also perfectly representable as a double (because it is x, and given that x*x fits in an int, x must also fit), and thus, yes, this will always work out for all x.

But, hey, why not give it a shot, right?

public static void main(String[] args) {
    int i = 1;
    while (true) {
        if (i * i < 0) break;
        int j = (int) Math.sqrt(i * i);
        if (i != j) System.out.println("Oh dear! " + i + " -> " + j);

        i++;
    }
    System.out.println("Done at " + i);
}

> Done at 46341

Thus proving it by exhaustively trying it all.

Turns out, none exist - any long value such that x * x still fits (thus, is <2^63-1) has the property that x == (long) Math.sqrt(x * x);. This is presumably because at x*x, the number fits perfectly in a long, even if not all integer numbers that are this large do. Proof:

long p = 2000000000L;
for (; true; p++) {
    long pp = p * p;
    if (pp < 0) break;
    long q = (long) Math.sqrt(pp);
    if (q != p) System.out.println("PROBLEM: " + p + " -> " + q);
}
System.out.println("Abort: " + p);

> Abort: 3037000500

Surely if any number exists that doesn't hold, there is at least one in this high end range. Starting from 0 takes very long.

But do we know that sqrt will always return an exact value for a perfect square, or might it be slightly inaccurate?

We should - it's java. Unlike C, almost everything is 'well defined', and a JVM cannot legally call itself one if it fails to produce the exact answer as specified. The leeway that the Math.sqrt docs provide is not sufficient for any answer other than precisely x to be a legal implementation, therefore, yes, this is a guarantee.

In theory the JVM has some very minor leeway with floating point numbers, which strictfp disables, but [A] that's more about using 80-bit registers to represent numbers instead of 64, which cannot possibly ruin this hypothesis, and [B] a while back a java tag question showed up to show strictfp having any effect on any hardware and any VM version and the only viable result was a non-reproducible thing from 15 years ago. I feel quite confident to state that this will always hold, regardless of hardware or VM version.

like image 67
rzwitserloot Avatar answered Oct 16 '22 21:10

rzwitserloot