ShortFloat.st
changeset 16670 b81b77ec431d
parent 16633 dba9ffd9c439
child 17220 614c3a1d3c73
equal deleted inserted replaced
16669:8488266c39e5 16670:b81b77ec431d
    11 "
    11 "
    12 "{ Package: 'stx:libbasic' }"
    12 "{ Package: 'stx:libbasic' }"
    13 
    13 
    14 LimitedPrecisionReal variableByteSubclass:#ShortFloat
    14 LimitedPrecisionReal variableByteSubclass:#ShortFloat
    15 	instanceVariableNames:''
    15 	instanceVariableNames:''
    16 	classVariableNames:''
    16 	classVariableNames:'DefaultPrintFormat Epsilon'
    17 	poolDictionaries:''
    17 	poolDictionaries:''
    18 	category:'Magnitude-Numbers'
    18 	category:'Magnitude-Numbers'
    19 !
    19 !
    20 
    20 
    21 !ShortFloat primitiveDefinitions!
    21 !ShortFloat primitiveDefinitions!
    29 #endif
    29 #endif
    30 
    30 
    31 #define __USE_ISOC9X 1
    31 #define __USE_ISOC9X 1
    32 #define __USE_ISOC99 1
    32 #define __USE_ISOC99 1
    33 #include <math.h>
    33 #include <math.h>
       
    34 
       
    35 #ifndef INT32
       
    36 # define INT32 int
       
    37 #endif
    34 
    38 
    35 /*
    39 /*
    36  * on some systems errno is a macro ... check for it here
    40  * on some systems errno is a macro ... check for it here
    37  */
    41  */
    38 #ifndef errno
    42 #ifndef errno
    66  * no finite(x) ?
    70  * no finite(x) ?
    67  * no isnan(x) ?
    71  * no isnan(x) ?
    68  */
    72  */
    69 # ifndef isnan
    73 # ifndef isnan
    70 #  define isnan(x)      \
    74 #  define isnan(x)      \
    71 	((((unsigned int *)(&x))[0] == 0x00000000) && \
    75         ((((unsigned int *)(&x))[0] == 0x00000000) && \
    72 	 (((unsigned int *)(&x))[1] == 0xFFF80000))
    76          (((unsigned int *)(&x))[1] == 0xFFF80000))
    73 # endif
    77 # endif
    74 
    78 
    75 # ifndef isPositiveInfinity
    79 # ifndef isPositiveInfinity
    76 #  define isPositiveInfinity(x) \
    80 #  define isPositiveInfinity(x) \
    77 	((((unsigned int *)(&x))[0] == 0x00000000) && \
    81         ((((unsigned int *)(&x))[0] == 0x00000000) && \
    78 	 (((unsigned int *)(&x))[1] == 0x7FF00000))
    82          (((unsigned int *)(&x))[1] == 0x7FF00000))
    79 # endif
    83 # endif
    80 
    84 
    81 # ifndef isNegativeInfinity
    85 # ifndef isNegativeInfinity
    82 #  define isNegativeInfinity(x) \
    86 #  define isNegativeInfinity(x) \
    83 	((((unsigned int *)(&x))[0] == 0x00000000) && \
    87         ((((unsigned int *)(&x))[0] == 0x00000000) && \
    84 	 (((unsigned int *)(&x))[1] == 0xFFF00000))
    88          (((unsigned int *)(&x))[1] == 0xFFF00000))
    85 # endif
    89 # endif
    86 
    90 
    87 # ifndef isinf
    91 # ifndef isinf
    88 #  define isinf(x) \
    92 #  define isinf(x) \
    89 	((((unsigned int *)(&x))[0] == 0x00000000) && \
    93         ((((unsigned int *)(&x))[0] == 0x00000000) && \
    90 	 ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000))
    94          ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000))
    91 # endif
    95 # endif
    92 
    96 
    93 # ifndef isfinite
    97 # ifndef isfinite
    94 #  define isfinite(x) (!isinf(x) && !isnan(x))
    98 #  define isfinite(x) (!isinf(x) && !isnan(x))
    95 # endif
    99 # endif
    96 
   100 
    97 # ifndef isnanf
   101 # ifndef isnanf
    98 #  define isnanf(x)      \
   102 #  define isnanf(x)      \
    99 	(((unsigned int *)(&x))[0] == 0xFFC00000)
   103         (((unsigned int *)(&x))[0] == 0xFFC00000)
   100 # endif
   104 # endif
   101 
   105 
   102 # ifndef isPositiveInfinityf
   106 # ifndef isPositiveInfinityf
   103 #  define isPositiveInfinityf(x)      \
   107 #  define isPositiveInfinityf(x)      \
   104 	(((unsigned int *)(&x))[0] == 0x7F800000)
   108         (((unsigned int *)(&x))[0] == 0x7F800000)
   105 # endif
   109 # endif
   106 
   110 
   107 # ifndef isNegativeInfinityf
   111 # ifndef isNegativeInfinityf
   108 #  define isNegativeInfinityf(x)      \
   112 #  define isNegativeInfinityf(x)      \
   109 	(((unsigned int *)(&x))[0] == 0xFF800000)
   113         (((unsigned int *)(&x))[0] == 0xFF800000)
   110 # endif
   114 # endif
   111 
   115 
   112 # ifndef isinff
   116 # ifndef isinff
   113 #  define isinff(x)      \
   117 #  define isinff(x)      \
   114 	((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000)
   118         ((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000)
   115 # endif
   119 # endif
   116 
   120 
   117 # ifndef isfinitef
   121 # ifndef isfinitef
   118 #  define isfinitef(x) (!isinff(x) && !isnanf(x))
   122 #  define isfinitef(x) (!isinff(x) && !isnanf(x))
   119 # endif
   123 # endif
   314 ! !
   318 ! !
   315 
   319 
   316 !ShortFloat class methodsFor:'accessing'!
   320 !ShortFloat class methodsFor:'accessing'!
   317 
   321 
   318 defaultPrintFormat
   322 defaultPrintFormat
   319     "this is fixed in ShortFloat"
   323     ^ DefaultPrintFormat
   320 
   324 !
   321     ^ '.6'
   325 
       
   326 defaultPrintFormat:aString
       
   327     DefaultPrintFormat := aString.
       
   328 !
       
   329 
       
   330 epsilon
       
   331     ^ Epsilon
   322 ! !
   332 ! !
   323 
       
   324 
   333 
   325 !ShortFloat class methodsFor:'binary storage'!
   334 !ShortFloat class methodsFor:'binary storage'!
   326 
   335 
   327 readBinaryIEEESingleFrom:aStream
   336 readBinaryIEEESingleFrom:aStream
   328     "read a float value from the binary stream, aStream,
   337     "read a float value from the binary stream, aStream,
   434     ]
   443     ]
   435 
   444 
   436     "not part of libboss, as this is also used by others (TIFFReader)"
   445     "not part of libboss, as this is also used by others (TIFFReader)"
   437 
   446 
   438     "Modified: / 23-08-2006 / 16:01:55 / cg"
   447     "Modified: / 23-08-2006 / 16:01:55 / cg"
       
   448 ! !
       
   449 
       
   450 !ShortFloat class methodsFor:'class initialization'!
       
   451 
       
   452 initialize
       
   453     Epsilon isNil ifTrue:[
       
   454         DefaultPrintFormat := '.7'.  "/ print 7 valid digits
       
   455         Epsilon := self computeEpsilon.
       
   456     ].
       
   457 
       
   458     "
       
   459      Epsilon := nil.
       
   460      self initialize
       
   461     "
   439 ! !
   462 ! !
   440 
   463 
   441 !ShortFloat class methodsFor:'constants'!
   464 !ShortFloat class methodsFor:'constants'!
   442 
   465 
   443 e
   466 e
   992      1.0 asShortFloat hash
  1015      1.0 asShortFloat hash
   993      0.5 asShortFloat hash
  1016      0.5 asShortFloat hash
   994      0.25 asShortFloat hash
  1017      0.25 asShortFloat hash
   995      0.5 hash
  1018      0.5 hash
   996      0.25 hash
  1019      0.25 hash
       
  1020     "
       
  1021 !
       
  1022 
       
  1023 isAlmostEqualTo:aNumber nEpsilon:nE 
       
  1024     "return true, if the argument, aNumber represents almost the same numeric value
       
  1025      as the receiver, false otherwise.
       
  1026 
       
  1027      nE is the number of minimal float distances, that the numbers may differ and
       
  1028      still be considered equal.
       
  1029 
       
  1030      For background information why floats need this 
       
  1031      read: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
       
  1032     "
       
  1033 
       
  1034 %{  /* NOCONTEXT */
       
  1035 
       
  1036     /*
       
  1037      * notice:
       
  1038      * the following inline code handles some common cases,
       
  1039      * and exists as an optimization, to speed up those cases.
       
  1040      *
       
  1041      * Conceptionally, (and for most other argument types),
       
  1042      * mixed arithmetic is implemented by double dispatching
       
  1043      * (see the message send at the bottom)
       
  1044      */
       
  1045 
       
  1046     INT32 ulpDiff;
       
  1047     union {
       
  1048         float f;
       
  1049         INT32 i;
       
  1050     } myself, otherFloat;
       
  1051     int nEpsilon;
       
  1052     float scaledEpsilon;
       
  1053 
       
  1054 
       
  1055     if (!__isSmallInteger(nE)) {
       
  1056         goto tryHarder;
       
  1057     }
       
  1058 
       
  1059     nEpsilon =  __intVal(nE);
       
  1060     scaledEpsilon = nEpsilon *__shortFloatVal(@global(Epsilon));
       
  1061 
       
  1062     if (__isSmallInteger(aNumber)) {
       
  1063         otherFloat.f = (float)(__intVal(aNumber));
       
  1064     } else if (aNumber == nil) {
       
  1065         RETURN(false)
       
  1066     } else if (__qIsFloatLike(aNumber)) {
       
  1067         otherFloat.f = (float)(__floatVal(aNumber));
       
  1068     } else if (__qIsShortFloat(aNumber)) {
       
  1069         otherFloat.f = (double)(__shortFloatVal(aNumber));
       
  1070     } else {
       
  1071         goto tryHarder;
       
  1072     }
       
  1073 
       
  1074     myself.f = __shortFloatVal(self);
       
  1075 
       
  1076     // Check if the numbers are really close -- needed
       
  1077     // when comparing numbers near zero (ULP method below fails for numbers near 0!).
       
  1078     if (fabs(myself.f - otherFloat.f) <= scaledEpsilon) {
       
  1079         RETURN(true);
       
  1080     }
       
  1081 
       
  1082     // if the signs differ, the numbers are different
       
  1083     if ((myself.f >= 0) != (otherFloat.f >= 0)) {
       
  1084         RETURN(false);
       
  1085     }
       
  1086 
       
  1087     // compute the difference of the 'units in the last place" ULP
       
  1088     // (if ulpDiff == 1, two floats are adjecant)
       
  1089     ulpDiff = myself.i - otherFloat.i;
       
  1090     if (ulpDiff < 0) ulpDiff = -ulpDiff;
       
  1091     if (ulpDiff <= nEpsilon) {
       
  1092         RETURN(true);
       
  1093     } else {
       
  1094         RETURN(false)
       
  1095     }
       
  1096 
       
  1097 tryHarder:;
       
  1098 %}.
       
  1099     ^ aNumber isAlmostEqualToFromShortFloat:self nEpsilon:nE
       
  1100 
       
  1101     "
       
  1102         67329.234 asShortFloat isAlmostEqualTo:67329.23400000001 nEpsilon:1
       
  1103         1.0 asShortFloat isAlmostEqualTo:1.0001 nEpsilon:1
       
  1104         1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
       
  1105         1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
   997     "
  1106     "
   998 !
  1107 !
   999 
  1108 
  1000 ~= aNumber
  1109 ~= aNumber
  1001     "return true, if the arguments value are not equal"
  1110     "return true, if the arguments value are not equal"
  1090 
  1199 
  1091     char buffer[64];
  1200     char buffer[64];
  1092     REGISTER char *cp;
  1201     REGISTER char *cp;
  1093     int len;
  1202     int len;
  1094     OBJ s;
  1203     OBJ s;
       
  1204     char *fmt;
       
  1205     char fmtBuffer[20];
       
  1206 
       
  1207     if (__isStringLike(@global(DefaultPrintFormat))) {
       
  1208         fmt = (char *) __stringVal(@global(DefaultPrintFormat));
       
  1209     } else {
       
  1210         /*
       
  1211          * in case we get called before #initialize ...
       
  1212          */
       
  1213         fmt = ".7";
       
  1214     }
       
  1215 
       
  1216     /*
       
  1217      * build a printf format string
       
  1218      */
       
  1219     fmtBuffer[0] = '%';
       
  1220     strncpy(fmtBuffer+1, fmt, 10);
       
  1221     strcat(fmtBuffer, "g");
  1095 
  1222 
  1096     /*
  1223     /*
  1097      * actually only needed on sparc: since thisContext is
  1224      * actually only needed on sparc: since thisContext is
  1098      * in a global register, which gets destroyed by printf,
  1225      * in a global register, which gets destroyed by printf,
  1099      * manually save it here - very stupid ...
  1226      * manually save it here - very stupid ...
  1100      */
  1227      */
  1101     __BEGIN_PROTECT_REGISTERS__
  1228     __BEGIN_PROTECT_REGISTERS__
  1102     len = snprintf(buffer, sizeof(buffer), "%.6g", (float)__shortFloatVal(self));
  1229     len = snprintf(buffer, sizeof(buffer), fmtBuffer, (float)__shortFloatVal(self));
  1103     __END_PROTECT_REGISTERS__
  1230     __END_PROTECT_REGISTERS__
  1104 
  1231 
  1105     if (len >= 0 && len <= sizeof(buffer)-3) {
  1232     if (len >= 0 && len <= sizeof(buffer)-3) {
  1106 	/*
  1233         /*
  1107 	 * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1234          * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1108 	 * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1235          * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1109 	 */
  1236          */
  1110 	for (cp = buffer; *cp; cp++) {
  1237         for (cp = buffer; *cp; cp++) {
  1111 	    if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
  1238             if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
  1112 	}
  1239         }
  1113 	if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1240         if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1114 	    if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1241             if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1115 		*cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1242                 *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1116 	    } else {
  1243             } else {
  1117 		*cp++ = '.';
  1244                 *cp++ = '.';
  1118 	    }
  1245             }
  1119 	    *cp++ = '0';
  1246             *cp++ = '0';
  1120 	    *cp = '\0';
  1247             *cp = '\0';
  1121 	} else {
  1248         } else {
  1122 	    if (cp && (*cp == '.')) {
  1249             if (cp && (*cp == '.')) {
  1123 		if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1250                 if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1124 		    *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1251                     *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1125 		}
  1252                 }
  1126 	    }
  1253             }
  1127 	}
  1254         }
  1128 
  1255 
  1129 	s = __MKSTRING(buffer);
  1256         s = __MKSTRING(buffer);
  1130 	if (s != nil) {
  1257         if (s != nil) {
  1131 	    RETURN (s);
  1258             RETURN (s);
  1132 	}
  1259         }
  1133     }
  1260     }
  1134 %}.
  1261 %}.
  1135     ^ self asFloat printString
  1262     ^ self asFloat printString
  1136 
  1263 
  1137     "
  1264     "
  1138 	1.234 asShortFloat printString.
  1265         1.234 asShortFloat printString.
  1139 	1.0 asShortFloat printString.
  1266         1.0 asShortFloat printString.
  1140 	1e10 asShortFloat printString.
  1267         1e10 asShortFloat printString.
  1141 	1.2e3 asShortFloat printString.
  1268         1.2e3 asShortFloat printString.
  1142 	1.2e30 asShortFloat printString.
  1269         1.2e30 asShortFloat printString.
  1143 	(1.0 uncheckedDivide:0) asShortFloat printString.
  1270         (1.0 uncheckedDivide:0) asShortFloat printString.
  1144 	(0.0 uncheckedDivide:0) asShortFloat printString.
  1271         (0.0 uncheckedDivide:0) asShortFloat printString.
  1145 	self pi printString.
  1272         self pi printString.
  1146 
  1273 
  1147 	DecimalPointCharacterForPrinting := $,.
  1274         self pi printString.
  1148 	1.234 asShortFloat printString.
  1275         DefaultPrintFormat := '.3'.
  1149 	1.0 asShortFloat printString.
  1276         self pi printString.
  1150 	1e10 asShortFloat printString.
  1277         DefaultPrintFormat := '.7'.
  1151 	1.2e3 asShortFloat printString.
  1278 
  1152 	1.2e30 asShortFloat printString.
  1279         DecimalPointCharacterForPrinting := $,.
  1153 	(1.0 uncheckedDivide:0) asShortFloat printString.
  1280         1.234 asShortFloat printString.
  1154 	(0.0 uncheckedDivide:0) asShortFloat printString.
  1281         1.0 asShortFloat printString.
  1155 	DecimalPointCharacterForPrinting := $.
  1282         1e10 asShortFloat printString.
       
  1283         1.2e3 asShortFloat printString.
       
  1284         1.2e30 asShortFloat printString.
       
  1285         (1.0 uncheckedDivide:0) asShortFloat printString.
       
  1286         (0.0 uncheckedDivide:0) asShortFloat printString.
       
  1287         DecimalPointCharacterForPrinting := $.
  1156     "
  1288     "
  1157 !
  1289 !
  1158 
  1290 
  1159 printfPrintString:formatString
  1291 printfPrintString:formatString
  1160     "non-standard: return a printed representation of the receiver
  1292     "non-standard: return a printed representation of the receiver
  1221     /*
  1353     /*
  1222      * build a printf format string
  1354      * build a printf format string
  1223      */
  1355      */
  1224 
  1356 
  1225     __BEGIN_PROTECT_REGISTERS__
  1357     __BEGIN_PROTECT_REGISTERS__
  1226 #ifdef SYSV
  1358     len = snprintf(buffer, sizeof(buffer), "%.8g", (float)__shortFloatVal(self));
  1227     len = snprintf(buffer, sizeof(buffer), "%.6lg", (double)__shortFloatVal(self));
       
  1228 #else
       
  1229     len = snprintf(buffer, sizeof(buffer), "%.6G", (double)__shortFloatVal(self));
       
  1230 #endif
       
  1231     __END_PROTECT_REGISTERS__
  1359     __END_PROTECT_REGISTERS__
  1232 
  1360 
  1233     if (len >= 0 && len < sizeof(buffer)-3) {
  1361     if (len >= 0 && len < sizeof(buffer)-3) {
  1234 	/*
  1362         /*
  1235 	 * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1363          * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1236 	 * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1364          * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1237 	 */
  1365          */
  1238 	for (cp = buffer; *cp; cp++) {
  1366         for (cp = buffer; *cp; cp++) {
  1239 	    if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
  1367             if ((*cp == '.') || (*cp == ',') || (*cp == 'E') || (*cp == 'e')) break;
  1240 	}
  1368         }
  1241 	if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1369         if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1242 	    *cp++ = '.';
  1370             *cp++ = '.';
  1243 	    *cp++ = '0';
  1371             *cp++ = '0';
  1244 	    *cp = '\0';
  1372             *cp = '\0';
  1245 	}
  1373         }
  1246 
  1374 
  1247 	s = __MKSTRING(buffer);
  1375         s = __MKSTRING(buffer);
  1248 	if (s != nil) {
  1376         if (s != nil) {
  1249 	    RETURN (s);
  1377             RETURN (s);
  1250 	}
  1378         }
  1251     }
  1379     }
  1252 %}.
  1380 %}.
  1253     "
  1381     "
  1254      memory allocation (for the new string) failed.
  1382      memory allocation (for the new string) failed.
  1255      When we arrive here, there was no memory, even after a garbage collect.
  1383      When we arrive here, there was no memory, even after a garbage collect.
  1258      Bad luck - you should increase the swap space on your machine.
  1386      Bad luck - you should increase the swap space on your machine.
  1259     "
  1387     "
  1260     ^ ObjectMemory allocationFailureSignal raise.
  1388     ^ ObjectMemory allocationFailureSignal raise.
  1261 
  1389 
  1262     "
  1390     "
  1263 	1.0 asShortFloat storeString
  1391         0.1 asShortFloat storeString
  1264 	1.234 asShortFloat storeString
  1392         ((Array new:10 withAll:0.1 asShortFloat) inject:0 into:[:v :sumSoFar| sumSoFar + v]) storeString
  1265 	1e10 asShortFloat storeString
  1393         1.0 asShortFloat storeString
  1266 	1.2e3 asShortFloat storeString
  1394         1.234 asShortFloat storeString
  1267 	1.2e30 asShortFloat storeString
  1395         1e10 asShortFloat storeString
  1268 	Float pi asShortFloat storeString
  1396         1.2e3 asShortFloat storeString
  1269 	(1.0 uncheckedDivide:0) asShortFloat storeString
  1397         1.2e30 asShortFloat storeString
  1270 	(0.0 uncheckedDivide:0) asShortFloat storeString
  1398         Float pi asShortFloat storeString
       
  1399         (1.0 uncheckedDivide:0) asShortFloat storeString
       
  1400         (0.0 uncheckedDivide:0) asShortFloat storeString
  1271 
  1401 
  1272      notice that the storeString is NOT affected by DecimalPointCharacterForPrinting:
  1402      notice that the storeString is NOT affected by DecimalPointCharacterForPrinting:
  1273 
  1403 
  1274 	DecimalPointCharacterForPrinting := $,.
  1404         DecimalPointCharacterForPrinting := $,.
  1275 	1.234 asShortFloat storeString.
  1405         1.234 asShortFloat storeString.
  1276 	1.0 asShortFloat storeString.
  1406         1.0 asShortFloat storeString.
  1277 	1e10 asShortFloat storeString.
  1407         1e10 asShortFloat storeString.
  1278 	1.2e3 asShortFloat storeString.
  1408         1.2e3 asShortFloat storeString.
  1279 	1.2e30 asShortFloat storeString.
  1409         1.2e30 asShortFloat storeString.
  1280 	(1.0 uncheckedDivide:0) asShortFloat storeString.
  1410         (1.0 uncheckedDivide:0) asShortFloat storeString.
  1281 	(0.0 uncheckedDivide:0) asShortFloat storeString.
  1411         (0.0 uncheckedDivide:0) asShortFloat storeString.
  1282 	DecimalPointCharacterForPrinting := $.
  1412         DecimalPointCharacterForPrinting := $.
  1283     "
  1413     "
  1284 ! !
  1414 ! !
  1285 
  1415 
  1286 !ShortFloat methodsFor:'private accessing'!
  1416 !ShortFloat methodsFor:'private accessing'!
  1287 
  1417 
  1366 	^ self elementBoundsError:value
  1496 	^ self elementBoundsError:value
  1367     ].
  1497     ].
  1368     ^ self indexNotIntegerOrOutOfBounds:index
  1498     ^ self indexNotIntegerOrOutOfBounds:index
  1369 ! !
  1499 ! !
  1370 
  1500 
       
  1501 !ShortFloat methodsFor:'queries'!
       
  1502 
       
  1503 nextFloat:count
       
  1504     "answer the next float count places after (or before if count is negative) myself"
       
  1505 
       
  1506 %{
       
  1507     union u {
       
  1508         float d;
       
  1509         INT32 i;
       
  1510     } this;
       
  1511 
       
  1512     if (__isSmallInteger(count)) {
       
  1513         this.d = __shortFloatVal(self);
       
  1514         if (isfinite(this.d))
       
  1515             this.i += __intVal(count);
       
  1516 
       
  1517         RETURN(__MKSFLOAT(this.d));
       
  1518     }
       
  1519 %}.
       
  1520     self primitiveFailed:#badArgument
       
  1521 
       
  1522   "
       
  1523      (1.0 asShortFloat nextFloat:2) storeString
       
  1524      (67329.234 asShortFloat nextFloat:1) storeString
       
  1525      ShortFloat NaN nextFloat:100000
       
  1526      ShortFloat infinity nextFloat:100000
       
  1527   "
       
  1528 ! !
       
  1529 
  1371 !ShortFloat methodsFor:'special access'!
  1530 !ShortFloat methodsFor:'special access'!
  1372 
  1531 
  1373 exponent
  1532 exponent
  1374     "extract a normalized floats exponent.
  1533     "extract a normalized floats exponent.
  1375      The returned value depends on the float-representation of
  1534      The returned value depends on the float-representation of
  1865 ! !
  2024 ! !
  1866 
  2025 
  1867 !ShortFloat class methodsFor:'documentation'!
  2026 !ShortFloat class methodsFor:'documentation'!
  1868 
  2027 
  1869 version
  2028 version
  1870     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.130 2014-06-25 12:20:41 stefan Exp $'
  2029     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.131 2014-06-30 19:43:16 stefan Exp $'
  1871 !
  2030 !
  1872 
  2031 
  1873 version_CVS
  2032 version_CVS
  1874     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.130 2014-06-25 12:20:41 stefan Exp $'
  2033     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.131 2014-06-30 19:43:16 stefan Exp $'
  1875 ! !
  2034 ! !
  1876 
  2035 
       
  2036 
       
  2037 ShortFloat initialize!