Test integerness: Difference between revisions
Content added Content deleted
(→{{header|Quackery}}: bug fix) |
(add →Free Pascal: and →Pascal) |
||
Line 1,069: | Line 1,069: | ||
F (-3.00000000000000,3.14159265358979) |
F (-3.00000000000000,3.14159265358979) |
||
</pre> |
</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}}== |
=={{header|Go}}== |
||
Line 1,845: | Line 1,915: | ||
5.6 is NOT an integer |
5.6 is NOT an integer |
||
</pre> |
</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}}== |
=={{header|Phix}}== |
||
{{libheader|Phix/basics}} |
{{libheader|Phix/basics}} |
||
In most cases the builtin works |
In most cases the builtin works pretty well, with Phix automatically storing integer results as such. |
||
<!--<lang Phix>--> |
<!--<lang Phix>--> |