--- a/ShortFloat.st Tue Feb 04 21:09:59 2014 +0100
+++ b/ShortFloat.st Wed Apr 01 10:20:10 2015 +0100
@@ -11,9 +11,11 @@
"
"{ Package: 'stx:libbasic' }"
+"{ NameSpace: Smalltalk }"
+
LimitedPrecisionReal variableByteSubclass:#ShortFloat
instanceVariableNames:''
- classVariableNames:''
+ classVariableNames:'DefaultPrintFormat Epsilon'
poolDictionaries:''
category:'Magnitude-Numbers'
!
@@ -32,6 +34,10 @@
#define __USE_ISOC99 1
#include <math.h>
+#ifndef INT32
+# define INT32 int
+#endif
+
/*
* on some systems errno is a macro ... check for it here
*/
@@ -68,26 +74,26 @@
*/
# ifndef isnan
# define isnan(x) \
- ((((unsigned int *)(&x))[0] == 0x00000000) && \
- (((unsigned int *)(&x))[1] == 0xFFF80000))
+ ((((unsigned int *)(&x))[0] == 0x00000000) && \
+ (((unsigned int *)(&x))[1] == 0xFFF80000))
# endif
# ifndef isPositiveInfinity
# define isPositiveInfinity(x) \
- ((((unsigned int *)(&x))[0] == 0x00000000) && \
- (((unsigned int *)(&x))[1] == 0x7FF00000))
+ ((((unsigned int *)(&x))[0] == 0x00000000) && \
+ (((unsigned int *)(&x))[1] == 0x7FF00000))
# endif
# ifndef isNegativeInfinity
# define isNegativeInfinity(x) \
- ((((unsigned int *)(&x))[0] == 0x00000000) && \
- (((unsigned int *)(&x))[1] == 0xFFF00000))
+ ((((unsigned int *)(&x))[0] == 0x00000000) && \
+ (((unsigned int *)(&x))[1] == 0xFFF00000))
# endif
# ifndef isinf
# define isinf(x) \
- ((((unsigned int *)(&x))[0] == 0x00000000) && \
- ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000))
+ ((((unsigned int *)(&x))[0] == 0x00000000) && \
+ ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000))
# endif
# ifndef isfinite
@@ -96,22 +102,22 @@
# ifndef isnanf
# define isnanf(x) \
- (((unsigned int *)(&x))[0] == 0xFFC00000)
+ (((unsigned int *)(&x))[0] == 0xFFC00000)
# endif
# ifndef isPositiveInfinityf
# define isPositiveInfinityf(x) \
- (((unsigned int *)(&x))[0] == 0x7F800000)
+ (((unsigned int *)(&x))[0] == 0x7F800000)
# endif
# ifndef isNegativeInfinityf
# define isNegativeInfinityf(x) \
- (((unsigned int *)(&x))[0] == 0xFF800000)
+ (((unsigned int *)(&x))[0] == 0xFF800000)
# endif
# ifndef isinff
# define isinff(x) \
- ((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000)
+ ((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000)
# endif
# ifndef isfinitef
@@ -175,7 +181,7 @@
documentation
"
ShortFloats represent rational numbers with limited precision.
- They use the C-compilers 'float' format, which is usually the IEE single float format.
+ They use the C-compilers 'float' format, which is usually the IEEE single float format.
In contrast to Floats (which use the C-compilers 64bit 'double' format),
ShortFloats give you 32 bit floats.
@@ -185,42 +191,39 @@
to bothe visualWorks and other smalltalks, which use C-doubles for the Float class.
Thus, STX's Float precision is not worse than that of other ST's.
- This may change in one of the next versions (at least on machines, which
- provide different float and double types in their C-compiler.
-
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 IEE floats
- 23 bit mantissa,
- 8 bit exponent,
- 6 decimal digits (approx)
+ 32bit single precision IEEE floats
+ 23 bit mantissa,
+ 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
"
! !
@@ -243,6 +246,10 @@
%}
!
+coerce:aNumber
+ ^ aNumber asShortFloat.
+!
+
fastFromString:aString at:startIndex
"return the next ShortFloat from the string starting at startIndex.
No spaces are skipped.
@@ -310,56 +317,28 @@
r.i = __unsignedLongIntVal( anInteger );
RETURN( __MKSFLOAT(r.f) );
%}
-!
-
-readFrom:aStringOrStream
- "read a shortFloat from a string"
-
- |num|
-
- num := super readFrom:aStringOrStream onError:[self error:'conversion error for: ' , self name].
- num notNil ifTrue:[
- num := num asShortFloat
- ].
- ^ num
"
- ShortFloat readFrom:'0.1'
- ShortFloat readFrom:'0'
- ShortFloat readFrom:'.123'
- ShortFloat readFrom:'-.123'
- ShortFloat readFrom:'1e4'
+ ShortFloat fromIEEE32Bit:(#[64 73 15 219] asInteger)
"
-
- "Modified: / 7.1.1998 / 16:17:59 / cg"
!
-readFrom:aStringOrStream onError:exceptionBlock
- "read a shortFloat from a string"
-
- |num|
-
- num := super readFrom:aStringOrStream onError:nil.
- num isNil ifTrue:[
- ^ exceptionBlock value
- ].
- ^ num asShortFloat
-
- "
- ShortFloat readFrom:'0.1'
- ShortFloat readFrom:'0'
- ShortFloat readFrom:'.123'
- "
-
- "Modified: / 7.1.1998 / 16:17:59 / cg"
+fromNumber:aNumber
+ ^aNumber asShortFloat
! !
!ShortFloat class methodsFor:'accessing'!
defaultPrintFormat
- "this is fixed in ShortFloat"
+ ^ DefaultPrintFormat
+!
- ^ '.6'
+defaultPrintFormat:aString
+ DefaultPrintFormat := aString.
+!
+
+epsilon
+ ^ Epsilon
! !
!ShortFloat class methodsFor:'binary storage'!
@@ -478,6 +457,20 @@
"Modified: / 23-08-2006 / 16:01:55 / cg"
! !
+!ShortFloat class methodsFor:'class initialization'!
+
+initialize
+ Epsilon isNil ifTrue:[
+ DefaultPrintFormat := '.7'. "/ print 7 valid digits
+ Epsilon := self computeEpsilon.
+ ].
+
+ "
+ Epsilon := nil.
+ self initialize
+ "
+! !
+
!ShortFloat class methodsFor:'constants'!
e
@@ -486,12 +479,31 @@
^ Float e asShortFloat
!
+emax
+ "Answer the maximum exponent for this representation."
+
+ ^127
+!
+
+emin
+ "Answer the minimum exponent for this representation."
+
+ ^-126
+!
+
pi
"return the constant pi as ShortFloat"
^ Float pi asShortFloat
!
+powersOfTwo
+ "/ sigh: cannot have PoersOfTwo as class nstvar (yet)
+ PowersOfTwo notNil ifTrue: [^PowersOfTwo].
+ PowersOfTwo := self newPowersOfTwo.
+ ^PowersOfTwo
+!
+
unity
"return the neutral element for multiplication (1.0) as ShortFloat"
@@ -523,24 +535,6 @@
"Modified: 23.4.1996 / 16:00:23 / cg"
!
-isIEEEFormat
- "return true, if this machine represents floats in IEEE format.
- Currently, no support is provided for non-ieee machines
- to convert their floats into this (which is only relevant,
- if such a machine wants to send floats as binary to some other
- machine).
- Machines with non-IEEE format are VAXed and IBM370-type systems
- (among others). Today, most systems use IEEE format floats."
-
-%{
-#ifdef __s390__
- RETURN(false);
-#endif
-%}.
-
- ^ true "/ this may be a lie
-!
-
numBitsInExponent
"answer the number of bits in the exponent
This is an IEEE float, where 8 bits are available:
@@ -1036,6 +1030,92 @@
"
!
+isAlmostEqualTo:aNumber nEpsilon:nE
+ "return true, if the argument, aNumber represents almost the same numeric value
+ as the receiver, false otherwise.
+
+ nE is the number of minimal float distances, that the numbers may differ and
+ still be considered equal.
+
+ For background information why floats need this
+ read: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
+ "
+
+%{ /* NOCONTEXT */
+
+ /*
+ * notice:
+ * the following inline code handles some common cases,
+ * and exists as an optimization, to speed up those cases.
+ *
+ * Conceptionally, (and for most other argument types),
+ * mixed arithmetic is implemented by double dispatching
+ * (see the message send at the bottom)
+ */
+
+ INT32 ulpDiff;
+ union {
+ float f;
+ INT32 i;
+ } myself, otherFloat;
+ int nEpsilon;
+ float scaledEpsilon;
+
+
+ if (!__isSmallInteger(nE)) {
+ goto tryHarder;
+ }
+
+ nEpsilon = __intVal(nE);
+ scaledEpsilon = nEpsilon *__shortFloatVal(@global(Epsilon));
+
+ if (__isSmallInteger(aNumber)) {
+ otherFloat.f = (float)(__intVal(aNumber));
+ } else if (aNumber == nil) {
+ RETURN(false)
+ } else if (__qIsFloatLike(aNumber)) {
+ otherFloat.f = (float)(__floatVal(aNumber));
+ } else if (__qIsShortFloat(aNumber)) {
+ otherFloat.f = (double)(__shortFloatVal(aNumber));
+ } else {
+ goto tryHarder;
+ }
+
+ myself.f = __shortFloatVal(self);
+
+ // Check if the numbers are really close -- needed
+ // when comparing numbers near zero (ULP method below fails for numbers near 0!).
+ if (fabs(myself.f - otherFloat.f) <= scaledEpsilon) {
+ RETURN(true);
+ }
+
+ // if the signs differ, the numbers are different
+ if ((myself.f >= 0) != (otherFloat.f >= 0)) {
+ RETURN(false);
+ }
+
+ // compute the difference of the 'units in the last place" ULP
+ // (if ulpDiff == 1, two floats are adjecant)
+ ulpDiff = myself.i - otherFloat.i;
+ if (ulpDiff < 0) ulpDiff = -ulpDiff;
+ if (ulpDiff <= nEpsilon) {
+ RETURN(true);
+ } else {
+ RETURN(false)
+ }
+
+tryHarder:;
+%}.
+ ^ aNumber isAlmostEqualToFromShortFloat:self nEpsilon:nE
+
+ "
+ 67329.234 asShortFloat isAlmostEqualTo:67329.23400000001 nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:1.0001 nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
+ "
+!
+
~= aNumber
"return true, if the arguments value are not equal"
@@ -1125,12 +1205,66 @@
LimitedPrecisonReal and its subclasses use #printString instead of
#printOn: as basic print mechanism."
+ ^ self printStringWithFormat:DefaultPrintFormat
+
+ "
+ 1.234 asShortFloat printString.
+ 1.0 asShortFloat printString.
+ 1e10 asShortFloat printString.
+ 1.2e3 asShortFloat printString.
+ 1.2e30 asShortFloat printString.
+ (1.0 uncheckedDivide:0) asShortFloat printString.
+ (0.0 uncheckedDivide:0) asShortFloat printString.
+ self pi printString.
+
+ self pi printString.
+ DefaultPrintFormat := '.3'.
+ self pi printString.
+ DefaultPrintFormat := '.7'.
+
+ DecimalPointCharacterForPrinting := $,.
+ 1.234 asShortFloat printString.
+ 1.0 asShortFloat printString.
+ 1e10 asShortFloat printString.
+ 1.2e3 asShortFloat printString.
+ 1.2e30 asShortFloat printString.
+ (1.0 uncheckedDivide:0) asShortFloat printString.
+ (0.0 uncheckedDivide:0) asShortFloat printString.
+ DecimalPointCharacterForPrinting := $.
+ "
+!
+
+printStringWithFormat:format
+ "return a printed representation of the receiver;
+ fmt must be of the form: .nn, where nn is the number of digits.
+ To print 6 valid digits, use printStringWithFormat:'.6'
+ For Floats, the default used in printString, is 15 (because its a double);
+ for ShortFloats, it is 6 (because it is a float)"
+
%{ /* NOCONTEXT */
char buffer[64];
REGISTER char *cp;
int len;
OBJ s;
+ char *fmt;
+ char fmtBuffer[20];
+
+ if (__isStringLike(format)) {
+ fmt = (char *) __stringVal(format);
+ } else {
+ /*
+ * in case we get called with garbage...
+ */
+ fmt = ".7";
+ }
+
+ /*
+ * build a printf format string
+ */
+ fmtBuffer[0] = '%';
+ strncpy(fmtBuffer+1, fmt, 10);
+ strcat(fmtBuffer, "g");
/*
* actually only needed on sparc: since thisContext is
@@ -1138,60 +1272,66 @@
* manually save it here - very stupid ...
*/
__BEGIN_PROTECT_REGISTERS__
- len = snprintf(buffer, sizeof(buffer), "%.6g", (float)__shortFloatVal(self));
+ len = snprintf(buffer, sizeof(buffer), fmtBuffer, (float)__shortFloatVal(self));
__END_PROTECT_REGISTERS__
if (len >= 0 && len <= sizeof(buffer)-3) {
- /*
- * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
- * (i.e. look if string contains '.' or 'e' and append '.0' if not)
- */
- for (cp = buffer; *cp; cp++) {
- if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
- }
- if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
- if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
- *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
- } else {
- *cp++ = '.';
- }
- *cp++ = '0';
- *cp = '\0';
- } else {
- if (cp && (*cp == '.')) {
- if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
- *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
- }
- }
- }
+ /*
+ * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
+ * (i.e. look if string contains '.' or 'e' and append '.0' if not)
+ */
+ for (cp = buffer; *cp; cp++) {
+ if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
+ }
+ if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
+ if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
+ *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
+ } else {
+ *cp++ = '.';
+ }
+ *cp++ = '0';
+ *cp = '\0';
+ } else {
+ if (cp && (*cp == '.')) {
+ if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
+ *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
+ }
+ }
+ }
- s = __MKSTRING(buffer);
- if (s != nil) {
- RETURN (s);
- }
+ s = __MKSTRING(buffer);
+ if (s != nil) {
+ RETURN (s);
+ }
}
%}.
^ self asFloat printString
"
- 1.234 asShortFloat printString.
- 1.0 asShortFloat printString.
- 1e10 asShortFloat printString.
- 1.2e3 asShortFloat printString.
- 1.2e30 asShortFloat printString.
- (1.0 uncheckedDivide:0) asShortFloat printString.
- (0.0 uncheckedDivide:0) asShortFloat printString.
- self pi printString.
+ 1.234 asShortFloat printString.
+ ShortFloat pi printString.
+ 1.0 asShortFloat printString.
+ 1e10 asShortFloat printString.
+ 1.2e3 asShortFloat printString.
+ 1.2e30 asShortFloat printString.
+ (1.0 uncheckedDivide:0) asShortFloat printString.
+ (0.0 uncheckedDivide:0) asShortFloat printString.
+ self pi printString.
- DecimalPointCharacterForPrinting := $,.
- 1.234 asShortFloat printString.
- 1.0 asShortFloat printString.
- 1e10 asShortFloat printString.
- 1.2e3 asShortFloat printString.
- 1.2e30 asShortFloat printString.
- (1.0 uncheckedDivide:0) asShortFloat printString.
- (0.0 uncheckedDivide:0) asShortFloat printString.
- DecimalPointCharacterForPrinting := $.
+ self pi printString.
+ DefaultPrintFormat := '.3'.
+ self pi printString.
+ DefaultPrintFormat := '.7'.
+
+ DecimalPointCharacterForPrinting := $,.
+ 1.234 asShortFloat printString.
+ 1.0 asShortFloat printString.
+ 1e10 asShortFloat printString.
+ 1.2e3 asShortFloat printString.
+ 1.2e30 asShortFloat printString.
+ (1.0 uncheckedDivide:0) asShortFloat printString.
+ (0.0 uncheckedDivide:0) asShortFloat printString.
+ DecimalPointCharacterForPrinting := $.
"
!
@@ -1262,31 +1402,27 @@
*/
__BEGIN_PROTECT_REGISTERS__
-#ifdef SYSV
- len = snprintf(buffer, sizeof(buffer), "%.6lg", (double)__shortFloatVal(self));
-#else
- len = snprintf(buffer, sizeof(buffer), "%.6G", (double)__shortFloatVal(self));
-#endif
+ len = snprintf(buffer, sizeof(buffer), "%.8g", (float)__shortFloatVal(self));
__END_PROTECT_REGISTERS__
if (len >= 0 && len < sizeof(buffer)-3) {
- /*
- * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
- * (i.e. look if string contains '.' or 'e' and append '.0' if not)
- */
- for (cp = buffer; *cp; cp++) {
- if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
- }
- if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
- *cp++ = '.';
- *cp++ = '0';
- *cp = '\0';
- }
+ /*
+ * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
+ * (i.e. look if string contains '.' or 'e' and append '.0' if not)
+ */
+ for (cp = buffer; *cp; cp++) {
+ if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
+ }
+ if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
+ *cp++ = '.';
+ *cp++ = '0';
+ *cp = '\0';
+ }
- s = __MKSTRING(buffer);
- if (s != nil) {
- RETURN (s);
- }
+ s = __MKSTRING(buffer);
+ if (s != nil) {
+ RETURN (s);
+ }
}
%}.
"
@@ -1299,26 +1435,28 @@
^ ObjectMemory allocationFailureSignal raise.
"
- 1.0 asShortFloat storeString
- 1.234 asShortFloat storeString
- 1e10 asShortFloat storeString
- 1.2e3 asShortFloat storeString
- 1.2e30 asShortFloat storeString
- Float pi asShortFloat storeString
- (1.0 uncheckedDivide:0) asShortFloat storeString
- (0.0 uncheckedDivide:0) asShortFloat storeString
+ 0.1 asShortFloat storeString
+ ((Array new:10 withAll:0.1 asShortFloat) inject:0 into:[:v :sumSoFar| sumSoFar + v]) storeString
+ 1.0 asShortFloat storeString
+ 1.234 asShortFloat storeString
+ 1e10 asShortFloat storeString
+ 1.2e3 asShortFloat storeString
+ 1.2e30 asShortFloat storeString
+ Float pi asShortFloat storeString
+ (1.0 uncheckedDivide:0) asShortFloat storeString
+ (0.0 uncheckedDivide:0) asShortFloat storeString
notice that the storeString is NOT affected by DecimalPointCharacterForPrinting:
- DecimalPointCharacterForPrinting := $,.
- 1.234 asShortFloat storeString.
- 1.0 asShortFloat storeString.
- 1e10 asShortFloat storeString.
- 1.2e3 asShortFloat storeString.
- 1.2e30 asShortFloat storeString.
- (1.0 uncheckedDivide:0) asShortFloat storeString.
- (0.0 uncheckedDivide:0) asShortFloat storeString.
- DecimalPointCharacterForPrinting := $.
+ DecimalPointCharacterForPrinting := $,.
+ 1.234 asShortFloat storeString.
+ 1.0 asShortFloat storeString.
+ 1e10 asShortFloat storeString.
+ 1.2e3 asShortFloat storeString.
+ 1.2e30 asShortFloat storeString.
+ (1.0 uncheckedDivide:0) asShortFloat storeString.
+ (0.0 uncheckedDivide:0) asShortFloat storeString.
+ DecimalPointCharacterForPrinting := $.
"
! !
@@ -1407,6 +1545,35 @@
^ self indexNotIntegerOrOutOfBounds:index
! !
+!ShortFloat methodsFor:'queries'!
+
+nextFloat:count
+ "answer the next float count places after (or before if count is negative) myself"
+
+%{
+ union u {
+ float d;
+ INT32 i;
+ } this;
+
+ if (__isSmallInteger(count)) {
+ this.d = __shortFloatVal(self);
+ if (isfinite(this.d))
+ this.i += __intVal(count);
+
+ RETURN(__MKSFLOAT(this.d));
+ }
+%}.
+ self primitiveFailed:#badArgument
+
+ "
+ (1.0 asShortFloat nextFloat:2) storeString
+ (67329.234 asShortFloat nextFloat:1) storeString
+ ShortFloat NaN nextFloat:100000
+ ShortFloat infinity nextFloat:100000
+ "
+! !
+
!ShortFloat methodsFor:'special access'!
exponent
@@ -1525,12 +1692,15 @@
isNegativeZero
"many systems have two float.Pnt zeros"
-%{
-#if defined(__i386__) && defined(linux)
- RETURN ((__ByteArrayInstPtr(self)->ba_element[sizeof(float)-1] == 128) ? true : false );
+%{ /* NOCONTEXT */
+#if defined(__BORLANDC__)
+ union { float f; int i; } __u;
+ __u.f = __shortFloatVal(self);
+ RETURN ( (__u.f == 0.0 && __u.i < 0) ? true : false );
+#else
+ RETURN ( (__shortFloatVal(self) == 0.0 && signbit(__shortFloatVal(self)) != 0) ? true : false );
#endif
%}.
- ^ super isNegativeZero
"
0.0 asShortFloat isNegativeZero
@@ -1539,12 +1709,23 @@
!
negative
- "return true if the receiver is less than zero"
+ "return true if the receiver is less than zero.
+ -0.0 is positive for now."
%{ /* NOCONTEXT */
- RETURN ( (__shortFloatVal(self) < 0.0) ? true : false );
+ RETURN ( __shortFloatVal(self) < 0.0 ? true : false );
+ // RETURN ( signbit(__shortFloatVal(self)) != 0 ? true : false );
%}.
+
+ "
+ 0.0 asShortFloat negative
+ -0.0 asShortFloat negative
+ 1.0 asShortFloat negative
+ -1.0 asShortFloat negative
+ (1.0 uncheckedDivide: 0.0) asShortFloat negative
+ (-1.0 uncheckedDivide: 0.0) asShortFloat negative
+ "
!
numberOfBits
@@ -1565,12 +1746,23 @@
!
positive
- "return true if the receiver is greater or equal to zero"
+ "return true if the receiver is greater or equal to zero
+ 0.0 and -0.0 are positive for now."
%{ /* NOCONTEXT */
- RETURN ( (__shortFloatVal(self) >= 0.0) ? true : false );
-%}
+ RETURN ( __shortFloatVal(self) >= 0.0 ? true : false );
+// RETURN ( (signbit(__shortFloatVal(self)) == 0 ? true : false ) );
+%}.
+
+ "
+ 0.0 asShortFloat positive
+ -0.0 asShortFloat positive
+ 1.0 asShortFloat positive
+ -1.0 asShortFloat positive
+ (1.0 uncheckedDivide: 0.0) asShortFloat positive
+ (-1.0 uncheckedDivide: 0.0) asShortFloat positive
+ "
!
strictlyPositive
@@ -1906,10 +2098,12 @@
!ShortFloat class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.128 2013-03-31 20:47:22 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.140 2015-03-25 19:18:18 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.128 2013-03-31 20:47:22 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.140 2015-03-25 19:18:18 cg Exp $'
! !
+
+ShortFloat initialize!