/**************************************************************************** ** ** This file is part of GAP, a system for computational discrete algebra. ** ** Copyright of GAP belongs to its developers, whose names are too numerous ** to list here. Please refer to the COPYRIGHT file for details. ** ** SPDX-License-Identifier: GPL-2.0-or-later ** ** This file contains the functions for the macfloat package. ** ** Machine floating point values, aka macfloats, are stored as bags ** containing a 64 bit value.
*/
// glibc only declares exp10 in its headers if we define _GNU_SOURCE #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif
/**************************************************************************** ** *F TypeMacfloat( <macfloat> ) . . . . . . . . . . type of a macfloat value ** ** 'TypeMacfloat' returns the type of macfloatean values. ** ** 'TypeMacfloat' is the function in 'TypeObjFuncs' for macfloatean values.
*/ static Obj TYPE_MACFLOAT;
// helper function for printing a "decimal" representation of a macfloat // into a buffer. staticvoid
PrintMacfloatToBuf(char * buf, size_t bufsize, Double val, int precision)
{ // handle printing of NaN and infinities ourselves, to ensure // they are printed uniformly across all platforms if (isnan(val)) {
strcpy(buf, "nan");
} elseif (isinf(val)) { if (val > 0)
strcpy(buf, "inf"); else
strcpy(buf, "-inf");
} else {
snprintf(buf, bufsize, "%.*" PRINTFFORMAT, precision, val); // check if a period is in the output; this is not always the case, // e.g. if the value is an integer if (strchr(buf, '.')) return; // everything is fine // we need to insert a '.'; either at the end, or before an exponent // (e.g. "7e10" -> "7.e10"). For this we need 1 extra byte of storage, // plus of course 1 byte for the string terminator; check if the // buffer is big enough if (strlen(buf) + 2 <= bufsize) { char * loc = strchr(buf, 'e'); if (loc) {
memmove(loc + 1, loc, strlen(loc) + 1);
loc[0] = '.';
} else {
strxcat(buf, ".", bufsize);
}
}
}
}
/**************************************************************************** ** *F PrintMacfloat( <macfloat> ) . . . . . . . . . . . print a macfloat value ** ** 'PrintMacfloat' prints the macfloating value <macfloat>.
*/ staticvoid PrintMacfloat(Obj x)
{ Char buf[1024]; // TODO: should we use PRINTFDIGITS instead of 16?
PrintMacfloatToBuf(buf, sizeof(buf), VAL_MACFLOAT(x), 16);
Pr("%s", (Int)buf, 0);
}
/**************************************************************************** ** *F EqMacfloat( <macfloatL>, <macfloatR> ) . . . . . . . . . test if <macfloatL> = <macfloatR> ** ** 'EqMacfloat' returns 'True' if the two macfloatean values <macfloatL> and <macfloatR> are ** equal, and 'False' otherwise.
*/ staticInt EqMacfloat(Obj macfloatL, Obj macfloatR)
{ return VAL_MACFLOAT(macfloatL) == VAL_MACFLOAT(macfloatR);
}
/**************************************************************************** ** *F FuncSIN_MACFLOAT( <self>, <macfloat> ) . .The sin function from the math library **
*/
Double f = VAL_MACFLOAT(macfloat); if (isnan(f))
ErrorQuit("cannot convert float nan to integer", 0, 0); if (isinf(f))
ErrorQuit("cannot convert float %s to integer", (Int)(f > 0 ? "inf" : "-inf"), 0);
#ifdef HAVE_TRUNC
f = trunc(f); #else if (f >= 0.0)
f = floor(f); else
f = -floor(-f); #endif
if (fabs(f) < (Double)((Int)1 << NR_SMALL_INT_BITS)) return INTOBJ_INT((Int)f);
int str_len = (int) (log(fabs(f)) / log(16.0)) + 3;
Obj str = NEW_STRING(str_len); char *s = CSTR_STRING(str), *p = s+str_len-1; if (f < 0.0) {
f = -f;
s[0] = '-';
} while (p > s || (p == s && s[0] != '-')) { int d = (int) fmod(f,16.0);
*p-- = d < 10 ? '0'+d : 'a'+d-10;
f /= 16.0;
} return IntHexString(str);
}
static Obj FuncSTRING_DIGITS_MACFLOAT(Obj self, Obj gapprec, Obj f)
{ Char buf[1024];
Obj str; int prec = INT_INTOBJ(gapprec); if (prec > 40) // too much anyways, and would risk buffer overrun
prec = 40;
PrintMacfloatToBuf(buf, sizeof(buf), VAL_MACFLOAT(f), prec);
str = MakeString(buf); return str;
}
// allow method selection to protest against comparisons of float and int for (int t = T_INT; t <= T_CYC; t++)
EqFuncs[T_MACFLOAT][t] = EqFuncs[t][T_MACFLOAT] = EqObject;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.