Test integerness: Difference between revisions
Content added Content deleted
(add →Free Pascal: and →Pascal) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 116: | Line 116: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">F isint(f) |
||
R Complex(f).imag == 0 & fract(Complex(f).real) == 0 |
R Complex(f).imag == 0 & fract(Complex(f).real) == 0 |
||
Line 126: | Line 126: | ||
print(isint(Float.infinity)) |
print(isint(Float.infinity)) |
||
print(isint(5.0 + 0.0i)) |
print(isint(5.0 + 0.0i)) |
||
print(isint(5 - 5i))</ |
print(isint(5 - 5i))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 143: | Line 143: | ||
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}} |
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}} |
||
Uses LONG LONG values which in Algol 68 have a programmer specifiable number of digits. As with the C version, we need only handle the complex case directly, as Algol 68 will automatically coerce integer and real values to complex as required. |
Uses LONG LONG values which in Algol 68 have a programmer specifiable number of digits. As with the C version, we need only handle the complex case directly, as Algol 68 will automatically coerce integer and real values to complex as required. |
||
< |
<syntaxhighlight lang="algol68"># set the required precision of LONG LONG values using # |
||
# "PR precision n PR" if required # |
# "PR precision n PR" if required # |
||
PR precision 24 PR |
PR precision 24 PR |
||
Line 168: | Line 168: | ||
test is int( 4.0 I 0 ); |
test is int( 4.0 I 0 ); |
||
test is int( 123456789012345678901234 ) |
test is int( 123456789012345678901234 ) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 179: | Line 179: | ||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
<syntaxhighlight lang="awk"> |
|||
<lang AWK> |
|||
# syntax: GAWK -f TEST_INTEGERNESS.AWK |
# syntax: GAWK -f TEST_INTEGERNESS.AWK |
||
BEGIN { |
BEGIN { |
||
Line 190: | Line 190: | ||
exit(0) |
exit(0) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 206: | Line 206: | ||
The main function that checks a numeric value is actually quite short. Because of C's weak types and implicit casting we can get away with making a function which checks long double complex types only. |
The main function that checks a numeric value is actually quite short. Because of C's weak types and implicit casting we can get away with making a function which checks long double complex types only. |
||
<syntaxhighlight lang="c"> |
|||
<lang c> |
|||
#include <stdio.h> |
#include <stdio.h> |
||
#include <complex.h> |
#include <complex.h> |
||
Line 264: | Line 264: | ||
printf("Test 4 (0+1.2i) = %s\n", isint(test4) ? "true" : "false"); |
printf("Test 4 (0+1.2i) = %s\n", isint(test4) ? "true" : "false"); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 296: | Line 296: | ||
< |
<syntaxhighlight lang="c sharp"> |
||
namespace Test_integerness |
namespace Test_integerness |
||
{ |
{ |
||
Line 426: | Line 426: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out| Program Input and Output :}} |
{{out| Program Input and Output :}} |
||
<pre> |
<pre> |
||
Line 513: | Line 513: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp"> |
||
#include <complex> |
#include <complex> |
||
#include <math.h> |
#include <math.h> |
||
Line 683: | Line 683: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 716: | Line 716: | ||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
COBOL likes to work with fixed-point decimal numbers. For the sake of argument, this program tests the "integerness" of values that have up to nine digits before the decimal point and up to nine digits after. It can therefore be "tricked", as in the third of the four tests below, by computing a result that differs from an integer by less than 0.000000001; if there is any likelihood of such results arising, it would be a good idea to allow more digits of precision after the decimal point. Support for complex numbers (in a sense) is included, because the specification calls for it—but it adds little of interest. |
COBOL likes to work with fixed-point decimal numbers. For the sake of argument, this program tests the "integerness" of values that have up to nine digits before the decimal point and up to nine digits after. It can therefore be "tricked", as in the third of the four tests below, by computing a result that differs from an integer by less than 0.000000001; if there is any likelihood of such results arising, it would be a good idea to allow more digits of precision after the decimal point. Support for complex numbers (in a sense) is included, because the specification calls for it—but it adds little of interest. |
||
< |
<syntaxhighlight lang="cobol">IDENTIFICATION DIVISION. |
||
PROGRAM-ID. INTEGERNESS-PROGRAM. |
PROGRAM-ID. INTEGERNESS-PROGRAM. |
||
DATA DIVISION. |
DATA DIVISION. |
||
Line 750: | Line 750: | ||
ELSE DISPLAY POSSIBLE-INTEGER ' IS NOT AN INTEGER.'. |
ELSE DISPLAY POSSIBLE-INTEGER ' IS NOT AN INTEGER.'. |
||
COMPLEX-PARAGRAPH. |
COMPLEX-PARAGRAPH. |
||
DISPLAY REAL-PART '+' IMAGINARY-PART 'i IS NOT AN INTEGER.'.</ |
DISPLAY REAL-PART '+' IMAGINARY-PART 'i IS NOT AN INTEGER.'.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>-000000004.000000000 IS AN INTEGER. |
<pre>-000000004.000000000 IS AN INTEGER. |
||
Line 758: | Line 758: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.complex; |
||
import std.math; |
import std.math; |
||
import std.meta; |
import std.meta; |
||
Line 844: | Line 844: | ||
assert(isInteger(0.00009i, 0.0001)); |
assert(isInteger(0.00009i, 0.0001)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 859: | Line 859: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
< |
<syntaxhighlight lang="elixir">defmodule Test do |
||
def integer?(n) when n == trunc(n), do: true |
def integer?(n) when n == trunc(n), do: true |
||
def integer?(_), do: false |
def integer?(_), do: false |
||
Line 866: | Line 866: | ||
Enum.each([2, 2.0, 2.5, 2.000000000000001, 1.23e300, 1.0e-300, "123", '123', :"123"], fn n -> |
Enum.each([2, 2.0, 2.5, 2.000000000000001, 1.23e300, 1.0e-300, "123", '123', :"123"], fn n -> |
||
IO.puts "#{inspect n} is integer?: #{Test.integer?(n)}" |
IO.puts "#{inspect n} is integer?: #{Test.integer?(n)}" |
||
end)</ |
end)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 883: | Line 883: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
The <code>number=</code> word in the <code>math</code> vocabulary comes very close to encapsulating this task. It compares numbers for equality without regard for class, like <code>=</code> would. However, since <code>>integer</code> and <code>round</code> do not specialize on the <code>complex</code> class, we need to handle complex numbers specially. We use <code>>rect</code> to extract the real components of the complex number for further processing. |
The <code>number=</code> word in the <code>math</code> vocabulary comes very close to encapsulating this task. It compares numbers for equality without regard for class, like <code>=</code> would. However, since <code>>integer</code> and <code>round</code> do not specialize on the <code>complex</code> class, we need to handle complex numbers specially. We use <code>>rect</code> to extract the real components of the complex number for further processing. |
||
< |
<syntaxhighlight lang="factor">USING: formatting io kernel math math.functions sequences ; |
||
IN: rosetta-code.test-integerness |
IN: rosetta-code.test-integerness |
||
Line 918: | Line 918: | ||
[ ] [ integral? ] [ 0.00001 fuzzy-int? ] tri |
[ ] [ integral? ] [ 0.00001 fuzzy-int? ] tri |
||
"%-41u %-11u %u\n" printf |
"%-41u %-11u %u\n" printf |
||
] each</ |
] each</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 943: | Line 943: | ||
The MODULE protocol of F90 is used, merely to save on the need to define the types of the function in each routine that uses them, since there is no default type for LOGICAL. Otherwise, this is F77 style. |
The MODULE protocol of F90 is used, merely to save on the need to define the types of the function in each routine that uses them, since there is no default type for LOGICAL. Otherwise, this is F77 style. |
||
< |
<syntaxhighlight lang="fortran"> MODULE ZERMELO !Approach the foundations of mathematics. |
||
CONTAINS |
CONTAINS |
||
LOGICAL FUNCTION ISINTEGRAL(X) !A whole number? |
LOGICAL FUNCTION ISINTEGRAL(X) !A whole number? |
||
Line 970: | Line 970: | ||
Z = DCMPLX(-3D0,4*ATAN(1D0)) |
Z = DCMPLX(-3D0,4*ATAN(1D0)) |
||
WRITE (6,*) ISINTEGRALZ(Z),Z |
WRITE (6,*) ISINTEGRALZ(Z),Z |
||
END</ |
END</syntaxhighlight> |
||
<pre> |
<pre> |
||
See if some numbers are integral... |
See if some numbers are integral... |
||
Line 981: | Line 981: | ||
The argument is the same with binary (or base 4, 8 or 16), but, you have to know what base is used to prepare the proper boundary value, similarly you must ascertain just how many digits of precision are in use, remembering that in binary the leading one of normalised numbers may be represented implicitly, or it may be explicitly present. One would have to devise probing routines with delicate calculations that may be disrupted by various compiler optimisation tricks and unanticipated details of the arithmetic mill. For instance, the Intel 8087 floating-point co-processor and its descendants use an implicit leading-one bit for 32- and 64-bit floating-point numbers, but ''not'' for 80-bit floating-point numbers. So if your compiler offers a REAL*10 type, such variables will enjoy a slightly different style of arithmetic. Further, ''during'' a calculation (add, subtract, multiply, divide) a further three guard bits (with special meanings) are employed. Calculations are done with full 83-bit precision to yield an 80-bit result; it is only when values are stored that they are converted to single or double precision format in storage - the register retains full precision. On top of that, the arithmetic can employ "denormalised" numbers during underflow towards zero. Chapter 6 of ''The I8087 Numeric Data Processor'', page 219, remarks "At least some of the generalised numerical solutions to common mathematical procedures have coding that is so involved and tricky in order to take care of all possible roundoff contingencies that they have been termed 'pornographic algorithms'". So a probe routine that worked for one design will likely need tweaking when tried on another system. |
The argument is the same with binary (or base 4, 8 or 16), but, you have to know what base is used to prepare the proper boundary value, similarly you must ascertain just how many digits of precision are in use, remembering that in binary the leading one of normalised numbers may be represented implicitly, or it may be explicitly present. One would have to devise probing routines with delicate calculations that may be disrupted by various compiler optimisation tricks and unanticipated details of the arithmetic mill. For instance, the Intel 8087 floating-point co-processor and its descendants use an implicit leading-one bit for 32- and 64-bit floating-point numbers, but ''not'' for 80-bit floating-point numbers. So if your compiler offers a REAL*10 type, such variables will enjoy a slightly different style of arithmetic. Further, ''during'' a calculation (add, subtract, multiply, divide) a further three guard bits (with special meanings) are employed. Calculations are done with full 83-bit precision to yield an 80-bit result; it is only when values are stored that they are converted to single or double precision format in storage - the register retains full precision. On top of that, the arithmetic can employ "denormalised" numbers during underflow towards zero. Chapter 6 of ''The I8087 Numeric Data Processor'', page 219, remarks "At least some of the generalised numerical solutions to common mathematical procedures have coding that is so involved and tricky in order to take care of all possible roundoff contingencies that they have been termed 'pornographic algorithms'". So a probe routine that worked for one design will likely need tweaking when tried on another system. |
||
To determine the number of digits of precision, one probes somewhat as follows:< |
To determine the number of digits of precision, one probes somewhat as follows:<syntaxhighlight lang="fortran"> X = 1 |
||
10 X = X*BASE |
10 X = X*BASE |
||
Y = X + 1 |
Y = X + 1 |
||
D = Y - X |
D = Y - X |
||
IF (D .EQ. 1) GO TO 10</ |
IF (D .EQ. 1) GO TO 10</syntaxhighlight> |
||
Or alternatively, compare 1 + ''eps'' to 1, successively dividing ''eps'' by BASE. |
Or alternatively, compare 1 + ''eps'' to 1, successively dividing ''eps'' by BASE. |
||
Line 997: | Line 997: | ||
Despite the attempt at generality, there will be difficulties on systems whose word sizes are not multiples of eight bits so that the REAL*4 scheme falters. Still, it is preferable to a blizzard of terms such as small int, int, long int, long long int. A decimal computer would be quite different in its size specifications, and there have been rumours of a Russian computer that worked in base three... |
Despite the attempt at generality, there will be difficulties on systems whose word sizes are not multiples of eight bits so that the REAL*4 scheme falters. Still, it is preferable to a blizzard of terms such as small int, int, long int, long long int. A decimal computer would be quite different in its size specifications, and there have been rumours of a Russian computer that worked in base three... |
||
<syntaxhighlight lang="fortran"> |
|||
<lang Fortran> |
|||
MODULE ZERMELO !Approach the foundations of mathematics. |
MODULE ZERMELO !Approach the foundations of mathematics. |
||
INTERFACE ISINTEGRAL !And obscure them with computerese. |
INTERFACE ISINTEGRAL !And obscure them with computerese. |
||
Line 1,059: | Line 1,059: | ||
WRITE (6,*) ISINTEGRAL(Z),Z |
WRITE (6,*) ISINTEGRAL(Z),Z |
||
END |
END |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 1,071: | Line 1,071: | ||
=={{header|Free Pascal}}== |
=={{header|Free Pascal}}== |
||
< |
<syntaxhighlight lang="delphi">// in FPC 3.2.0 the definition of `integer` still depends on the compiler mode |
||
{$mode objFPC} |
{$mode objFPC} |
||
Line 1,128: | Line 1,128: | ||
writeLn(isInteger(5.0 + 0.0 * i)); |
writeLn(isInteger(5.0 + 0.0 * i)); |
||
writeLn(isInteger(5 - 5 * i)); |
writeLn(isInteger(5 - 5 * i)); |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> isInteger( 2.50000000000000000000E+0001) = TRUE isInteger( 2.50000000000000000000E+0001, 0.00001) = TRUE |
<pre> isInteger( 2.50000000000000000000E+0001) = TRUE isInteger( 2.50000000000000000000E+0001, 0.00001) = TRUE |
||
Line 1,141: | Line 1,141: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,297: | Line 1,297: | ||
show("12345/5") |
show("12345/5") |
||
show(new(customIntegerType)) |
show(new(customIntegerType)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,352: | Line 1,352: | ||
Some imports for additional number types |
Some imports for additional number types |
||
< |
<syntaxhighlight lang="haskell">import Data.Decimal |
||
import Data.Ratio |
import Data.Ratio |
||
import Data.Complex</ |
import Data.Complex</syntaxhighlight> |
||
Haskell is statically typed, so in order to get universal integerness test we define a class of numbers, which may contain integers: |
Haskell is statically typed, so in order to get universal integerness test we define a class of numbers, which may contain integers: |
||
< |
<syntaxhighlight lang="haskell">class ContainsInteger a where |
||
isInteger :: a -> Bool</ |
isInteger :: a -> Bool</syntaxhighlight> |
||
Laws for this class are simple: |
Laws for this class are simple: |
||
Line 1,372: | Line 1,372: | ||
Integral numbers: |
Integral numbers: |
||
< |
<syntaxhighlight lang="haskell">instance ContainsInteger Int where isInteger _ = True |
||
instance ContainsInteger Integer where isInteger _ = True</ |
instance ContainsInteger Integer where isInteger _ = True</syntaxhighlight> |
||
Real fractional numbers: |
Real fractional numbers: |
||
< |
<syntaxhighlight lang="haskell">isIntegerF :: (Eq x, RealFrac x) => x -> Bool |
||
isIntegerF x = x == fromInteger (truncate x) |
isIntegerF x = x == fromInteger (truncate x) |
||
instance ContainsInteger Double where isInteger = isIntegerF |
instance ContainsInteger Double where isInteger = isIntegerF |
||
instance Integral i => ContainsInteger (DecimalRaw i) where isInteger = isIntegerF |
instance Integral i => ContainsInteger (DecimalRaw i) where isInteger = isIntegerF |
||
instance Integral i => ContainsInteger (Ratio i) where isInteger = isIntegerF</ |
instance Integral i => ContainsInteger (Ratio i) where isInteger = isIntegerF</syntaxhighlight> |
||
Complex numbers: |
Complex numbers: |
||
< |
<syntaxhighlight lang="haskell">instance (Eq a, Num a, ContainsInteger a) => ContainsInteger (Complex a) where |
||
isInteger z = isInteger (realPart z) && (imagPart z == 0)</ |
isInteger z = isInteger (realPart z) && (imagPart z == 0)</syntaxhighlight> |
||
'''Extra credit''' |
'''Extra credit''' |
||
Approximate integerness for fractional numbers: |
Approximate integerness for fractional numbers: |
||
< |
<syntaxhighlight lang="haskell">x ~~ eps = abs x <= eps |
||
almostInteger :: RealFrac a => a -> a -> Bool |
almostInteger :: RealFrac a => a -> a -> Bool |
||
Line 1,396: | Line 1,396: | ||
almostIntegerC :: RealFrac a => a -> Complex a -> Bool |
almostIntegerC :: RealFrac a => a -> Complex a -> Bool |
||
almostIntegerC eps z = almostInteger eps (realPart z) && (imagPart z) ~~ eps</ |
almostIntegerC eps z = almostInteger eps (realPart z) && (imagPart z) ~~ eps</syntaxhighlight> |
||
'''Testing''' |
'''Testing''' |
||
< |
<syntaxhighlight lang="haskell">tests = all (== True) |
||
[ isInteger (5 :: Integer) |
[ isInteger (5 :: Integer) |
||
, isInteger (5.0 :: Decimal) |
, isInteger (5.0 :: Decimal) |
||
Line 1,423: | Line 1,423: | ||
, not $ almostInteger 0.01 2.02 |
, not $ almostInteger 0.01 2.02 |
||
, almostIntegerC 0.001 (5.999999 :+ 0.000001) |
, almostIntegerC 0.001 (5.999999 :+ 0.000001) |
||
]</ |
]</syntaxhighlight> |
||
'''Possible use''' |
'''Possible use''' |
||
Line 1,429: | Line 1,429: | ||
Effective definition of Pithagorean triangles: |
Effective definition of Pithagorean triangles: |
||
< |
<syntaxhighlight lang="haskell">pithagoreanTriangles :: [[Integer]] |
||
pithagoreanTriangles = |
pithagoreanTriangles = |
||
[ [a, b, round c] | b <- [1..] |
[ [a, b, round c] | b <- [1..] |
||
, a <- [1..b] |
, a <- [1..b] |
||
, let c = sqrt (fromInteger (a^2 + b^2)) |
, let c = sqrt (fromInteger (a^2 + b^2)) |
||
, isInteger (c :: Double) ]</ |
, isInteger (c :: Double) ]</syntaxhighlight> |
||
<pre>λ> take 7 pithagoreanTriangles |
<pre>λ> take 7 pithagoreanTriangles |
||
[[3,4,5],[6,8,10],[5,12,13],[9,12,15],[8,15,17],[12,16,20],[15,20,25]] |
[[3,4,5],[6,8,10],[5,12,13],[9,12,15],[8,15,17],[12,16,20],[15,20,25]] |
||
Line 1,445: | Line 1,445: | ||
=={{header|J}}== |
=={{header|J}}== |
||
'''Solution''':< |
'''Solution''':<syntaxhighlight lang="j"> isInt =: (= <.) *. (= {.@+.)</syntaxhighlight> |
||
'''Alternative solution''' (remainder after diving by 1?): < |
'''Alternative solution''' (remainder after diving by 1?): <syntaxhighlight lang="j"> isInt=: (0 = 1&|) *. (0 = {:@+.)</syntaxhighlight> |
||
'''Example''':< |
'''Example''':<syntaxhighlight lang="j"> isInt 3.14 7 1.4j0 4j0 5j3 5r3 6r3 |
||
0 1 0 1 0 0 1</ |
0 1 0 1 0 0 1</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
< |
<syntaxhighlight lang="java">import java.math.BigDecimal; |
||
import java.util.List; |
import java.util.List; |
||
Line 1,551: | Line 1,551: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>25.000000 is an integer |
<pre>25.000000 is an integer |
||
Line 1,582: | Line 1,582: | ||
we shall also identify the rational numbers p/q with JSON objects that have the form: |
we shall also identify the rational numbers p/q with JSON objects that have the form: |
||
{"type": "rational", "p": p, "q": q}. |
{"type": "rational", "p": p, "q": q}. |
||
< |
<syntaxhighlight lang="jq">def is_integral: |
||
if type == "number" then . == floor |
if type == "number" then . == floor |
||
elif type == "array" then |
elif type == "array" then |
||
Line 1,591: | Line 1,591: | ||
and (.q | is_integral) |
and (.q | is_integral) |
||
and ((.p / .q) | is_integral) |
and ((.p / .q) | is_integral) |
||
end ;</ |
end ;</syntaxhighlight> |
||
'''Example''': |
'''Example''': |
||
< |
<syntaxhighlight lang="jq">( |
||
0, -1, [3,0], {"p": 4, "q": 2, "type": "rational"}, |
0, -1, [3,0], {"p": 4, "q": 2, "type": "rational"}, |
||
1.1, -1.1, [3,1], {"p": 5, "q": 2, "type": "rational"} |
1.1, -1.1, [3,1], {"p": 5, "q": 2, "type": "rational"} |
||
) | "\(.) => \(if is_integral then "integral" else "" end)"</ |
) | "\(.) => \(if is_integral then "integral" else "" end)"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="sh">$ jq -r -n -f is_integral.jq |
||
0 => integral |
0 => integral |
||
-1 => integral |
-1 => integral |
||
Line 1,606: | Line 1,606: | ||
-1.1 => |
-1.1 => |
||
[3,1] => |
[3,1] => |
||
{"p":5,"q":2,"type":"rational"} => </ |
{"p":5,"q":2,"type":"rational"} => </syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang="julia"># v0.6.0 |
||
@show isinteger(25.000000) |
@show isinteger(25.000000) |
||
Line 1,620: | Line 1,620: | ||
@show isinteger(complex(5.0, 0.0)) |
@show isinteger(complex(5.0, 0.0)) |
||
@show isinteger(complex(5, 5)) |
@show isinteger(complex(5, 5)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,635: | Line 1,635: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
As Kotlin doesn't have built in rational or complex number classes, we create 'bare bones' classes for the purposes of this task: |
As Kotlin doesn't have built in rational or complex number classes, we create 'bare bones' classes for the purposes of this task: |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
import java.math.BigInteger |
import java.math.BigInteger |
||
Line 1,702: | Line 1,702: | ||
println("$r is ${if (exact) "an" else "not an"} integer") |
println("$r is ${if (exact) "an" else "not an"} integer") |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,729: | Line 1,729: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">function isInt (x) return type(x) == "number" and x == math.floor(x) end |
||
print("Value\tInteger?") |
print("Value\tInteger?") |
||
print("=====\t========") |
print("=====\t========") |
||
local testCases = {2, 0, -1, 3.5, "String!", true} |
local testCases = {2, 0, -1, 3.5, "String!", true} |
||
for _, input in pairs(testCases) do print(input, isInt(input)) end</ |
for _, input in pairs(testCases) do print(input, isInt(input)) end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Value Integer? |
<pre>Value Integer? |
||
Line 1,747: | Line 1,747: | ||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
The built-in function IntegerQ performs the required test |
The built-in function IntegerQ performs the required test |
||
< |
<syntaxhighlight lang="mathematica">IntegerQ /@ {E, 2.4, 7, 9/2}</syntaxhighlight> |
||
{{out}}<pre>{False,False,True,False}</pre> |
{{out}}<pre>{False,False,True,False}</pre> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
Line 1,762: | Line 1,762: | ||
::– Complex: complex type; real and imaginary of any (identical) SomeFloat type |
::– Complex: complex type; real and imaginary of any (identical) SomeFloat type |
||
< |
<syntaxhighlight lang="nim">import complex, rationals, math, fenv, sugar |
||
func isInteger[T: Complex | Rational | SomeNumber](x: T; tolerance = 0f64): bool = |
func isInteger[T: Complex | Rational | SomeNumber](x: T; tolerance = 0f64): bool = |
||
Line 1,792: | Line 1,792: | ||
# Complex numbers. |
# Complex numbers. |
||
assert not (1.0 + im 1.0).isInteger |
assert not (1.0 + im 1.0).isInteger |
||
assert (5.0 + im 0.0).isInteger</ |
assert (5.0 + im 0.0).isInteger</syntaxhighlight> |
||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
< |
<syntaxhighlight lang="oorexx">/* REXX --------------------------------------------------------------- |
||
* 22.06.2014 Walter Pachl using a complex data class |
* 22.06.2014 Walter Pachl using a complex data class |
||
* ooRexx Distribution contains an elaborate complex class |
* ooRexx Distribution contains an elaborate complex class |
||
Line 1,854: | Line 1,854: | ||
::method string /* format as a string value */ |
::method string /* format as a string value */ |
||
expose real imaginary /* get the state info */ |
expose real imaginary /* get the state info */ |
||
return real'+'imaginary'i' /* format as real+imaginaryi */</ |
return real'+'imaginary'i' /* format as real+imaginaryi */</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre>1E+12+0i is an integer |
<pre>1E+12+0i is an integer |
||
Line 1,880: | Line 1,880: | ||
The operator <code>==</code> does what we want here, comparing a number mathematically regardless of how it's stored. <code>===</code> checks literal equivalence instead. |
The operator <code>==</code> does what we want here, comparing a number mathematically regardless of how it's stored. <code>===</code> checks literal equivalence instead. |
||
< |
<syntaxhighlight lang="parigp">isInteger(z)=real(z)==real(z)\1 && imag(z)==imag(z)\1; |
||
apply(isInteger, [7, I, 1.7 + I, 10.0 + I, 1.0 - 7.0 * I])</ |
apply(isInteger, [7, I, 1.7 + I, 10.0 + I, 1.0 - 7.0 * I])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>%1 = [1, 1, 0, 1, 1]</pre> |
<pre>%1 = [1, 1, 0, 1, 1]</pre> |
||
Line 1,887: | Line 1,887: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use Math::Complex; |
||
sub is_int { |
sub is_int { |
||
Line 1,902: | Line 1,902: | ||
for (5, 4.1, sqrt(2), sqrt(4), 1.1e10, 3.0-0.0*i, 4-3*i, 5.6+0*i) { |
for (5, 4.1, sqrt(2), sqrt(4), 1.1e10, 3.0-0.0*i, 4-3*i, 5.6+0*i) { |
||
printf "%20s is%s an integer\n", $_, (is_int($_) ? "" : " NOT"); |
printf "%20s is%s an integer\n", $_, (is_int($_) ? "" : " NOT"); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,921: | Line 1,921: | ||
Pascal teaches you to program without making any presumptions about the underlying system. |
Pascal teaches you to program without making any presumptions about the underlying system. |
||
That also means, you cannot properly inspect numeric properties beyond <tt>maxInt</tt> and <tt>maxReal</tt>. |
That also means, you cannot properly inspect numeric properties beyond <tt>maxInt</tt> and <tt>maxReal</tt>. |
||
< |
<syntaxhighlight lang="pascal">program integerness(output); |
||
{ determines whether a `complex` also fits in `integer` ---------------- } |
{ determines whether a `complex` also fits in `integer` ---------------- } |
||
Line 1,955: | Line 1,955: | ||
test(cmplx(5.0, 0.0)); |
test(cmplx(5.0, 0.0)); |
||
test(cmplx(5, -5)); |
test(cmplx(5, -5)); |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 2.500000000000000e+01 + 0.000000000000000e+00 𝒾 : True True |
<pre> 2.500000000000000e+01 + 0.000000000000000e+00 𝒾 : True True |
||
Line 1,971: | Line 1,971: | ||
In most cases the builtin works pretty well, with Phix automatically storing integer results as such. |
In most cases the builtin works pretty well, with Phix automatically storing integer results as such. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3.4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- false</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3.4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- false</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
The round function takes an inverted precision, so 1000000 means to the nearest 0.000001 and 100000 means the nearest 0.00001 |
The round function takes an inverted precision, so 1000000 means to the nearest 0.000001 and 100000 means the nearest 0.00001 |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">24.999999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000000</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- false</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">24.999999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000000</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- false</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">24.999999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100000</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- true</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">24.999999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100000</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- true</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
By default the inverted precision of round is 1, and that does exactly what you'd expect. |
By default the inverted precision of round is 1, and that does exactly what you'd expect. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- true</span> |
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- true</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.15</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.15</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- false</span> |
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.15</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.15</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- false</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
Technically though, -2.1e120 is way past precision limits, as next, so declaring it integer is deeply flawed... |
Technically though, -2.1e120 is way past precision limits, as next, so declaring it integer is deeply flawed... |
||
Line 1,995: | Line 1,995: | ||
digits of precision needed, that is compared to the mere 19 or so that the raw physical hardware can manage. |
digits of precision needed, that is compared to the mere 19 or so that the raw physical hardware can manage. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">+</span><span style="color: #000000;">PI</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true!!</span> |
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2.1e120</span><span style="color: #0000FF;">+</span><span style="color: #000000;">PI</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true!!</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
Phix considers both nan and inf as not an integer, and does not support complex numbers (as a primitive type, though there is a builtins/complex.e, not an autoinclude). Two final examples: |
Phix considers both nan and inf as not an integer, and does not support complex numbers (as a primitive type, though there is a builtins/complex.e, not an autoinclude). Two final examples: |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">5e-2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- false</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">5e-2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- false</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">25.000000</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true</span> |
<span style="color: #0000FF;">?</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">25.000000</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- true</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Pico Lisp scaled fixed-point numbers. Every number is stored an an Integer and a Non-integer only relative to the scale applied. For this example we assume that all numbers are generated with the same scale. This is the common case. |
Pico Lisp scaled fixed-point numbers. Every number is stored an an Integer and a Non-integer only relative to the scale applied. For this example we assume that all numbers are generated with the same scale. This is the common case. |
||
<syntaxhighlight lang="picolisp"> |
|||
<lang PicoLisp> |
|||
(de int? (N) |
(de int? (N) |
||
(= N (* 1.0 (/ N 1.0)))) #returns T or NIL |
(= N (* 1.0 (/ N 1.0)))) #returns T or NIL |
||
Line 2,023: | Line 2,023: | ||
(int? "RE") #-> "RE" -- Number expected |
(int? "RE") #-> "RE" -- Number expected |
||
(int? (*/ 2.0 1.0 3.0)) #-> NIL # 6667 is not an integer of the scale of 4, use of */ because of the scale |
(int? (*/ 2.0 1.0 3.0)) #-> NIL # 6667 is not an integer of the scale of 4, use of */ because of the scale |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
function Test-Integer ($Number) |
function Test-Integer ($Number) |
||
{ |
{ |
||
Line 2,047: | Line 2,047: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
Test-Integer 9 |
Test-Integer 9 |
||
Test-Integer 9.9 |
Test-Integer 9.9 |
||
Line 2,054: | Line 2,054: | ||
Test-Integer (New-Object System.Numerics.Complex(14,56)) |
Test-Integer (New-Object System.Numerics.Complex(14,56)) |
||
Test-Integer "abc" |
Test-Integer "abc" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,066: | Line 2,066: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">>>> def isint(f): |
||
return complex(f).imag == 0 and complex(f).real.is_integer() |
return complex(f).imag == 0 and complex(f).real.is_integer() |
||
Line 2,092: | Line 2,092: | ||
>>> isint(5-5j) |
>>> isint(5-5j) |
||
False |
False |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
Line 2,100: | Line 2,100: | ||
<code>approxint</code> is the extra credit version. Tolerance is specified to a number of decimal places. |
<code>approxint</code> is the extra credit version. Tolerance is specified to a number of decimal places. |
||
< |
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now! |
||
[ mod not ] is v-is-num ( n/d --> b ) |
[ mod not ] is v-is-num ( n/d --> b ) |
||
[ 1+ dip [ proper rot drop ] |
[ 1+ dip [ proper rot drop ] |
||
10 swap ** round v-is-num ] is approxint ( n/d n --> b )</ |
10 swap ** round v-is-num ] is approxint ( n/d n --> b )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,138: | Line 2,138: | ||
See [http://docs.racket-lang.org/reference/number-types.html?q=integer%3F#%28def._%28%28quote._~23~25kernel%29._integer~3f%29%29 documentation for <code>integer?</code>] |
See [http://docs.racket-lang.org/reference/number-types.html?q=integer%3F#%28def._%28%28quote._~23~25kernel%29._integer~3f%29%29 documentation for <code>integer?</code>] |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(require tests/eli-tester) |
(require tests/eli-tester) |
||
Line 2,190: | Line 2,190: | ||
(integer? pi) => #f |
(integer? pi) => #f |
||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
All tests pass. |
All tests pass. |
||
Line 2,200: | Line 2,200: | ||
For the extra credit task, we can add another multi candidate that checks the distance between the number and it's nearest integer, but then we'll have to handle complex numbers specially. |
For the extra credit task, we can add another multi candidate that checks the distance between the number and it's nearest integer, but then we'll have to handle complex numbers specially. |
||
<lang |
<syntaxhighlight lang="raku" line>multi is-int ($n) { $n.narrow ~~ Int } |
||
multi is-int ($n, :$tolerance!) { |
multi is-int ($n, :$tolerance!) { |
||
Line 2,216: | Line 2,216: | ||
is-int($_), |
is-int($_), |
||
is-int($_, :tolerance<0.00001>); |
is-int($_, :tolerance<0.00001>); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,233: | Line 2,233: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===version 1=== |
===version 1=== |
||
< |
<syntaxhighlight lang="rexx">/* REXX --------------------------------------------------------------- |
||
* 20.06.2014 Walter Pachl |
* 20.06.2014 Walter Pachl |
||
* 22.06.2014 WP add complex numbers such as 13-12j etc. |
* 22.06.2014 WP add complex numbers such as 13-12j etc. |
||
Line 2,320: | Line 2,320: | ||
imag=imag_sign||imag_v |
imag=imag_sign||imag_v |
||
Return real imag</ |
Return real imag</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre>3.14 isn't an integer |
<pre>3.14 isn't an integer |
||
Line 2,343: | Line 2,343: | ||
===version 1a Extra Credit=== |
===version 1a Extra Credit=== |
||
< |
<syntaxhighlight lang="rexx">/* REXX --------------------------------------------------------------- |
||
* Extra credit |
* Extra credit |
||
* Instead of using the datatype built-in function one could use this |
* Instead of using the datatype built-in function one could use this |
||
Line 2,366: | Line 2,366: | ||
Else |
Else |
||
Say x 'isn''t an integer' |
Say x 'isn''t an integer' |
||
Return</ |
Return</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>25.000000 is an integer |
<pre>25.000000 is an integer |
||
Line 2,383: | Line 2,383: | ||
Also, most REXXes have a limit on the minimum/maximum value of the power in exponentiated numbers. |
Also, most REXXes have a limit on the minimum/maximum value of the power in exponentiated numbers. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program tests if a number (possibly complex) is equivalent to an integer. */ |
||
numeric digits 3000 /*be able to handle gihugic integers. */ |
numeric digits 3000 /*be able to handle gihugic integers. */ |
||
parse arg #s /*obtain optional numbers list from CL.*/ |
parse arg #s /*obtain optional numbers list from CL.*/ |
||
Line 2,432: | Line 2,432: | ||
x= left(x, e+s) /* " " " real " " " */ |
x= left(x, e+s) /* " " " real " " " */ |
||
if isInt(z) then if z\=0 then x=. /*Not imaginary part=0? Not an integer.*/ |
if isInt(z) then if z\=0 then x=. /*Not imaginary part=0? Not an integer.*/ |
||
return /*return to the invoker of this sub. */</ |
return /*return to the invoker of this sub. */</syntaxhighlight> |
||
{{out|output|text= when using the default inputs:}} |
{{out|output|text= when using the default inputs:}} |
||
<pre> |
<pre> |
||
Line 2,470: | Line 2,470: | ||
would be considered an integer (extra blanks were added to show the number with more clarity). |
would be considered an integer (extra blanks were added to show the number with more clarity). |
||
< |
<syntaxhighlight lang="rexx">/*REXX program tests if a number (possibly complex) is equivalent to an integer. */ |
||
numeric digits 3000 /*be able to handle gihugic integers. */ |
numeric digits 3000 /*be able to handle gihugic integers. */ |
||
unaB= '++ -- -+ +-' /*a list of unary operators.*/ |
unaB= '++ -- -+ +-' /*a list of unary operators.*/ |
||
Line 2,528: | Line 2,528: | ||
x= left(x, e+s) /* " " " real " " " */ |
x= left(x, e+s) /* " " " real " " " */ |
||
if isInt(z) then if z\=0 then x=. /*Not imaginary part=0? Not an integer.*/ |
if isInt(z) then if z\=0 then x=. /*Not imaginary part=0? Not an integer.*/ |
||
return /*return to the invoker of this sub. */</ |
return /*return to the invoker of this sub. */</syntaxhighlight> |
||
{{out|output|text= when using the default inputs:}} |
{{out|output|text= when using the default inputs:}} |
||
<pre> |
<pre> |
||
Line 2,540: | Line 2,540: | ||
Testing for integerness of floats, rationals and complex numbers: |
Testing for integerness of floats, rationals and complex numbers: |
||
< |
<syntaxhighlight lang="ruby"> |
||
class Numeric |
class Numeric |
||
def to_i? |
def to_i? |
||
Line 2,554: | Line 2,554: | ||
ar.each{|num| puts "#{num} integer? #{num.to_i?}" } |
ar.each{|num| puts "#{num} integer? #{num.to_i?}" } |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,605: | Line 2,605: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">func is_int (n, tolerance=0) { |
||
!!(abs(n.real.round + n.imag - n) <= tolerance) |
!!(abs(n.real.round + n.imag - n) <= tolerance) |
||
} |
} |
||
Line 2,614: | Line 2,614: | ||
is_int(n), |
is_int(n), |
||
is_int(n, tolerance: 0.00001)) |
is_int(n, tolerance: 0.00001)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,632: | Line 2,632: | ||
The simplest way is to test whether the value is (numerically) equal to itself cast as an integer. entier() performs this cast without imposing any word-size limits (as int() or wide() would). |
The simplest way is to test whether the value is (numerically) equal to itself cast as an integer. entier() performs this cast without imposing any word-size limits (as int() or wide() would). |
||
< |
<syntaxhighlight lang="tcl">proc isNumberIntegral {x} { |
||
expr {$x == entier($x)} |
expr {$x == entier($x)} |
||
} |
} |
||
Line 2,638: | Line 2,638: | ||
foreach x {1e100 3.14 7 1.000000000000001 1000000000000000000000 -22.7 -123.000} { |
foreach x {1e100 3.14 7 1.000000000000001 1000000000000000000000 -22.7 -123.000} { |
||
puts [format "%s: %s" $x [expr {[isNumberIntegral $x] ? "yes" : "no"}]] |
puts [format "%s: %s" $x [expr {[isNumberIntegral $x] ? "yes" : "no"}]] |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,652: | Line 2,652: | ||
Note that 1.0000000000000001 will pass this integer test, because its difference from 1.0 is beyond the precision of an IEEE binary64 float. This discrepancy will be visible in other languages, but perhaps more obvious in Tcl as such a value's string representation will persist: |
Note that 1.0000000000000001 will pass this integer test, because its difference from 1.0 is beyond the precision of an IEEE binary64 float. This discrepancy will be visible in other languages, but perhaps more obvious in Tcl as such a value's string representation will persist: |
||
< |
<syntaxhighlight lang="tcl">% set a 1.0000000000000001 |
||
1.0000000000000001 |
1.0000000000000001 |
||
% expr $a |
% expr $a |
||
Line 2,659: | Line 2,659: | ||
1 |
1 |
||
% puts $a |
% puts $a |
||
1.0000000000000001</ |
1.0000000000000001</syntaxhighlight> |
||
compare Python: |
compare Python: |
||
< |
<syntaxhighlight lang="python">>>> a = 1.0000000000000001 |
||
>>> a |
>>> a |
||
1.0 |
1.0 |
||
>>> 1.0 == 1.0000000000000001 |
>>> 1.0 == 1.0000000000000001 |
||
True</ |
True</syntaxhighlight> |
||
.. this is a fairly benign illustration of why comparing floating point values with == is usually a bad idea. |
.. this is a fairly benign illustration of why comparing floating point values with == is usually a bad idea. |
||
Line 2,677: | Line 2,677: | ||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
The -2e120 example requires the use of BigRat to reliably determine whether it's an integer or not. Although the Num class can deal with numbers of this size and correctly identifies it as an integer, it would do the same if (say) 0.5 were added to it because integer determination is only reliable up to around 15 digits. |
The -2e120 example requires the use of BigRat to reliably determine whether it's an integer or not. Although the Num class can deal with numbers of this size and correctly identifies it as an integer, it would do the same if (say) 0.5 were added to it because integer determination is only reliable up to around 15 digits. |
||
< |
<syntaxhighlight lang="ecmascript">import "/big" for BigRat |
||
import "/complex" for Complex |
import "/complex" for Complex |
||
import "/rat" for Rat |
import "/rat" for Rat |
||
Line 2,713: | Line 2,713: | ||
var d = (t - t.round).abs |
var d = (t - t.round).abs |
||
Fmt.print(" $9.6f is integer? $s", t, d <= tol) |
Fmt.print(" $9.6f is integer? $s", t, d <= tol) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,749: | Line 2,749: | ||
is not an XPL0 integer that can be represented by a 32-bit signed value. |
is not an XPL0 integer that can be represented by a 32-bit signed value. |
||
< |
<syntaxhighlight lang="xpl0">real R; |
||
[Format(20, 20); |
[Format(20, 20); |
||
repeat R:= RlIn(0); |
repeat R:= RlIn(0); |
||
Line 2,757: | Line 2,757: | ||
CrLf(0); |
CrLf(0); |
||
until R = 0.; |
until R = 0.; |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,773: | Line 2,773: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
No complex type. |
No complex type. |
||
< |
<syntaxhighlight lang="zkl">T(1, 2.0,4.1,"nope",self).apply((1).isType)</syntaxhighlight> |
||
{{out}}<pre>L(True,False,False,False,False)</pre> |
{{out}}<pre>L(True,False,False,False,False)</pre> |
||
All is not golden as BigInts (lib GMP) don't consider themselves to be integers so the above test would fail. For that case: |
All is not golden as BigInts (lib GMP) don't consider themselves to be integers so the above test would fail. For that case: |
||
< |
<syntaxhighlight lang="zkl">fcn isInt(x){ try{x==x.toInt()}catch{False}} |
||
var BN=Import("zklBigNum"); |
var BN=Import("zklBigNum"); |
||
T(1, 2.0,4.1,"nope",self,BN(5)).apply(isInt);</ |
T(1, 2.0,4.1,"nope",self,BN(5)).apply(isInt);</syntaxhighlight> |
||
{{out}}<pre>L(True,True,False,False,False,True)</pre> |
{{out}}<pre>L(True,True,False,False,False,True)</pre> |
||
Note that the first float is now considered to have an integer equivalent. |
Note that the first float is now considered to have an integer equivalent. |