Test integerness: Difference between revisions

Line 1,069:
F (-3.00000000000000,3.14159265358979)
</pre>
 
=={{header|Free Pascal}}==
<lang delphi>// in FPC 3.2.0 the definition of `integer` still depends on the compiler mode
{$mode objFPC}
 
uses
// used for `isInfinite`, `isNan` and `fMod`
math,
// NB: `ucomplex`’s `complex` isn’t a simple data type as ISO 10206 requires
ucomplex;
 
{ --- determines whether a `float` value is (almost) an `integer` ------ }
function isInteger(x: float; const fuzziness: float = 0.0): Boolean;
// nested routine allows us to spare an `if … then` statement below
function fuzzyInteger: Boolean;
begin
// `x mod 1.0` uses `fMod` function from `math` unit
x := x mod 1.0;
result := (x <= fuzziness) or (x >= 1.0 - fuzziness);
end;
begin
{$push}
// just for emphasis: use lazy evaluation strategy (currently default)
{$boolEval off}
result := not isInfinite(x) and not isNan(x) and fuzzyInteger;
{$pop}
end;
 
{ --- check whether a `complex` number is (almost) in ℤ ---------------- }
function isInteger(const x: complex; const fuzziness: float = 0.0): Boolean;
begin
// you could use `isZero` from the `math` unit for a fuzzy zero
isInteger := (x.im = 0.0) and isInteger(x.re, fuzziness)
end;
 
{ --- test routine ----------------------------------------------------- }
procedure test(const x: float);
const
tolerance = 0.00001;
w = 42;
var
s: string;
begin
writeStr(s, 'isInteger(', x);
writeLn(s:w, ') = ', isInteger(x):5,
s:w, ', ', tolerance:7:5, ') = ', isInteger(x, tolerance):5);
end;
 
{ === MAIN ============================================================= }
begin
test(25.000000);
test(24.999999);
test(25.000100);
test(-2.1e120);
test(-5e-2);
test(NaN);
test(Infinity);
writeLn(isInteger(5.0 + 0.0 * i));
writeLn(isInteger(5 - 5 * i));
end.</lang>
{{out}}
<pre> isInteger( 2.50000000000000000000E+0001) = TRUE isInteger( 2.50000000000000000000E+0001, 0.00001) = TRUE
isInteger( 2.49999990000000000007E+0001) = FALSE isInteger( 2.49999990000000000007E+0001, 0.00001) = TRUE
isInteger( 2.50000999999999999994E+0001) = FALSE isInteger( 2.50000999999999999994E+0001, 0.00001) = FALSE
isInteger(-2.10000000000000000006E+0120) = TRUE isInteger(-2.10000000000000000006E+0120, 0.00001) = TRUE
isInteger(-5.00000000000000000007E-0002) = TRUE isInteger(-5.00000000000000000007E-0002, 0.00001) = TRUE
isInteger( Nan) = FALSE isInteger( Nan, 0.00001) = FALSE
isInteger( +Inf) = FALSE isInteger( +Inf, 0.00001) = FALSE
TRUE
FALSE</pre>
 
=={{header|Go}}==
Line 1,845 ⟶ 1,915:
5.6 is NOT an integer
</pre>
 
=={{header|Pascal}}==
{{works with|Extended Pascal}}
Within Pascal’s dogma, the programmer is not supposed to be concerned about internal memory representation of specific values.
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>.
<lang pascal>program integerness(output);
 
{ determines whether a `complex` also fits in `integer` ---------------- }
function isRealIntegral(protected x: complex): Boolean;
begin
{ It constitutes an error if no value for `trunc(x)` exists, }
{ thus check re(x) is in the range -maxInt..maxInt first. }
isRealIntegral := (im(x) = 0.0) and_then
(abs(re(x)) <= maxInt * 1.0) and_then
(trunc(re(x)) * 1.0 = re(x))
end;
 
{ calls isRealIntegral with zero imaginary part ------------------------ }
function isIntegral(protected x: real): Boolean;
begin
isIntegral := isRealIntegral(cmplx(x * 1.0, 0.0))
end;
 
{ Rosetta code test ---------------------------------------------------- }
procedure test(protected x: complex);
begin
writeLn(re(x), ' + ', im(x), ' 𝒾 : ',
isIntegral(re(x)), ' ', isRealIntegral(x))
end;
{ === MAIN ============================================================= }
begin
test(cmplx(25.0, 0.0));
test(cmplx(24.999999, 0.0));
test(cmplx(25.000100, 0.0));
test(cmplx(-2.1E120, 0.0));
test(cmplx(-5E-2, 0.0));
test(cmplx(5.0, 0.0));
test(cmplx(5, -5));
end.</lang>
{{out}}
<pre> 2.500000000000000e+01 + 0.000000000000000e+00 𝒾 : True True
2.499999900000000e+01 + 0.000000000000000e+00 𝒾 : False False
2.500010000000000e+01 + 0.000000000000000e+00 𝒾 : False False
-2.100000000000000e+120 + 0.000000000000000e+00 𝒾 : False False
-5.000000000000000e-02 + 0.000000000000000e+00 𝒾 : False False
5.000000000000000e+00 + 0.000000000000000e+00 𝒾 : True True
5.000000000000000e+00 + -5.000000000000000e+00 𝒾 : True False</pre>
Note that the <tt>program</tt> ''fails'' on the test case <tt>-2.1E120</tt>.
The utilized <tt>trunc</tt> function only works if a truncated <tt>integer</tt> value ''does'' exist.
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
In most cases the builtin works pretypretty well, with Phix automatically storing integer results as such.
 
<!--<lang Phix>-->
149

edits