Skip to content

Commit e1ed107

Browse files
committed
kernel: ensure uniform printing of macfloats nan, inf, -inf
On some platforms, NaN values might be printed as `nan`, on others as `NaN`; on some, the sign of the Nan value may be printed, on other not so (and the sign of a NaN is something which highly depends on the float implementation to start with). This made it difficult to write tests which rely on the way these values are printed. Hence we now deal with these values explicitly and in a manner which produces identical results across all platforms. Fixes #2193
1 parent 76cffdc commit e1ed107

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

src/macfloat.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,39 @@ Obj TypeMacfloat (
5050
}
5151

5252

53+
// helper function for printing a "decimal" representation of a macfloat
54+
// into a buffer.
55+
static void PrintMacfloatToBuf(char *buf, size_t bufsize, Double val, int precision)
56+
{
57+
// handle printing of NaN and infinities ourselves, to ensure
58+
// they are printed uniformly across all platforms
59+
if (isnan(val)) {
60+
strcpy(buf, "nan");
61+
}
62+
else if (isinf(val)) {
63+
if (val > 0)
64+
strcpy(buf, "inf");
65+
else
66+
strcpy(buf, "-inf");
67+
}
68+
else {
69+
snprintf(buf, bufsize, "%.*" PRINTFFORMAT, precision, val);
70+
}
71+
}
72+
73+
5374
/****************************************************************************
5475
**
55-
*F PrintMacfloat( <macfloat> ) . . . . . . . . . . . . . . . . print a macfloat value
76+
*F PrintMacfloat( <macfloat> ) . . . . . . . . . . . print a macfloat value
5677
**
5778
** 'PrintMacfloat' prints the macfloating value <macfloat>.
5879
*/
59-
void PrintMacfloat (
60-
Obj x )
80+
void PrintMacfloat(Obj x)
6181
{
62-
Char buf[32];
63-
snprintf(buf, sizeof(buf), "%.16" PRINTFFORMAT, (TOPRINTFFORMAT) VAL_MACFLOAT(x));
64-
Pr("%s",(Int)buf, 0);
82+
Char buf[32];
83+
// TODO: should we use PRINTFDIGITS instead of 16?
84+
PrintMacfloatToBuf(buf, sizeof(buf), VAL_MACFLOAT(x), 16);
85+
Pr("%s", (Int)buf, 0);
6586
}
6687

6788

@@ -418,7 +439,7 @@ Obj FuncSTRING_DIGITS_MACFLOAT( Obj self, Obj gapprec, Obj f)
418439
int prec = INT_INTOBJ(gapprec);
419440
if (prec > 40) /* too much anyways, and would risk buffer overrun */
420441
prec = 40;
421-
snprintf(buf, sizeof(buf), "%.*" PRINTFFORMAT, prec, (TOPRINTFFORMAT)VAL_MACFLOAT(f));
442+
PrintMacfloatToBuf(buf, sizeof(buf), VAL_MACFLOAT(f), prec);
422443
str = MakeString(buf);
423444
return str;
424445
}

src/macfloat.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
1717

1818
#ifdef VERY_LONG_DOUBLES
1919
typedef long double /* __float128 */ Double;
20-
#define TOPRINTFFORMAT long double
2120
#define PRINTFDIGITS 20
2221
#define PRINTFFORMAT "Lg"
2322
#define STRTOD strtold
2423
#define MATH(name) name##l
2524
#else
2625
typedef double Double;
27-
#define TOPRINTFFORMAT double
2826
#define PRINTFDIGITS 16
2927
#define PRINTFFORMAT "g"
3028
#define STRTOD strtod

0 commit comments

Comments
 (0)