fallback for missing strtof with BORLAND
authorClaus Gittinger <cg@exept.de>
Mon, 25 Nov 2019 14:17:45 +0100
changeset 24976 0b3c34125507
parent 24975 fdf3a5b2f6b6
child 24977 32eaed5d822c
fallback for missing strtof with BORLAND
ShortFloat.st
--- a/ShortFloat.st	Mon Nov 25 12:14:31 2019 +0100
+++ b/ShortFloat.st	Mon Nov 25 14:17:45 2019 +0100
@@ -203,38 +203,38 @@
     Thus, STX's Float precision is not worse than that of other ST's.
 
     WARNING:
-        The layout of shortFloat instances is known by the runtime system and the compiler;
-        you may not add instance variables here.
-        Also, subclassing is complicated by the fact, that the VM creates floats/shortFloats,
-        and does some of its float-checks by an identity compare with the ShortFloat-class.
-        (i.e. your subclasses instances may not be recognized as float-like objects,
-         thus mixed mode arithmetic will always coerce them, effectively slowing things down).
-        This may be changed, to use a flag bit in the class.
+	The layout of shortFloat instances is known by the runtime system and the compiler;
+	you may not add instance variables here.
+	Also, subclassing is complicated by the fact, that the VM creates floats/shortFloats,
+	and does some of its float-checks by an identity compare with the ShortFloat-class.
+	(i.e. your subclasses instances may not be recognized as float-like objects,
+	 thus mixed mode arithmetic will always coerce them, effectively slowing things down).
+	This may be changed, to use a flag bit in the class.
 
     Mixed mode arithmetic:
-        shortFloat op shortFloat   -> shortFloat
-        shortFloat op fix         -> shortFloat
-        shortFloat op fraction    -> shortFloat
-        shortFloat op integer     -> shortFloat
-        shortFloat op longFloat   -> longFloat
-        shortFloat op float       -> float
-        shortFloat op complex     -> complex
+	shortFloat op shortFloat   -> shortFloat
+	shortFloat op fix         -> shortFloat
+	shortFloat op fraction    -> shortFloat
+	shortFloat op integer     -> shortFloat
+	shortFloat op longFloat   -> longFloat
+	shortFloat op float       -> float
+	shortFloat op complex     -> complex
 
     Representation:
-            32bit single precision IEEE floats
-            23 bit mantissa + 1 hidden bit, providing a precision of 24bits,
-            8 bit exponent,
-            6 decimal digits (approx.)
+	    32bit single precision IEEE floats
+	    23 bit mantissa + 1 hidden bit, providing a precision of 24bits,
+	    8 bit exponent,
+	    6 decimal digits (approx.)
 
     Range and Precision of Storage Formats: see LimitedPrecisionReal >> documentation
 
     [author:]
-        Claus Gittinger
+	Claus Gittinger
 
     [see also:]
-        Number
-        Float LongFloat Fraction FixedPoint Integer Complex
-        FloatArray DoubleArray
+	Number
+	Float LongFloat Fraction FixedPoint Integer Complex
+	FloatArray DoubleArray
 "
 ! !
 
@@ -264,24 +264,29 @@
      Returns garbage if the argument string is not a valid float number.
 
      This is a specially tuned entry (using a low-level C-call to atof).
-     It has been added to allow high speed string decomposition 
+     It has been added to allow high speed string decomposition
      into numbers, especially for mass-data (reading millions of floats)."
 
 %{   /* NOCONTEXT */
      if (__isStringLike(aString) && __isSmallInteger(startIndex)) {
-        char *cp = (char *)(__stringVal(aString));
-        int idx = __intVal(startIndex) - 1;
-
-        if ((unsigned)idx < __stringSize(aString)) {
+	char *cp = (char *)(__stringVal(aString));
+	int idx = __intVal(startIndex) - 1;
+
+	if ((unsigned)idx < __stringSize(aString)) {
 #ifndef NO_STRTOF
-            float strtof(const char *, char**);
-            float val = strtof(cp+idx, NULL);
+	    float strtof(const char *, char**);
+	    float val = strtof(cp+idx, NULL);
 #else
-            double atof(const char *);
-            double val = atof(cp + idx);
+# ifndef NO_STRTOD
+	    double strtod(const char *, char**);
+	    double val = strtod(cp+idx, NULL);
+# else
+	    double atof(const char *);
+	    double val = atof(cp + idx);
+# endif
 #endif
-            RETURN (__MKSFLOAT(val));
-        }
+	    RETURN (__MKSFLOAT(val));
+	}
      }
 %}.
      self primitiveFailed.
@@ -303,17 +308,17 @@
 
     "
      Time millisecondsToRun:[
-        1000000 timesRepeat:[
-            ShortFloat readFrom:'123.45'
-        ]
+	1000000 timesRepeat:[
+	    ShortFloat readFrom:'123.45'
+	]
      ]
     "
 
     "
      Time millisecondsToRun:[
-        1000000 timesRepeat:[
-            ShortFloat fastFromString:'123.45' at:1
-        ]
+	1000000 timesRepeat:[
+	    ShortFloat fastFromString:'123.45' at:1
+	]
      ]
     "
 
@@ -343,9 +348,9 @@
 
 defaultPrintFormat
     "/ by default, I will print 7 digits
-    "/  ShortFloat pi   -> 3.141593  
-    "/  Float pi        -> 3.14159265358979  
-    "/  LongFloat pi    -> 3.141592653589793239  
+    "/  ShortFloat pi   -> 3.141593
+    "/  Float pi        -> 3.14159265358979
+    "/  LongFloat pi    -> 3.141592653589793239
 
     ^ DefaultPrintFormat
 !
@@ -495,7 +500,7 @@
     "return a shortFloat which represents not-a-Number (i.e. an invalid number)"
 
     NaN isNil ifTrue:[
-        NaN := super NaN
+	NaN := super NaN
     ].
     ^ NaN
 
@@ -517,7 +522,7 @@
 !
 
 eBias
-    "Answer the exponent's bias; 
+    "Answer the exponent's bias;
      that is the offset of the zero exponent when stored"
 
     ^ 127
@@ -539,7 +544,7 @@
     "return a shortFloat which represents positive infinity (for my instances)"
 
     PositiveInfinity isNil ifTrue:[
-        PositiveInfinity := Float infinity asShortFloat
+	PositiveInfinity := Float infinity asShortFloat
     ].
     ^ PositiveInfinity
 
@@ -566,7 +571,7 @@
     "return the natural logarithm of 2 as a shortFloat"
 
     Ln2 isNil ifTrue:[
-        Ln2 := Float ln2 asShortFloat
+	Ln2 := Float ln2 asShortFloat
     ].
     ^ Ln2
 
@@ -583,7 +588,7 @@
      instead, check using isFinite or isInfinite"
 
     NegativeInfinity isNil ifTrue:[
-        NegativeInfinity := Float negativeInfinity asShortFloat
+	NegativeInfinity := Float negativeInfinity asShortFloat
     ].
     ^ NegativeInfinity
 
@@ -595,7 +600,7 @@
     "return the constant phi as ShortFloat"
 
     Phi isNil ifTrue:[
-        Phi := Float phi asShortFloat
+	Phi := Float phi asShortFloat
     ].
     ^ Phi
 !
@@ -646,7 +651,7 @@
      (i.e. the value-delta of the least significant bit)"
 
     Epsilon isNil ifTrue:[
-        Epsilon := self computeEpsilon.
+	Epsilon := self computeEpsilon.
     ].
     ^ Epsilon
 
@@ -680,7 +685,7 @@
 numBitsInExponent
     "answer the number of bits in the exponent
      This is an IEEE float, where 8 bits are available:
-        seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
+	seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
     "
 
     ^ 8
@@ -1211,7 +1216,7 @@
     "
 
     Epsilon isNil ifTrue:[
-        Epsilon := self class computeEpsilon.
+	Epsilon := self class computeEpsilon.
     ].
 
 %{  /* NOCONTEXT */
@@ -1228,31 +1233,31 @@
 
     INT32 ulpDiff;
     union {
-        float f;
-        INT32 i;
+	float f;
+	INT32 i;
     } myself, otherFloat;
     int nEpsilon;
     float scaledEpsilon;
 
     if (!__isSmallInteger(nE)) {
-        goto tryHarder;
+	goto tryHarder;
     }
 
     nEpsilon =  __intVal(nE);
     scaledEpsilon = nEpsilon *__shortFloatVal(@global(Epsilon));
 
     if (__isSmallInteger(aNumber)) {
-        otherFloat.f = (float)(__intVal(aNumber));
+	otherFloat.f = (float)(__intVal(aNumber));
     } else if (aNumber == nil) {
-        RETURN(false)
+	RETURN(false)
     } else if (__qIsFloatLike(aNumber)) {
-        otherFloat.f = (float)(__floatVal(aNumber));
+	otherFloat.f = (float)(__floatVal(aNumber));
     } else if (__qIsShortFloat(aNumber)) {
-        otherFloat.f = __shortFloatVal(aNumber);
+	otherFloat.f = __shortFloatVal(aNumber);
 //    } else if (__qIsLongFloat(aNumber)) {
 //        otherFloat.f = (float)(__longFloatVal(aNumber));
     } else {
-        goto tryHarder;
+	goto tryHarder;
     }
 
     myself.f = __shortFloatVal(self);
@@ -1261,18 +1266,18 @@
     // when comparing numbers near zero (ULP method below fails for numbers near 0!).
 # ifdef NO_ABSF
     if (fabs((double)(myself.f - otherFloat.f)) <= scaledEpsilon) {
-        RETURN(true);
+	RETURN(true);
     }
 # else
     // fprintf(stderr, "%.10f %.10f\n", fabsf(myself.f - otherFloat.f), scaledEpsilon);
     if (fabsf(myself.f - otherFloat.f) <= scaledEpsilon) {
-        RETURN(true);
+	RETURN(true);
     }
 #endif
 
     // if the signs differ, the numbers are different
     if ((myself.f >= 0) != (otherFloat.f >= 0)) {
-        RETURN(false);
+	RETURN(false);
     }
 
     // compute the difference of the 'units in the last place" ULP
@@ -1280,9 +1285,9 @@
     ulpDiff = myself.i - otherFloat.i;
     if (ulpDiff < 0) ulpDiff = -ulpDiff;
     if (ulpDiff <= nEpsilon) {
-        RETURN(true);
+	RETURN(true);
     } else {
-        RETURN(false)
+	RETURN(false)
     }
 
 tryHarder:;
@@ -1290,15 +1295,15 @@
     ^ aNumber isAlmostEqualToFromShortFloat:self nEpsilon:nE
 
     "
-        67329.234 asShortFloat isAlmostEqualTo:67329.23401 asShortFloat nEpsilon:1
-        1.0 asShortFloat isAlmostEqualTo:1.0000001 asShortFloat nEpsilon:1
-        1.0 asShortFloat isAlmostEqualTo:1.0000001  nEpsilon:1
-        1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
-        1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
-        0.0 asShortFloat isAlmostEqualTo:0.0000001 asShortFloat nEpsilon:1
-        0.0 asShortFloat isAlmostEqualTo:0.000001 asShortFloat nEpsilon:1
-        0.0 asShortFloat isAlmostEqualTo:self epsilon nEpsilon:1
-        0.0 asShortFloat - 1.192093e-07 asShortFloat
+	67329.234 asShortFloat isAlmostEqualTo:67329.23401 asShortFloat nEpsilon:1
+	1.0 asShortFloat isAlmostEqualTo:1.0000001 asShortFloat nEpsilon:1
+	1.0 asShortFloat isAlmostEqualTo:1.0000001  nEpsilon:1
+	1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
+	1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
+	0.0 asShortFloat isAlmostEqualTo:0.0000001 asShortFloat nEpsilon:1
+	0.0 asShortFloat isAlmostEqualTo:0.000001 asShortFloat nEpsilon:1
+	0.0 asShortFloat isAlmostEqualTo:self epsilon nEpsilon:1
+	0.0 asShortFloat - 1.192093e-07 asShortFloat
     "
 
     "Modified: / 10-05-2018 / 00:47:22 / stefan"
@@ -1714,24 +1719,24 @@
     int len;
 
     if (__isStringLike(formatString)) {
-        /*
-         * actually only needed on sparc: since thisContext is
-         * in a global register, which gets destroyed by printf,
-         * manually save it here - very stupid ...
-         */
-        __BEGIN_PROTECT_REGISTERS__
-
-        len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __shortFloatVal(self));
-
-        __END_PROTECT_REGISTERS__
-
-        if (len < 0) goto fail;
-        if (len >= sizeof(buffer)) goto fail;
-
-        s = __MKSTRING_L(buffer, len);
-        if (s != nil) {
-            RETURN (s);
-        }
+	/*
+	 * actually only needed on sparc: since thisContext is
+	 * in a global register, which gets destroyed by printf,
+	 * manually save it here - very stupid ...
+	 */
+	__BEGIN_PROTECT_REGISTERS__
+
+	len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __shortFloatVal(self));
+
+	__END_PROTECT_REGISTERS__
+
+	if (len < 0) goto fail;
+	if (len >= sizeof(buffer)) goto fail;
+
+	s = __MKSTRING_L(buffer, len);
+	if (s != nil) {
+	    RETURN (s);
+	}
     }
 fail: ;
 #endif /* not __SCHTEAM__ */
@@ -2014,11 +2019,11 @@
 #endif
     {
 #if defined(__i386__) && defined(__GNUC__)
-        float frac = frexpf(myVal, &exp);
-        RETURN (__MKSFLOAT(frac));
+	float frac = frexpf(myVal, &exp);
+	RETURN (__MKSFLOAT(frac));
 #else
-        double frac = frexp( (double)(myVal), &exp);
-        RETURN (__MKFLOAT(frac));
+	double frac = frexp( (double)(myVal), &exp);
+	RETURN (__MKFLOAT(frac));
 #endif
     }
 %}.
@@ -2061,9 +2066,9 @@
     ^ false
 
     "
-        1.0 asShortFloat isFinite
-        (0.0 asShortFloat uncheckedDivide: 0.0) isFinite
-        (1.0 asShortFloat uncheckedDivide: 0.0) isFinite
+	1.0 asShortFloat isFinite
+	(0.0 asShortFloat uncheckedDivide: 0.0) isFinite
+	(1.0 asShortFloat uncheckedDivide: 0.0) isFinite
     "
 !
 
@@ -2209,7 +2214,7 @@
      * ST-80 (and X3J20) returns integer.
      */
     if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
-        RETURN ( __mkSmallInteger( (INT) fVal ) );
+	RETURN ( __mkSmallInteger( (INT) fVal ) );
     }
     __qMKSFLOAT(val, fVal);
 %}.
@@ -2263,7 +2268,7 @@
      * ST-80 (and X3J20) returns integer.
      */
     if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
-        RETURN ( __mkSmallInteger( (INT) fVal ) );
+	RETURN ( __mkSmallInteger( (INT) fVal ) );
     }
     __qMKSFLOAT(val, fVal);
 %}.
@@ -2358,22 +2363,22 @@
     fVal = __shortFloatVal(self);
 #if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
     if (fVal < 0.0) {
-        fVal = ceilf(fVal - (float)0.5);
+	fVal = ceilf(fVal - (float)0.5);
     } else {
-        fVal = floorf(fVal + (float)0.5);
+	fVal = floorf(fVal + (float)0.5);
     }
 #else
     if (fVal < 0.0) {
-        fVal = (float)ceil((double)fVal - 0.5);
+	fVal = (float)ceil((double)fVal - 0.5);
     } else {
-        fVal = (float)floor((double)fVal + 0.5);
+	fVal = (float)floor((double)fVal + 0.5);
     }
 #endif
     /*
      * ST-80 (and X3J20) return integer.
      */
     if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
-        RETURN ( __mkSmallInteger( (INT) fVal ) );
+	RETURN ( __mkSmallInteger( (INT) fVal ) );
     }
     __qMKSFLOAT(val, fVal);
 %}.
@@ -2403,15 +2408,15 @@
     fVal = __shortFloatVal(self);
 #if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
     if (fVal < 0.0) {
-        fVal = ceilf(fVal - (float)0.5);
+	fVal = ceilf(fVal - (float)0.5);
     } else {
-        fVal = floorf(fVal + (float)0.5);
+	fVal = floorf(fVal + (float)0.5);
     }
 #else
     if (fVal < 0.0) {
-        fVal = (float)ceil((double)fVal - 0.5);
+	fVal = (float)ceil((double)fVal - 0.5);
     } else {
-        fVal = (float)floor((double)fVal + 0.5);
+	fVal = (float)floor((double)fVal + 0.5);
     }
 #endif
     __qMKSFLOAT(v, fVal);
@@ -2446,22 +2451,22 @@
     fVal = __shortFloatVal(self);
 #if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
     if (fVal < 0.0) {
-        fVal = ceilf(fVal);
+	fVal = ceilf(fVal);
     } else {
-        fVal = floorf(fVal);
+	fVal = floorf(fVal);
     }
 #else
     if (fVal < 0.0) {
-        fVal = (float)ceil((double)fVal);
+	fVal = (float)ceil((double)fVal);
     } else {
-        fVal = (float)floor((double)fVal);
+	fVal = (float)floor((double)fVal);
     }
 #endif
     /*
      * ST-80 (and X3J20) returns integer.
      */
     if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
-        RETURN ( __mkSmallInteger( (INT) fVal ) );
+	RETURN ( __mkSmallInteger( (INT) fVal ) );
     }
     __qMKSFLOAT(val, fVal);
 %}.
@@ -2489,15 +2494,15 @@
     fVal = __shortFloatVal(self);
 #if (defined(__i386__) || defined(xx__x86_64__)) && defined(__GNUC__)
     if (fVal < 0.0) {
-        fVal = ceilf(fVal);
+	fVal = ceilf(fVal);
     } else {
-        fVal = floorf(fVal);
+	fVal = floorf(fVal);
     }
 #else
     if (fVal < 0.0) {
-        fVal = (float)ceil((double)fVal);
+	fVal = (float)ceil((double)fVal);
     } else {
-        fVal = (float)floor((double)fVal);
+	fVal = (float)floor((double)fVal);
     }
 #endif
     __qMKSFLOAT(v, fVal);