Test for equation irrational

寵の児 提交于 2020-01-02 10:33:57

问题


I'm making a number data shower, which show the data of a number, like even or odd. Now I stopped at irrational numbers, how can I test for is it that?

Something like this:

alert(isIrrational(Math.sqrt(9)));

回答1:


It depends on the context, but you might want to say that floating point numbers that are very close to simple rational numbers should be identified as rational, and otherwise they should be identified as possible irrational numbers. You have to choose definitions for "very close" and "simple rational numbers."

For relatively small numbers (say absolute value under 100), you might say that the simple rational numbers are those with small denominators, such as 2/3, say those with denominators under 100. Your definition of "very close" might be that the absolute magnitude of the difference is small, say under 10^-6, or you might require numbers to be closer than 1000 times the square the of denominator. For most purposes, this is enough.

The theory of rational approximations to a number with small denominators is part of number theory called Diophantine approximation. One tool you might use is the simple continued fraction expansion of a number, such as pi = 3+1/(7+1/(15+1/(1+1/292+...))) and e-1=1+1/(1+1/(2+1/(1+1/(1+1/(4+1/(1+1/(1+1/(6+...))). You can compute these recursively although you run out of precision quickly. When you truncate such an expression, you get a good rational approximation, such as pi~3, or pi~22/7, pi~355/113, or e~193/71. These give the candidate rational numbers with small denominators which are close. Large coefficients in the simple continued fraction mean the number has a good rational approximation.

Some rational numbers will not be detected to be rational this way, such as 1/500 if you use a threshold of 100 for the denominator. However, you would be able to identify 1/3.0f as rational, and Math.sqrt(2.0)*Math.sqrt(8.0), which you would reject Math.sqrt(2.0).

I don't know if there is a standard way to determine the complexity of a large float like 6.73241 x 10^31. That could even be an integer, but you don't have the precision to tell. You might say that numbers close to smooth integers are simple. Smooth means that there are no large primes in the prime factorization. While factoring large numbers in general is hard, factoring smooth numbers is not so bad because you only have to test a few possible prime factors. When you can't even test nearby numbers for smoothness, you might compare the logarithm of the number with combinations of the logarithms of small primes. This might mean that a large prime would not be identified as a rational number, but in case you care, record-setting prime numbers are typically 1 away from smooth numbers, e.g., 2**57885161-1.

Between extremely large floating point numbers and decimals, you might use some sort of complexity measure which uses a combination of the simplicity of the possible numerators and the simplicity of the possible denominators. So, for numbers between 10^6 and 10^9, you might decide that you only tolerate denominators up to 10, and you might require that the difference be smaller than 10^-4 from one of these numbers.




回答2:


Determining whether sqrt(rational) is irrational or not is fairly simple. Here is how:

Write the rational argument as m/n with m and n integers and coprime, i.e., gcd(n, m) = 1. Now assume that there exists a rational square root r of m/n. If r = s/t with s and t integers and coprime, we would have:

s^2/t^2 = rˆ2 = m/n

or

n * s * s = m * t * t

In particular s * s would divide m * t * t and since s and t have no common primes, s * s would actually divide m. In other words, we would have (1) s * s <= m and (2) m % (s * s) = 0 (mod operation). So, all candidates for s could be computed very easily with the following routine

  1. [Initialize] Let S be an empty collection of divisors and d := 1.
  2. [Check] If m % (d * d) = 0, then add d to S
  3. [Increment] Set d := d + 1
  4. [Repeat] If d * d <= m go to 2
  5. [End] Return S

In the same way we may conclude that t satisfies (1) t * t <= n and (2) n % (t * t) = 0. And we could use the same routine as above to compute the collection T of all squared divisors of n (just replace S with T and m with n.)

Finally, we would have to enumerate all pairs (s, t) in S x T looking for a pair such that

m * s * s = n * t * t

using exact integer arithmetic, which is perfectly possible. If no pair (s, t) is found, then sqrt(m/n) would be irrational.

Example

Let's pretend we don't know that sqrt(100/81) is the rational 10/9 and let's deduce it using the algorithm given above:

First we compute the collection D of squared divisors of 100. Here is a trace of the algorithm:

`d = 1` Yes, `100 % (1 * 1) = 0`
`d = 2` Yes, `100 % (2 * 2) = 0`
`d = 3` No, `100 % (3 * 3) = 1`
`d = 4` No, `100 % (4 * 4) = 4`
`d = 5` Yes, `100 % (5 * 5) = 0`
`d = 6` No, `100 % (6 * 6) = 28`
`d = 7` No, `100 % (7 * 7) = 2`
`d = 8` No, `100 % (8 * 8) = 36`
`d = 9` No, `100 % (9 * 9) = 19`
`d = 10` Yes, `100 % (10 * 10) = 0`
End: `11 * 11 > 100`.

So, D = {1, 2, 5, 10}. Now let's compute T, squared divisors of 81

`d = 1`, Yes
`d = 2`, No (remainder = 1)
`d = 3`, Yes
`d = 4`, No (remainder = 1)
`d = 5`, No (remainder = 6)
`d = 6`, No (remainder = 9)
`d = 7`, No (remainder = 32)
`d = 8`, No (remainder = 17)
`d = 9`, Yes
End: `10 * 10 > 81`.

So, T = {1, 3, 9}

Now we enumerate all pairs (s, t) in D x T and compare 81 * s * s with 100 * t * t. The pairs are:

(1, 1), (2, 1), (5, 1), (10, 1)
(1, 3), (2, 3), (5, 3), (10, 3)
(1, 9), (2, 9), (5, 9), (10, 9)

and we see that the last one (10, 9) satisfies 81 * 10 * 10 = 100 * 9 * 9. Therefore sqrt(100/81) = 10/9. Had the example been chosen so that no pair satisfies the equation the squared root would have been irrational.




回答3:


Here's a possibility. The first step is to find the next smallest and largest float (which are the various assignments leading up to prevFloat and nextFloat). After than, we step through all possible rational numbers with the denominator below a certain threshold, looking for something to fit between the floats. If it can't find a fraction before running out of potential denominators, it reports NaN. The function ends up running in O(maxDenom).

function asRational(number) {
    var maxDenom = 1000,
        sign = number < 0 ? "-" : "+",
        absVal = Math.abs(number),
        integer = Math.floor(absVal),
        fractionalPart = absVal-integer,
        asBinary = fractionalPart.toString(2),
        prevAsBinary = asBinary.replace(/10*$/,function(match) {
            return "0"+Array(match.length).join("1");
        }),
        nextAsBinary = asBinary.replace(/01*$/,function(match) {
            return "1"+Array(match.length).join("0");
        }),
        prevFloat = parseFloat(prevAsBinary,2),
        nextFloat = parseFloat(nextAsBinary,2),
        numerator = 0;
    for ( var denominator = 1 ; denominator <= maxDenom ; denominator++ ) {
        while ( numerator < denominator*prevFloat ) {
            numerator++;
        }
        if ( numerator <= denominator*nextFloat ) {
            return {
                "sign":sign,
                "integer":integer,
                "numerator":numerator,
                "denominator":denominator
            };
        }
    }
    return NaN;
}

function rationalToString(rational) {
    if ( !! rational ) {
        return rational.sign+"("+rational.integer
            +"+"+rational.numerator+"/"+rational.denominator+")";
    } else {
        return "NaN";
    }
}

function parseFloat(asString,radix) {
    var power = asString.length-asString.indexOf(".")-1,
        asFloat = parseInt(asString.replace(".",""),radix);
    for ( var i = 0 ; i < power ; i++ ) {
        asFloat /= radix;
    }
    return asFloat;
}

var paras = document.getElementsByTagName("p");
for ( var i = 0 ; i < paras.length ; i++ ) {
    paras[i].textContent
        = paras[i].id+"="+rationalToString(asRational(eval(paras[i].id)));
}
<html>
 <head>
 </head>
 <body>
  <p id="5/3"></p>
  <p id="100/999"></p>
  <p id="99/1000"></p>
  <p id="100/1001"></p>
  <p id="1000/10000"></p>
 </body>
</html>


来源:https://stackoverflow.com/questions/28768654/test-for-equation-irrational

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!