--- a/QuadFloat.st Fri Jun 07 03:27:38 2019 +0200
+++ b/QuadFloat.st Fri Jun 07 09:40:32 2019 +0200
@@ -1848,6 +1848,47 @@
return uZ.f;
}
+bool
+f128_isNan( float128_t a) {
+ int_fast32_t expA;
+ struct uint128 sigA;
+ uint_fast64_t uiA64, uiA0;
+ union ui128_f128 uA;
+
+ uA.f = a;
+ uiA64 = uA.ui.v64;
+ uiA0 = uA.ui.v0;
+ return isNaNF128UI( uiA64, uiA0 );
+// expA = expF128UI64( uiA64 );
+// sigA.v64 = fracF128UI64( uiA64 );
+// sigA.v0 = uiA0;
+//
+// if ( expA == 0x7FFF ) {
+// if ( sigA.v64 | sigA.v0 ) return 1;
+// }
+// return 0;
+}
+
+bool
+f128_isInf( float128_t a) {
+ int_fast32_t expA;
+ struct uint128 sigA;
+ uint_fast64_t uiA64, uiA0;
+ union ui128_f128 uA;
+
+ uA.f = a;
+ uiA64 = uA.ui.v64;
+ uiA0 = uA.ui.v0;
+ expA = expF128UI64( uiA64 );
+ sigA.v64 = fracF128UI64( uiA64 );
+ sigA.v0 = uiA0;
+
+ if ( expA == 0x7FFF ) {
+ if ( sigA.v64 == 0 ) return 1;
+ }
+ return 0;
+}
+
static bool
f128_eq( float128_t a, float128_t b )
{
@@ -1869,7 +1910,7 @@
) {
softfloat_raiseFlags( softfloat_flag_invalid );
}
- return false;
+ return 0;
}
return
(uiA0 == uiB0)
@@ -1895,7 +1936,7 @@
uiB0 = uB.ui.v0;
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
softfloat_raiseFlags( softfloat_flag_invalid );
- return false;
+ return 0;
}
signA = signF128UI64( uiA64 );
signB = signF128UI64( uiB64 );
@@ -1942,7 +1983,9 @@
documentation
"
QuadFloats represent rational numbers with limited precision
- and are mapped to IEEE quadruple precision format (128bit).
+ and are mapped to IEEE quadruple precision format (128bit),
+ also called binary128.
+
If the underlying cpu supports them natively, the machine format (long double) is
used. Otherwise, a software emulation is done, which is much slower.
Thus only use them, if you really need the additional precision;
@@ -1961,8 +2004,8 @@
on x86 CPUs, this is emulated and slow.
Mixed mode arithmetic:
- quadFloat op anyFloat -> longFloat
- longFloat op complex -> complex
+ quadFloat op anyFloat -> quadFloat
+ anyFloat op quadFloat -> quadFloat
Range and precision of storage formats: see LimitedPrecisionReal >> documentation
@@ -2096,7 +2139,7 @@
"return the neutral element for multiplication (1.0) as QuadFloat"
QuadFloatOne isNil ifTrue:[
- QuadFloatOne := 1.0 asQuadFloat.
+ QuadFloatOne := 1.0 asQuadFloat.
].
^ QuadFloatOne
@@ -2113,13 +2156,53 @@
!QuadFloat class methodsFor:'queries'!
+isFinite
+ "return true, if the receiver is a finite float
+ i.e. not NaN and not infinite."
+
+%{ /* NOCONTEXT */
+ float128_t myVal;
+
+ myVal = __quadFloatVal(self);
+ RETURN (f128_isInf(myVal) ? true : false)
+%}.
+
+ "
+ 1.0 isFinite
+ self NaN isFinite
+ self infinity isFinite
+ (0.0 uncheckedDivide: 0.0) isFinite
+ (1.0 uncheckedDivide: 0.0) isFinite
+ "
+!
+
+isNaN
+ "return true, if the receiver is a finite float
+ i.e. not NaN and not infinite."
+
+%{ /* NOCONTEXT */
+ float128_t myVal;
+
+ myVal = __quadFloatVal(self);
+ RETURN (f128_isNan(myVal) ? true : false)
+%}.
+
+ "
+ 1.0 isFinite
+ self NaN isFinite
+ self infinity isFinite
+ (0.0 uncheckedDivide: 0.0) isFinite
+ (1.0 uncheckedDivide: 0.0) isFinite
+ "
+!
+
numBitsInMantissa
"answer the number of bits in the mantissa
the hidden bit is not counted here:
This is an 128bit quadfloat,
- where 112 bits are available in the mantissa:
- seeeeeee eeeeeeee mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm...
+ where 112 bits are available in the mantissa:
+ seeeeeee eeeeeeee mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm...
"
^ 112
@@ -2298,4 +2381,3 @@
version_CVS
^ '$Header$'
! !
-