Float.st
changeset 12478 e8051030cda6
parent 12423 a3c777accbb0
child 12583 4271383b5862
equal deleted inserted replaced
12477:0c213a90642b 12478:e8051030cda6
   281      returns garbage if the argument string is not a valid float number.
   281      returns garbage if the argument string is not a valid float number.
   282      It has been added to allow high speed string decomposition into numbers,
   282      It has been added to allow high speed string decomposition into numbers,
   283      especially for mass-data."
   283      especially for mass-data."
   284 
   284 
   285 %{   /* NOCONTEXT */
   285 %{   /* NOCONTEXT */
   286      if (__isString(aString) && __isSmallInteger(startIndex)) {
   286      if (__isStringLike(aString) && __isSmallInteger(startIndex)) {
   287 	char *cp = (char *)(__stringVal(aString));
   287         char *cp = (char *)(__stringVal(aString));
   288 	int idx = __intVal(startIndex) - 1;
   288         int idx = __intVal(startIndex) - 1;
   289 	double atof();
   289         double atof();
   290 	double val;
   290         double val;
   291 
   291 
   292 	if ((unsigned)idx < __stringSize(aString)) {
   292         if ((unsigned)idx < __stringSize(aString)) {
   293 	    val = atof(cp + idx);
   293             val = atof(cp + idx);
   294 	    RETURN (__MKFLOAT(val));
   294             RETURN (__MKFLOAT(val));
   295 	}
   295         }
   296      }
   296      }
   297 %}.
   297 %}.
   298      self primitiveFailed.
   298      self primitiveFailed.
   299 
   299 
   300     "
   300     "
   310      Float fastFromString:'12345' at:6
   310      Float fastFromString:'12345' at:6
   311      Float fastFromString:'12345' at:0
   311      Float fastFromString:'12345' at:0
   312      Float fastFromString:'hello123.45E4' at:1
   312      Float fastFromString:'hello123.45E4' at:1
   313 
   313 
   314      Time millisecondsToRun:[
   314      Time millisecondsToRun:[
   315 	100000 timesRepeat:[
   315         100000 timesRepeat:[
   316 	    Float readFrom:'123.45'
   316             Float readFrom:'123.45'
   317 	]
   317         ]
   318      ]
   318      ]
   319     "
   319     "
   320 
   320 
   321     "
   321     "
   322      Time millisecondsToRun:[
   322      Time millisecondsToRun:[
   323 	100000 timesRepeat:[
   323         100000 timesRepeat:[
   324 	    Float fastFromString:'123.45' at:1
   324             Float fastFromString:'123.45' at:1
   325 	]
   325         ]
   326      ]
   326      ]
   327     "
   327     "
   328 
       
   329 
       
   330 !
   328 !
   331 
   329 
   332 fromVAXFloatBytes:b1 b2:b2 b3:b3 b4:b4
   330 fromVAXFloatBytes:b1 b2:b2 b3:b3 b4:b4
   333     "creates a double, given the four vax float bytes to an ieee double.
   331     "creates a double, given the four vax float bytes to an ieee double.
   334      For NaNs and Infinity, nil is returned.
   332      For NaNs and Infinity, nil is returned.
  1456     OBJ s;
  1454     OBJ s;
  1457     char *fmt;
  1455     char *fmt;
  1458     char fmtBuffer[20];
  1456     char fmtBuffer[20];
  1459     int len;
  1457     int len;
  1460 
  1458 
  1461     if (__isString(@global(DefaultPrintFormat))) {
  1459     if (__isStringLike(@global(DefaultPrintFormat))) {
  1462 	fmt = (char *) __stringVal(@global(DefaultPrintFormat));
  1460         fmt = (char *) __stringVal(@global(DefaultPrintFormat));
  1463     } else {
  1461     } else {
  1464 	/*
  1462         /*
  1465 	 * in case we get called before #initialize ...
  1463          * in case we get called before #initialize ...
  1466 	 */
  1464          */
  1467 	fmt = ".6";
  1465         fmt = ".6";
  1468     }
  1466     }
  1469 
  1467 
  1470     /*
  1468     /*
  1471      * build a printf format string
  1469      * build a printf format string
  1472      */
  1470      */
  1481     __BEGIN_PROTECT_REGISTERS__
  1479     __BEGIN_PROTECT_REGISTERS__
  1482     len = snprintf(buffer, sizeof(buffer), fmtBuffer, __floatVal(self));
  1480     len = snprintf(buffer, sizeof(buffer), fmtBuffer, __floatVal(self));
  1483     __END_PROTECT_REGISTERS__
  1481     __END_PROTECT_REGISTERS__
  1484 
  1482 
  1485     if (len >= 0 && len < sizeof(buffer)-3) {
  1483     if (len >= 0 && len < sizeof(buffer)-3) {
  1486 	/*
  1484         /*
  1487 	 * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1485          * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
  1488 	 * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1486          * (i.e. look if string contains '.' or 'e' and append '.0' if not)
  1489 	 */
  1487          */
  1490 	for (cp = buffer; *cp; cp++) {
  1488         for (cp = buffer; *cp; cp++) {
  1491 	    if ((*cp == '.') || (*cp == 'E') || (*cp == 'e')) break;
  1489             if ((*cp == '.') || (*cp == 'E') || (*cp == 'e')) break;
  1492 	}
  1490         }
  1493 	if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1491         if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) {
  1494 	    if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1492             if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1495 		*cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1493                 *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1496 	    } else {
  1494             } else {
  1497 		*cp++ = '.';
  1495                 *cp++ = '.';
  1498 	    }
  1496             }
  1499 	    *cp++ = '0';
  1497             *cp++ = '0';
  1500 	    *cp = '\0';
  1498             *cp = '\0';
  1501 	} else {
  1499         } else {
  1502 	    if (cp && (*cp == '.')) {
  1500             if (cp && (*cp == '.')) {
  1503 		if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1501                 if (__isCharacter(@global(DecimalPointCharacterForPrinting))) {
  1504 		    *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1502                     *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting)));
  1505 		}
  1503                 }
  1506 	    }
  1504             }
  1507 	}
  1505         }
  1508 
  1506 
  1509 	s = __MKSTRING(buffer);
  1507         s = __MKSTRING(buffer);
  1510 	if (s != nil) {
  1508         if (s != nil) {
  1511 	    RETURN (s);
  1509             RETURN (s);
  1512 	}
  1510         }
  1513     }
  1511     }
  1514 %}.
  1512 %}.
  1515     "
  1513     "
  1516      memory allocation (for the new string) failed.
  1514      memory allocation (for the new string) failed.
  1517      When we arrive here, there was no memory, even after a garbage collect.
  1515      When we arrive here, there was no memory, even after a garbage collect.
  1520      Bad luck - you should increase the swap space on your machine.
  1518      Bad luck - you should increase the swap space on your machine.
  1521     "
  1519     "
  1522     ^ ObjectMemory allocationFailureSignal raise.
  1520     ^ ObjectMemory allocationFailureSignal raise.
  1523 
  1521 
  1524     "
  1522     "
  1525 	1.0 printString
  1523         1.0 printString
  1526 	1.234 printString
  1524         1.234 printString
  1527 	1e10 printString
  1525         1e10 printString
  1528 	1.2e3 printString
  1526         1.2e3 printString
  1529 	1.2e30 printString
  1527         1.2e30 printString
  1530 	(1.0 uncheckedDivide:0) printString
  1528         (1.0 uncheckedDivide:0) printString
  1531 	(0.0 uncheckedDivide:0) printString
  1529         (0.0 uncheckedDivide:0) printString
  1532 
  1530 
  1533 	DecimalPointCharacter := $,.
  1531         DecimalPointCharacter := $,.
  1534 	1.234 printString.
  1532         1.234 printString.
  1535 	1.0 printString.
  1533         1.0 printString.
  1536 	1e10 printString.
  1534         1e10 printString.
  1537 	1.2e3 printString.
  1535         1.2e3 printString.
  1538 	1.2e30 printString.
  1536         1.2e30 printString.
  1539 	(1.0 uncheckedDivide:0) printString.
  1537         (1.0 uncheckedDivide:0) printString.
  1540 	(0.0 uncheckedDivide:0) printString.
  1538         (0.0 uncheckedDivide:0) printString.
  1541 	DecimalPointCharacter := $.
  1539         DecimalPointCharacter := $.
  1542     "
  1540     "
  1543 !
  1541 !
  1544 
  1542 
  1545 printfPrintString:formatString
  1543 printfPrintString:formatString
  1546     "non-standard: return a printed representation of the receiver
  1544     "non-standard: return a printed representation of the receiver
  1558 %{  /* STACK: 400 */
  1556 %{  /* STACK: 400 */
  1559     char buffer[256];
  1557     char buffer[256];
  1560     OBJ s;
  1558     OBJ s;
  1561     int len;
  1559     int len;
  1562 
  1560 
  1563     if (__isString(formatString)) {
  1561     if (__isStringLike(formatString)) {
  1564 	/*
  1562         /*
  1565 	 * actually only needed on sparc: since thisContext is
  1563          * actually only needed on sparc: since thisContext is
  1566 	 * in a global register, which gets destroyed by printf,
  1564          * in a global register, which gets destroyed by printf,
  1567 	 * manually save it here - very stupid ...
  1565          * manually save it here - very stupid ...
  1568 	 */
  1566          */
  1569 	__BEGIN_PROTECT_REGISTERS__
  1567         __BEGIN_PROTECT_REGISTERS__
  1570 
  1568 
  1571 	len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __floatVal(self));
  1569         len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __floatVal(self));
  1572 
  1570 
  1573 	__END_PROTECT_REGISTERS__
  1571         __END_PROTECT_REGISTERS__
  1574 
  1572 
  1575 	if (len < 0) goto fail;
  1573         if (len < 0) goto fail;
  1576 
  1574 
  1577 	s = __MKSTRING_L(buffer, len);
  1575         s = __MKSTRING_L(buffer, len);
  1578 	if (s != nil) {
  1576         if (s != nil) {
  1579 	    RETURN (s);
  1577             RETURN (s);
  1580 	}
  1578         }
  1581     }
  1579     }
  1582 fail: ;
  1580 fail: ;
  1583 %}.
  1581 %}.
  1584     self primitiveFailed
  1582     self primitiveFailed
  1585 
  1583 
  2740 ! !
  2738 ! !
  2741 
  2739 
  2742 !Float class methodsFor:'documentation'!
  2740 !Float class methodsFor:'documentation'!
  2743 
  2741 
  2744 version
  2742 version
  2745     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.170 2009-11-03 10:04:19 cg Exp $'
  2743     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.171 2009-11-05 16:25:22 stefan Exp $'
  2746 !
  2744 !
  2747 
  2745 
  2748 version_CVS
  2746 version_CVS
  2749     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.170 2009-11-03 10:04:19 cg Exp $'
  2747     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.171 2009-11-05 16:25:22 stefan Exp $'
  2750 ! !
  2748 ! !
  2751 
  2749 
  2752 Float initialize!
  2750 Float initialize!