Skip to content

Commit

Permalink
kernel: add some 'missing' methods for machine floats
Browse files Browse the repository at this point in the history
- A bunch of operations for floating point numbers had no implementation for
  machine floats, even though C99 provides suitable functions.

- Most of the math functions we checked for in configure are actually
  guaranteed to be there by C99. The sole exception is exp10, which is a
  non-standard extension.

- Add a bunch of super-trivial tests to ensure those new functions are
  actually callable. These are not good tests, just a bare minimum.
  • Loading branch information
fingolfin committed Apr 27, 2020
1 parent 8820125 commit 3ad5da9
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 52 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,8 @@ AC_SEARCH_LIBS([cos], [m], [], [
AC_MSG_ERROR([unable to find the cos() function])
])

dnl check for math functions
AC_CHECK_FUNCS([log2 log10 log1p exp2 expm1 exp10 trunc])
dnl check for non-standard math functions
AC_CHECK_FUNCS([exp10])

dnl pthreads
AS_IF([test "x$enable_hpcgap" = xyes],[
Expand Down
8 changes: 4 additions & 4 deletions lib/float.gd
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ end);
## <#GAPDoc Label="Float-Math-Commands">
## <ManSection>
## <Heading>Standard mathematical operations</Heading>
## <Attr Name="Cos" Arg="f"/>
## <Attr Name="Sin" Arg="f"/>
## <Attr Name="Cos" Arg="f"/>
## <Attr Name="Tan" Arg="f"/>
## <Attr Name="Sec" Arg="f"/>
## <Attr Name="Csc" Arg="f"/>
## <Attr Name="Cot" Arg="f"/>
## <Attr Name="Asin" Arg="f"/>
## <Attr Name="Acos" Arg="f"/>
## <Attr Name="Atan" Arg="f"/>
## <Attr Name="Cosh" Arg="f"/>
## <Attr Name="Sinh" Arg="f"/>
## <Attr Name="Cosh" Arg="f"/>
## <Attr Name="Tanh" Arg="f"/>
## <Attr Name="Sech" Arg="f"/>
## <Attr Name="Csch" Arg="f"/>
Expand All @@ -79,16 +79,16 @@ end);
## <Attr Name="Expm1" Arg="f"/>
## <Attr Name="CubeRoot" Arg="f"/>
## <Attr Name="Square" Arg="f"/>
## <Oper Name="Atan2" Arg="y x"/>
## <Oper Name="Hypothenuse" Arg="x y"/>
## <Attr Name="Ceil" Arg="f"/>
## <Attr Name="Floor" Arg="f"/>
## <Attr Name="Round" Arg="f"/>
## <Attr Name="Trunc" Arg="f"/>
## <Oper Name="Atan2" Arg="y x"/>
## <Attr Name="FrExp" Arg="f"/>
## <Oper Name="LdExp" Arg="f exp"/>
## <Attr Name="AbsoluteValue" Arg="f" Label="for floats"/>
## <Attr Name="Norm" Arg="f" Label="for floats"/>
## <Oper Name="Hypothenuse" Arg="x y"/>
## <Attr Name="Frac" Arg="f"/>
## <Attr Name="SinCos" Arg="f"/>
## <Attr Name="Erf" Arg="f"/>
Expand Down
41 changes: 23 additions & 18 deletions lib/ieee754.g
Original file line number Diff line number Diff line change
Expand Up @@ -61,39 +61,44 @@ InstallMethod( Int, "for macfloats", true, [ IsIEEE754FloatRep ], 0, INTFLOOR_MA
InstallMethod( Sin, "for macfloats", [ IsIEEE754FloatRep ], SIN_MACFLOAT );
InstallMethod( Cos, "for macfloats", [ IsIEEE754FloatRep ], COS_MACFLOAT );
InstallMethod( Tan, "for macfloats", [ IsIEEE754FloatRep ], TAN_MACFLOAT );
InstallMethod( Acos, "for macfloats", [ IsIEEE754FloatRep ], ACOS_MACFLOAT );
InstallMethod( Asin, "for macfloats", [ IsIEEE754FloatRep ], ASIN_MACFLOAT );
InstallMethod( Acos, "for macfloats", [ IsIEEE754FloatRep ], ACOS_MACFLOAT );
InstallMethod( Atan, "for macfloats", [ IsIEEE754FloatRep ], ATAN_MACFLOAT );
InstallMethod( Atan2, "for macfloats", [ IsIEEE754FloatRep, IsIEEE754FloatRep ], ATAN2_MACFLOAT );

InstallMethod( Sinh, "for macfloats", [ IsIEEE754FloatRep ], SINH_MACFLOAT );
InstallMethod( Cosh, "for macfloats", [ IsIEEE754FloatRep ], COSH_MACFLOAT );
InstallMethod( Tanh, "for macfloats", [ IsIEEE754FloatRep ], TANH_MACFLOAT );
InstallMethod( Asinh, "for macfloats", [ IsIEEE754FloatRep ], ASINH_MACFLOAT );
InstallMethod( Acosh, "for macfloats", [ IsIEEE754FloatRep ], ACOSH_MACFLOAT );
InstallMethod( Atanh, "for macfloats", [ IsIEEE754FloatRep ], ATANH_MACFLOAT );

InstallMethod( Log, "for macfloats", [ IsIEEE754FloatRep ], LOG_MACFLOAT );
InstallMethod( Log2, "for macfloats", [ IsIEEE754FloatRep ], LOG2_MACFLOAT );
InstallMethod( Log10, "for macfloats", [ IsIEEE754FloatRep ], LOG10_MACFLOAT );
InstallMethod( Log1p, "for macfloats", [ IsIEEE754FloatRep ], LOG1P_MACFLOAT );

InstallMethod( Exp, "for macfloats", [ IsIEEE754FloatRep ], EXP_MACFLOAT );
if IsBound(LOG2_MACFLOAT) then
InstallMethod( Log2, "for macfloats", [ IsIEEE754FloatRep ], LOG2_MACFLOAT );
fi;
if IsBound(LOG10_MACFLOAT) then
InstallMethod( Log10, "for macfloats", [ IsIEEE754FloatRep ], LOG10_MACFLOAT );
fi;
if IsBound(LOG1P_MACFLOAT) then
InstallMethod( Log1p, "for macfloats", [ IsIEEE754FloatRep ], LOG1P_MACFLOAT );
fi;
if IsBound(EXP2_MACFLOAT) then
InstallMethod( Exp2, "for macfloats", [ IsIEEE754FloatRep ], EXP2_MACFLOAT );
fi;
if IsBound(EXPM1_MACFLOAT) then
InstallMethod( Expm1, "for macfloats", [ IsIEEE754FloatRep ], EXPM1_MACFLOAT );
fi;
InstallMethod( Exp2, "for macfloats", [ IsIEEE754FloatRep ], EXP2_MACFLOAT );
InstallMethod( Expm1, "for macfloats", [ IsIEEE754FloatRep ], EXPM1_MACFLOAT );
if IsBound(EXP10_MACFLOAT) then
InstallMethod( Exp10, "for macfloats", [ IsIEEE754FloatRep ], EXP10_MACFLOAT );
fi;

InstallMethod( Sqrt, "for macfloats", [ IsIEEE754FloatRep ], SQRT_MACFLOAT );
InstallMethod( CubeRoot, "for macfloats", [ IsIEEE754FloatRep ], CBRT_MACFLOAT );

InstallMethod( Atan2, "for macfloats", [ IsIEEE754FloatRep, IsIEEE754FloatRep ], ATAN2_MACFLOAT );
InstallMethod( Hypothenuse, "for macfloats", [ IsIEEE754FloatRep, IsIEEE754FloatRep ], HYPOT_MACFLOAT );

InstallMethod( Erf, "for macfloats", [ IsIEEE754FloatRep ], ERF_MACFLOAT );
InstallMethod( Gamma, "for macfloats", [ IsIEEE754FloatRep ], GAMMA_MACFLOAT );

InstallMethod( Round, "for macfloats", [ IsIEEE754FloatRep ], RINT_MACFLOAT );
InstallMethod( Floor, "for macfloats", [ IsIEEE754FloatRep ], FLOOR_MACFLOAT );
InstallMethod( Ceil, "for macfloats", [ IsIEEE754FloatRep ], CEIL_MACFLOAT );
InstallMethod( AbsoluteValue, "for macfloats", [ IsIEEE754FloatRep ], ABS_MACFLOAT );
InstallMethod( SignFloat, "for macfloats", [ IsIEEE754FloatRep ], SIGN_MACFLOAT );
InstallMethod( SignBit, "for macfloats", [ IsIEEE754FloatRep ], SIGNBIT_MACFLOAT );
InstallMethod( Hypothenuse, "for macfloats", [ IsIEEE754FloatRep, IsIEEE754FloatRep ], HYPOT_MACFLOAT );
InstallMethod( LdExp, "for macfloat,int", [ IsIEEE754FloatRep, IsInt ], LDEXP_MACFLOAT );
InstallMethod( FrExp, "for macfloat", [ IsIEEE754FloatRep ], FREXP_MACFLOAT );
InstallMethod( EqFloat, "for macfloats", [ IsIEEE754FloatRep, IsIEEE754FloatRep ], EQ_MACFLOAT );
Expand Down
54 changes: 32 additions & 22 deletions src/macfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,34 +398,39 @@ MAKEMATHPRIMITIVE(TAN,tan)
MAKEMATHPRIMITIVE(ACOS,acos)
MAKEMATHPRIMITIVE(ASIN,asin)
MAKEMATHPRIMITIVE(ATAN,atan)

MAKEMATHPRIMITIVE(COSH,cosh)
MAKEMATHPRIMITIVE(SINH,sinh)
MAKEMATHPRIMITIVE(TANH,tanh)
MAKEMATHPRIMITIVE(ACOSH,acosh)
MAKEMATHPRIMITIVE(ASINH,asinh)
MAKEMATHPRIMITIVE(ATANH,atanh)

MAKEMATHPRIMITIVE(LOG,log)
MAKEMATHPRIMITIVE(EXP,exp)
#ifdef HAVE_LOG2
MAKEMATHPRIMITIVE(LOG2,log2)
#endif
#ifdef HAVE_LOG10
MAKEMATHPRIMITIVE(LOG10,log10)
#endif
#ifdef HAVE_LOG1P
MAKEMATHPRIMITIVE(LOG1P,log1p)
#endif
#ifdef HAVE_EXP2

MAKEMATHPRIMITIVE(EXP,exp)
MAKEMATHPRIMITIVE(EXP2,exp2)
#endif
#ifdef HAVE_EXPM1
MAKEMATHPRIMITIVE(EXPM1,expm1)
#endif
#ifdef HAVE_EXP10
MAKEMATHPRIMITIVE(EXP10,exp10)
#endif

MAKEMATHPRIMITIVE(SQRT,sqrt)
MAKEMATHPRIMITIVE(CBRT,cbrt)
MAKEMATHPRIMITIVE(RINT,rint)
MAKEMATHPRIMITIVE(FLOOR,floor)
MAKEMATHPRIMITIVE(CEIL,ceil)
MAKEMATHPRIMITIVE(ABS,fabs)
MAKEMATHPRIMITIVE2(ATAN2,atan2)
MAKEMATHPRIMITIVE2(HYPOT,hypot)

MAKEMATHPRIMITIVE(ERF,erf)
MAKEMATHPRIMITIVE(GAMMA,tgamma)


static Obj FuncSIGN_MACFLOAT(Obj self, Obj f)
{
Double vf = VAL_MACFLOAT(f);
Expand Down Expand Up @@ -529,39 +534,44 @@ static StructBagNames BagNames[] = {
static StructGVarFunc GVarFuncs [] = {
GVAR_FUNC_1ARGS(MACFLOAT_INT, int),
GVAR_FUNC_1ARGS(MACFLOAT_STRING, string),

GVAR_FUNC_1ARGS(SIN_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(COS_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(TAN_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ASIN_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ACOS_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ATAN_MACFLOAT, macfloat),

GVAR_FUNC_1ARGS(SINH_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(COSH_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(TANH_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ASINH_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ACOSH_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(ATANH_MACFLOAT, macfloat),

GVAR_FUNC_2ARGS(ATAN2_MACFLOAT, real, imag),
GVAR_FUNC_2ARGS(HYPOT_MACFLOAT, real, imag),

GVAR_FUNC_1ARGS(LOG_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(EXP_MACFLOAT, macfloat),
#ifdef HAVE_LOG2
GVAR_FUNC_1ARGS(LOG2_MACFLOAT, macfloat),
#endif
#ifdef HAVE_LOG10
GVAR_FUNC_1ARGS(LOG10_MACFLOAT, macfloat),
#endif
#ifdef HAVE_LOG1P
GVAR_FUNC_1ARGS(LOG1P_MACFLOAT, macfloat),
#endif
#ifdef HAVE_EXP2

GVAR_FUNC_1ARGS(EXP_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(EXP2_MACFLOAT, macfloat),
#endif
#ifdef HAVE_EXPM1
GVAR_FUNC_1ARGS(EXPM1_MACFLOAT, macfloat),
#endif
#ifdef HAVE_EXP10
GVAR_FUNC_1ARGS(EXP10_MACFLOAT, macfloat),
#endif

GVAR_FUNC_2ARGS(LDEXP_MACFLOAT, macfloat, int),
GVAR_FUNC_1ARGS(FREXP_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(SQRT_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(CBRT_MACFLOAT, macfloat),

GVAR_FUNC_1ARGS(ERF_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(GAMMA_MACFLOAT, macfloat),

GVAR_FUNC_1ARGS(RINT_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(INTFLOOR_MACFLOAT, macfloat),
GVAR_FUNC_1ARGS(FLOOR_MACFLOAT, macfloat),
Expand Down
91 changes: 85 additions & 6 deletions tst/testinstall/float.tst
Original file line number Diff line number Diff line change
Expand Up @@ -628,20 +628,79 @@ gap> Sin(0.);
0.
gap> Tan(0.);
0.
gap> Sec(0.);
1.
gap> Csc(0.);
inf
gap> Cot(0.);
inf
gap> Acos(1.);
0.
gap> Asin(0.);
0.
gap> Atan(0.);
0.

#
gap> Cosh(0.);
1.
gap> Sinh(0.);
0.
gap> Tanh(0.);
0.
gap> Sech(0.);
1.
gap> Csch(0.);
inf
gap> Coth(0.);
inf
gap> Asinh(0.);
0.
gap> Acosh(0.);
nan
gap> Atanh(0.);
0.

#
gap> Log(1.);
0.
gap> Log2(1.);
0.
gap> Log10(1.);
0.
gap> Log1p(0.);
0.

#
gap> Exp(0.);
1.
gap> if IsBound(Log2) then Assert(0, Log2(1.) = 0.); fi;
gap> if IsBound(Log10) then Assert(0, Log10(1.) = 0.); fi;
gap> if IsBound(Log1p) then Assert(0, Log1p(0.) = 0.); fi;
gap> if IsBound(Exp2) then Assert(0, Exp2(0.) = 1.); fi;
gap> if IsBound(Exp10) then Assert(0, Exp10(0.) = 1.); fi;
gap> if IsBound(Expm1) then Assert(0, Expm1(0.) = 0.); fi;
gap> Exp2(0.);
1.
gap> Exp10(0.);
1.
gap> Expm1(0.);
0.

#
gap> CubeRoot(0.);
0.
gap> Square(0.);
0.

#
gap> FrExp(0.);
[ 0., 0 ]
gap> LdExp(0.,0);
0.
gap> Norm(0.);
0.
gap> SinCos(0.);
[ 0., 1. ]
gap> Erf(0.);
0.
gap> #Zeta(0.); # TODO: not implemented for machine floats
gap> Gamma(1.);
1.

#
gap> Round(1.3);
Expand Down Expand Up @@ -673,6 +732,26 @@ gap> Ceil(-1.9);
gap> Ceil(-1.3);
-1.

#
gap> Trunc(1.3);
1.
gap> Trunc(1.9);
1.
gap> Trunc(-1.9);
-1.
gap> Trunc(-1.3);
-1.

#
gap> Frac(1.3);
0.3
gap> Frac(1.9);
0.9
gap> Frac(-1.9);
0.1
gap> Frac(-1.3);
0.7

#
gap> AbsoluteValue(1.3);
1.3
Expand Down

0 comments on commit 3ad5da9

Please sign in to comment.