Test integerness: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 150:
+1.2345678901234567890123400000000000e +23_+0.0000000000000000000000000000000000e +0 is integral
</pre>
 
=={{header|AWK}}==
<lang AWK>
Line 261 ⟶ 262:
</pre>
 
=={{header|C++ sharp|C#}}==
<lang cpp>
#include <complex>
#include <math.h>
#include <iostream>
 
template<class Type>
struct Precision
{
public:
static Type GetEps()
{
return eps;
}
 
static void SetEps(Type e)
{
eps = e;
}
 
private:
static Type eps;
};
 
template<class Type> Type Precision<Type>::eps = static_cast<Type>(1E-7);
 
template<class DigType>
bool IsDoubleEqual(DigType d1, DigType d2)
{
return (fabs(d1 - d2) < Precision<DigType>::GetEps());
}
 
template<class DigType>
DigType IntegerPart(DigType value)
{
return (value > 0) ? floor(value) : ceil(value);
}
 
template<class DigType>
DigType FractionPart(DigType value)
{
return fabs(IntegerPart<DigType>(value) - value);
}
 
template<class Type>
bool IsInteger(const Type& value)
{
return false;
}
 
#define GEN_CHECK_INTEGER(type) \
template<> \
bool IsInteger<type>(const type& value) \
{ \
return true; \
}
 
#define GEN_CHECK_CMPL_INTEGER(type) \
template<> \
bool IsInteger<std::complex<type> >(const std::complex<type>& value) \
{ \
type zero = type(); \
return value.imag() == zero; \
}
 
#define GEN_CHECK_REAL(type) \
template<> \
bool IsInteger<type>(const type& value) \
{ \
type zero = type(); \
return IsDoubleEqual<type>(FractionPart<type>(value), zero); \
}
 
#define GEN_CHECK_CMPL_REAL(type) \
template<> \
bool IsInteger<std::complex<type> >(const std::complex<type>& value) \
{ \
type zero = type(); \
return IsDoubleEqual<type>(value.imag(), zero); \
}
 
#define GEN_INTEGER(type) \
GEN_CHECK_INTEGER(type) \
GEN_CHECK_CMPL_INTEGER(type)
 
#define GEN_REAL(type) \
GEN_CHECK_REAL(type) \
GEN_CHECK_CMPL_REAL(type)
 
 
GEN_INTEGER(char)
GEN_INTEGER(unsigned char)
GEN_INTEGER(short)
GEN_INTEGER(unsigned short)
GEN_INTEGER(int)
GEN_INTEGER(unsigned int)
GEN_INTEGER(long)
GEN_INTEGER(unsigned long)
GEN_INTEGER(long long)
GEN_INTEGER(unsigned long long)
 
GEN_REAL(float)
GEN_REAL(double)
GEN_REAL(long double)
 
template<class Type>
inline void TestValue(const Type& value)
{
std::cout << "Value: " << value << " of type: " << typeid(Type).name() << " is integer - " << std::boolalpha << IsInteger(value) << std::endl;
}
 
int main()
{
char c = -100;
unsigned char uc = 200;
short s = c;
unsigned short us = uc;
int i = s;
unsigned int ui = us;
long long ll = i;
unsigned long long ull = ui;
 
std::complex<unsigned int> ci1(2, 0);
std::complex<int> ci2(2, 4);
std::complex<int> ci3(-2, 4);
std::complex<unsigned short> cs1(2, 0);
std::complex<short> cs2(2, 4);
std::complex<short> cs3(-2, 4);
 
std::complex<double> cd1(2, 0);
std::complex<float> cf1(2, 4);
std::complex<double> cd2(-2, 4);
 
float f1 = 1.0;
float f2 = -2.0;
float f3 = -2.4f;
float f4 = 1.23e-5f;
float f5 = 1.23e-10f;
double d1 = f5;
 
TestValue(c);
TestValue(uc);
TestValue(s);
TestValue(us);
TestValue(i);
TestValue(ui);
TestValue(ll);
TestValue(ull);
 
TestValue(ci1);
TestValue(ci2);
TestValue(ci3);
TestValue(cs1);
TestValue(cs2);
TestValue(cs3);
 
TestValue(cd1);
TestValue(cd2);
TestValue(cf1);
 
TestValue(f1);
TestValue(f2);
TestValue(f3);
TestValue(f4);
TestValue(f5);
std::cout << "Set float precision: 1e-15f\n";
Precision<float>::SetEps(1e-15f);
TestValue(f5);
TestValue(d1);
return 0;
}
</lang>
 
{{out}}
<pre>
Value: Ь of type: char is integer - true
Value: ╚ of type: unsigned char is integer - true
Value: -100 of type: short is integer - true
Value: 200 of type: unsigned short is integer - true
Value: -100 of type: int is integer - true
Value: 200 of type: unsigned int is integer - true
Value: -100 of type: __int64 is integer - true
Value: 200 of type: unsigned __int64 is integer - true
Value: (2,0) of type: class std::complex<unsigned int> is integer - true
Value: (2,4) of type: class std::complex<int> is integer - false
Value: (-2,4) of type: class std::complex<int> is integer - false
Value: (2,0) of type: class std::complex<unsigned short> is integer - true
Value: (2,4) of type: class std::complex<short> is integer - false
Value: (-2,4) of type: class std::complex<short> is integer - false
Value: (2,0) of type: class std::complex<double> is integer - true
Value: (-2,4) of type: class std::complex<double> is integer - false
Value: (2,4) of type: class std::complex<float> is integer - false
Value: 1 of type: float is integer - true
Value: -2 of type: float is integer - true
Value: -2.4 of type: float is integer - false
Value: 1.23e-05 of type: float is integer - false
Value: 1.23e-10 of type: float is integer - true
Set float precision: 1e-15f
Value: 1.23e-10 of type: float is integer - false
Value: 1.23e-10 of type: double is integer - true
</pre>
 
=={{header|C#}}==
 
 
Line 684 ⟶ 483:
Another test < Y /N > . . .
 
</pre>
 
=={{header|C++}}==
<lang cpp>
#include <complex>
#include <math.h>
#include <iostream>
 
template<class Type>
struct Precision
{
public:
static Type GetEps()
{
return eps;
}
 
static void SetEps(Type e)
{
eps = e;
}
 
private:
static Type eps;
};
 
template<class Type> Type Precision<Type>::eps = static_cast<Type>(1E-7);
 
template<class DigType>
bool IsDoubleEqual(DigType d1, DigType d2)
{
return (fabs(d1 - d2) < Precision<DigType>::GetEps());
}
 
template<class DigType>
DigType IntegerPart(DigType value)
{
return (value > 0) ? floor(value) : ceil(value);
}
 
template<class DigType>
DigType FractionPart(DigType value)
{
return fabs(IntegerPart<DigType>(value) - value);
}
 
template<class Type>
bool IsInteger(const Type& value)
{
return false;
}
 
#define GEN_CHECK_INTEGER(type) \
template<> \
bool IsInteger<type>(const type& value) \
{ \
return true; \
}
 
#define GEN_CHECK_CMPL_INTEGER(type) \
template<> \
bool IsInteger<std::complex<type> >(const std::complex<type>& value) \
{ \
type zero = type(); \
return value.imag() == zero; \
}
 
#define GEN_CHECK_REAL(type) \
template<> \
bool IsInteger<type>(const type& value) \
{ \
type zero = type(); \
return IsDoubleEqual<type>(FractionPart<type>(value), zero); \
}
 
#define GEN_CHECK_CMPL_REAL(type) \
template<> \
bool IsInteger<std::complex<type> >(const std::complex<type>& value) \
{ \
type zero = type(); \
return IsDoubleEqual<type>(value.imag(), zero); \
}
 
#define GEN_INTEGER(type) \
GEN_CHECK_INTEGER(type) \
GEN_CHECK_CMPL_INTEGER(type)
 
#define GEN_REAL(type) \
GEN_CHECK_REAL(type) \
GEN_CHECK_CMPL_REAL(type)
 
 
GEN_INTEGER(char)
GEN_INTEGER(unsigned char)
GEN_INTEGER(short)
GEN_INTEGER(unsigned short)
GEN_INTEGER(int)
GEN_INTEGER(unsigned int)
GEN_INTEGER(long)
GEN_INTEGER(unsigned long)
GEN_INTEGER(long long)
GEN_INTEGER(unsigned long long)
 
GEN_REAL(float)
GEN_REAL(double)
GEN_REAL(long double)
 
template<class Type>
inline void TestValue(const Type& value)
{
std::cout << "Value: " << value << " of type: " << typeid(Type).name() << " is integer - " << std::boolalpha << IsInteger(value) << std::endl;
}
 
int main()
{
char c = -100;
unsigned char uc = 200;
short s = c;
unsigned short us = uc;
int i = s;
unsigned int ui = us;
long long ll = i;
unsigned long long ull = ui;
 
std::complex<unsigned int> ci1(2, 0);
std::complex<int> ci2(2, 4);
std::complex<int> ci3(-2, 4);
std::complex<unsigned short> cs1(2, 0);
std::complex<short> cs2(2, 4);
std::complex<short> cs3(-2, 4);
 
std::complex<double> cd1(2, 0);
std::complex<float> cf1(2, 4);
std::complex<double> cd2(-2, 4);
 
float f1 = 1.0;
float f2 = -2.0;
float f3 = -2.4f;
float f4 = 1.23e-5f;
float f5 = 1.23e-10f;
double d1 = f5;
 
TestValue(c);
TestValue(uc);
TestValue(s);
TestValue(us);
TestValue(i);
TestValue(ui);
TestValue(ll);
TestValue(ull);
 
TestValue(ci1);
TestValue(ci2);
TestValue(ci3);
TestValue(cs1);
TestValue(cs2);
TestValue(cs3);
 
TestValue(cd1);
TestValue(cd2);
TestValue(cf1);
 
TestValue(f1);
TestValue(f2);
TestValue(f3);
TestValue(f4);
TestValue(f5);
std::cout << "Set float precision: 1e-15f\n";
Precision<float>::SetEps(1e-15f);
TestValue(f5);
TestValue(d1);
return 0;
}
</lang>
 
{{out}}
<pre>
Value: Ь of type: char is integer - true
Value: ╚ of type: unsigned char is integer - true
Value: -100 of type: short is integer - true
Value: 200 of type: unsigned short is integer - true
Value: -100 of type: int is integer - true
Value: 200 of type: unsigned int is integer - true
Value: -100 of type: __int64 is integer - true
Value: 200 of type: unsigned __int64 is integer - true
Value: (2,0) of type: class std::complex<unsigned int> is integer - true
Value: (2,4) of type: class std::complex<int> is integer - false
Value: (-2,4) of type: class std::complex<int> is integer - false
Value: (2,0) of type: class std::complex<unsigned short> is integer - true
Value: (2,4) of type: class std::complex<short> is integer - false
Value: (-2,4) of type: class std::complex<short> is integer - false
Value: (2,0) of type: class std::complex<double> is integer - true
Value: (-2,4) of type: class std::complex<double> is integer - false
Value: (2,4) of type: class std::complex<float> is integer - false
Value: 1 of type: float is integer - true
Value: -2 of type: float is integer - true
Value: -2.4 of type: float is integer - false
Value: 1.23e-05 of type: float is integer - false
Value: 1.23e-10 of type: float is integer - true
Set float precision: 1e-15f
Value: 1.23e-10 of type: float is integer - false
Value: 1.23e-10 of type: double is integer - true
</pre>
 
Line 1,646 ⟶ 1,647:
String! false
true false</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
The built-in function IntegerQ performs the required test
<lang Mathematica>IntegerQ /@ {E, 2.4, 7, 9/2}</lang>
{{out}}<pre>{False,False,True,False}</pre>
 
=={{header|ooRexx}}==
Line 1,729 ⟶ 1,735:
3+0i is an integer</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
The built-in function IntegerQ performs the required test
<lang Mathematica>IntegerQ /@ {E, 2.4, 7, 9/2}</lang>
{{out}}<pre>{False,False,True,False}</pre>
=={{header|PARI/GP}}==
 
Line 1,771 ⟶ 1,773:
4-3i is NOT an integer
5.6 is NOT an integer
</pre>
 
=={{header|Perl 6}}==
 
In Perl 6, all numeric types have a method called <tt>narrow</tt>, which returns an object with the same value but of the most appropriate type. So we can just check if ''that'' object is an <tt>Int</tt>. This works even with floats with large exponents, because the <tt>Int</tt> type supports arbitrarily large integers.
 
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 perl6>multi is-int ($n) { $n.narrow ~~ Int }
 
multi is-int ($n, :$tolerance!) {
abs($n.round - $n) <= $tolerance
}
 
multi is-int (Complex $n, :$tolerance!) {
is-int($n.re, :$tolerance) && abs($n.im) < $tolerance
}
 
# Testing:
 
for 25.000000, 24.999999, 25.000100, -2.1e120, -5e-2, Inf, NaN, 5.0+0.0i, 5-5i {
printf "%-7s %-9s %-5s %-5s\n", .^name, $_,
is-int($_),
is-int($_, :tolerance<0.00001>);
}</lang>
 
{{out}}
<pre>
Rat 25 True True
Rat 24.999999 False True
Rat 25.0001 False False
Num -2.1e+120 True True
Num -0.05 False False
Num Inf False False
Num NaN False False
Complex 5+0i True True
Complex 5-5i False False
</pre>
 
Line 1,978 ⟶ 1,943:
</lang>
All tests pass.
 
=={{header|Raku}}==
(formerly Perl 6)
 
In Perl 6, all numeric types have a method called <tt>narrow</tt>, which returns an object with the same value but of the most appropriate type. So we can just check if ''that'' object is an <tt>Int</tt>. This works even with floats with large exponents, because the <tt>Int</tt> type supports arbitrarily large integers.
 
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 perl6>multi is-int ($n) { $n.narrow ~~ Int }
 
multi is-int ($n, :$tolerance!) {
abs($n.round - $n) <= $tolerance
}
 
multi is-int (Complex $n, :$tolerance!) {
is-int($n.re, :$tolerance) && abs($n.im) < $tolerance
}
 
# Testing:
 
for 25.000000, 24.999999, 25.000100, -2.1e120, -5e-2, Inf, NaN, 5.0+0.0i, 5-5i {
printf "%-7s %-9s %-5s %-5s\n", .^name, $_,
is-int($_),
is-int($_, :tolerance<0.00001>);
}</lang>
 
{{out}}
<pre>
Rat 25 True True
Rat 24.999999 False True
Rat 25.0001 False False
Num -2.1e+120 True True
Num -0.05 False False
Num Inf False False
Num NaN False False
Complex 5+0i True True
Complex 5-5i False False
</pre>
 
=={{header|REXX}}==
10,327

edits