1555 ^ self coerce:(self truncated). |
1553 ^ self coerce:(self truncated). |
1556 |
1554 |
1557 " |
1555 " |
1558 0.4 asLongFloat truncatedAsFloat |
1556 0.4 asLongFloat truncatedAsFloat |
1559 " |
1557 " |
|
1558 ! |
|
1559 |
|
1560 truncatedToPrecision |
|
1561 "truncates to the precision of the float. |
|
1562 This is slightly different from truncated. |
|
1563 Taking for example 1e32, |
|
1564 the printed representation will be 1e32, |
|
1565 but the actual value, when truncating to an integer |
|
1566 would be 100000003318135351409612647563264. |
|
1567 |
|
1568 This is due to the inaccuracy in the least significant bits, |
|
1569 and the way the print-converter compensates for this. |
|
1570 This method tries to generate an integer value which corresponds |
|
1571 to what is seen in the float's printString. |
|
1572 |
|
1573 Here, a slow fallback (generating and rescanning the printString) |
|
1574 is provided, which should work on any float number. |
|
1575 Specialized versions in subclasses may be added for more performance |
|
1576 (however, this is probably only used rarely)" |
|
1577 |
|
1578 |pow10 printString intVal s sign nFract ch expSign exp pI| |
|
1579 |
|
1580 pow10 := #(10 100 1000 10000 100000 1000000 10000000 100000000 1000000000). |
|
1581 |
|
1582 printString := self printString. |
|
1583 intVal := 0. |
|
1584 sign := 1. |
|
1585 nFract := 0. |
|
1586 exp := 0. |
|
1587 |
|
1588 "/ fetch the mantissa |
|
1589 s := printString readStream. |
|
1590 s peek == $- ifTrue:[ |
|
1591 sign := -1. |
|
1592 s next. |
|
1593 ]. |
|
1594 intVal := s nextDecimalInteger. |
|
1595 s peek == $. ifTrue:[ |
|
1596 s next. |
|
1597 [(ch := s peek) notNil and:[ch isDigit]] whileTrue:[ |
|
1598 intVal := intVal * 10 + (s next digitValue). |
|
1599 nFract := nFract + 1. |
|
1600 ]. |
|
1601 ]. |
|
1602 ('eEdDqQ' includes:s peek) ifTrue:[ |
|
1603 expSign := 1. |
|
1604 s next. |
|
1605 (ch := s peek) == $- ifTrue:[ |
|
1606 expSign := -1. |
|
1607 s next. |
|
1608 ] ifFalse:[ |
|
1609 ch == $+ ifTrue:[ |
|
1610 s next. |
|
1611 ]. |
|
1612 ]. |
|
1613 exp := s nextDecimalInteger. |
|
1614 exp := exp * expSign. |
|
1615 ]. |
|
1616 exp := exp - nFract. |
|
1617 exp < 0 ifTrue:[ |
|
1618 [exp < 0] whileTrue:[ |
|
1619 pI := (exp negated) min:pow10 size. |
|
1620 intVal := intVal / (pow10 at:pI). |
|
1621 exp := exp + pI. |
|
1622 ]. |
|
1623 intVal := intVal asInteger. |
|
1624 ] ifFalse:[ |
|
1625 [exp > 0] whileTrue:[ |
|
1626 pI := exp min:pow10 size. |
|
1627 intVal := intVal * (pow10 at:pI). |
|
1628 exp := exp - pI. |
|
1629 ]. |
|
1630 ]. |
|
1631 ^ intVal |
|
1632 |
|
1633 " |
|
1634 1e32 asShortFloat truncated |
|
1635 1e32 asShortFloat truncatedToPrecision |
|
1636 1.234e10 asShortFloat truncatedToPrecision |
|
1637 1234e-1 asShortFloat truncatedToPrecision |
|
1638 |
|
1639 1e32 truncated |
|
1640 1e32 truncatedToPrecision |
|
1641 1.234e10 truncatedToPrecision |
|
1642 1234e-1 truncatedToPrecision |
|
1643 |
|
1644 1e32 asLongFloat truncated |
|
1645 1e32 asLongFloat truncatedToPrecision |
|
1646 1.234e10 asLongFloat truncatedToPrecision |
|
1647 1234e-1 asLongFloat truncatedToPrecision |
|
1648 " |
1560 ! ! |
1649 ! ! |
1561 |
1650 |
1562 !LimitedPrecisionReal methodsFor:'visiting'! |
1651 !LimitedPrecisionReal methodsFor:'visiting'! |
1563 |
1652 |
1564 acceptVisitor:aVisitor with:aParameter |
1653 acceptVisitor:aVisitor with:aParameter |