LimitedPrecisionReal.st
changeset 21852 5b5848e2afcc
parent 21842 ce71ca0b5cb8
child 21853 9486a8f34bff
--- a/LimitedPrecisionReal.st	Tue Jun 20 12:22:31 2017 +0200
+++ b/LimitedPrecisionReal.st	Tue Jun 20 12:23:11 2017 +0200
@@ -1139,16 +1139,27 @@
 !
 
 exponent
-    "extract a normalized floats exponent.
+    "extract a normalized float's exponent.
+     This is a fallback for systems which do not provide frexp in their math lib,
+     als also for error reporting (NaN or Inf).
      The returned value depends on the float-representation of
      the underlying machine and is therefore highly unportable.
      This is not for general use.
      This assumes that the mantissa is normalized to
-     0.5 .. 1.0 and the floats value is mantissa * 2^exp"
+     0.5 .. 1.0 and the float's value is mantissa * 2^exp"
 
     |shifty expPart exp numBytes numBitsInMantissa maskMantissa numBitsInExponent maskExponent
      biasExponent numIntegerBits fractionPart|
 
+    (self isNaN or:[self isInfinite]) ifTrue:[
+        ^ self class
+            raise:#domainErrorSignal
+            receiver:self
+            selector:#exponent
+            arguments:#()
+            errorString:'bad receiver (Inf or NaN) in exponent'
+    ].    
+
     "Extract the bits of an IEEE anySize float "
     numBytes := self basicSize.
     numBitsInMantissa := self class numBitsInMantissa. maskMantissa := (1 bitShift:numBitsInMantissa) - 1.
@@ -1188,6 +1199,8 @@
      0.25 exponent2     -1
      0.00000011111 exponent2  -23 
     "
+
+    "Modified (comment): / 20-06-2017 / 11:34:29 / cg"
 !
 
 fractionalPart
@@ -1204,6 +1217,54 @@
 
     "Modified: / 28.10.1998 / 17:10:12 / cg"
     "Created: / 28.10.1998 / 17:10:32 / cg"
+!
+
+mantissa
+    "extract a normalized float's mantissa.
+     This is a fallback for systems which do not provide frexp in their math lib,
+     als also for error reporting (NaN or Inf)."
+     
+    |shifty expPart numBytes numBitsInMantissa maskMantissa numBitsInExponent maskExponent
+     biasExponent numIntegerBits fractionPart|
+
+    (self isNaN or:[self isInfinite]) ifTrue:[
+        ^ self class
+            raise:#domainErrorSignal
+            receiver:self
+            selector:#mantissa
+            arguments:#()
+            errorString:'bad receiver (Inf or NaN) in mantissa'
+    ].    
+
+    "Extract the bits of an IEEE anySize float "
+    numBytes := self basicSize.
+    numBitsInMantissa := self class numBitsInMantissa. maskMantissa := (1 bitShift:numBitsInMantissa) - 1.
+    numBitsInExponent := self class numBitsInExponent. maskExponent := (1 bitShift:numBitsInExponent) - 1.
+    numIntegerBits := self class numBitsInIntegerPart.
+    biasExponent := maskExponent bitShift:-1.
+
+    shifty := LargeInteger basicNew numberOfDigits:numBytes.
+    UninterpretedBytes isBigEndian ifTrue:[
+        1 to:numBytes do:[:i | shifty digitAt:(numBytes+1-i) put:(self basicAt:i)].
+    ] ifFalse:[
+        1 to:numBytes do:[:i | shifty digitAt:i put:(self basicAt:i)].
+    ].
+
+    " Extract the sign and the biased exponent "
+    expPart := (shifty bitShift:numBitsInMantissa negated) bitAnd: maskExponent.
+
+    " Extract fractional part; answer 0 if this is a true 0.0 value "
+    fractionPart := shifty bitAnd:maskMantissa.
+    ^ fractionPart.
+    
+    "
+     0.3 asFloat mantissa  
+     0.3 asShortFloat mantissa  
+     0.3 asLongFloat mantissa  
+     0.3 asQDouble mantissa  
+    "
+
+    "Created: / 20-06-2017 / 11:36:51 / cg"
 ! !
 
 !LimitedPrecisionReal methodsFor:'comparing'!