ShortFloat.st
changeset 13359 17228556cabd
parent 13358 562da8ee5e75
child 13360 1aac241c9981
equal deleted inserted replaced
13358:562da8ee5e75 13359:17228556cabd
   647      3.0 asShortFloat abs
   647      3.0 asShortFloat abs
   648      -3.0 asShortFloat abs
   648      -3.0 asShortFloat abs
   649     "
   649     "
   650 !
   650 !
   651 
   651 
       
   652 negated
       
   653     "return myself negated"
       
   654 
       
   655 %{  /* NOCONTEXT */
       
   656     OBJ newFloat;
       
   657     float rslt = - __shortFloatVal(self);
       
   658 
       
   659     __qMKSFLOAT(newFloat, rslt);
       
   660     RETURN ( newFloat );
       
   661 %}.
       
   662     ^ 0.0 - self
       
   663 
       
   664 !
       
   665 
       
   666 uncheckedDivide:aNumber
       
   667     "return the quotient of the receiver and the argument, aNumber.
       
   668      Do not check for divide by zero (return NaN or Infinity).
       
   669      This operation is provided for emulators of other languages/semantics,
       
   670      where no exception is raised for these results (i.e. Java).
       
   671      Its only defined if the arguments type is the same as the receivers."
       
   672 
       
   673 %{  /* NOCONTEXT */
       
   674 
       
   675     OBJ newFloat;
       
   676     float result, val;
       
   677     double dResult, dVal;
       
   678 
       
   679     if (__isSmallInteger(aNumber)) {
       
   680 	result = __shortFloatVal(self) / (float)(__intVal(aNumber));
       
   681 retResult:
       
   682 	__qMKSFLOAT(newFloat, result);
       
   683 	RETURN ( newFloat );
       
   684     }
       
   685     if (__isShortFloat(aNumber)) {
       
   686 	val = __shortFloatVal(aNumber);
       
   687 	result = __shortFloatVal(self) / val;
       
   688 	goto retResult;
       
   689     }
       
   690     if (__isFloatLike(aNumber)) {
       
   691 	dVal = __floatVal(aNumber);
       
   692 	dResult = (double) __shortFloatVal(self) / dVal;
       
   693 	__qMKFLOAT(newFloat, dResult);
       
   694 	RETURN ( newFloat );
       
   695     }
       
   696 %}.
       
   697     ^ aNumber quotientFromShortFloat:self
       
   698 
       
   699     "
       
   700       0.0 asShortFloat uncheckedDivide:0
       
   701       1.0 asShortFloat uncheckedDivide:0.0
       
   702     "
       
   703 ! !
       
   704 
       
   705 !ShortFloat methodsFor:'coercing & converting'!
       
   706 
       
   707 asFloat
       
   708     "return a Float with same value as the receiver.
       
   709      Redefined for performance (machine can do it faster)"
       
   710 
       
   711 %{  /* NOCONTEXT */
       
   712 
       
   713     OBJ newFloat;
       
   714     double dVal = (double)__shortFloatVal(self);
       
   715 
       
   716     __qMKFLOAT(newFloat, dVal);
       
   717     RETURN ( newFloat );
       
   718 %}
       
   719 
       
   720     "
       
   721      1.0 asShortFloat asFloat
       
   722     "
       
   723 !
       
   724 
       
   725 asInteger
       
   726     "return an integer with same value - might truncate"
       
   727 
       
   728 %{  /* NOCONTEXT */
       
   729     float fVal;
       
   730 
       
   731     fVal = __shortFloatVal(self);
       
   732 #ifdef WIN32
       
   733     if (! isnanf(fVal))
       
   734 #endif
       
   735     {
       
   736 	if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
       
   737 	    RETURN ( __mkSmallInteger( (INT)fVal) );
       
   738 	}
       
   739     }
       
   740 %}.
       
   741     ^ super asInteger
       
   742 
       
   743     "
       
   744      12345.0 asShortFloat asInteger
       
   745      1e15 asShortFloat asInteger
       
   746     "
       
   747 !
       
   748 
       
   749 asLongFloat
       
   750     ^ LongFloat fromShortFloat:self
       
   751 !
       
   752 
       
   753 asShortFloat
       
   754     "return a ShortFloat with same value as the receiver - thats me"
       
   755 
       
   756     ^ self
       
   757 !
       
   758 
       
   759 coerce:aNumber
       
   760     "convert the argument aNumber into an instance of the receivers class and return it."
       
   761 
       
   762     ^ aNumber asShortFloat
       
   763 !
       
   764 
       
   765 generality
       
   766     "return the generality value - see ArithmeticValue>>retry:coercing:"
       
   767 
       
   768     ^ 70
       
   769 
       
   770 
       
   771 ! !
       
   772 
       
   773 !ShortFloat methodsFor:'comparing'!
       
   774 
       
   775 < aNumber
       
   776     "return true, if the argument is greater"
       
   777 
       
   778 %{  /* NOCONTEXT */
       
   779 
       
   780     if (__isSmallInteger(aNumber)) {
       
   781 	RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false );
       
   782     }
       
   783     if (aNumber != nil) {
       
   784 	if (__qIsFloatLike(aNumber)) {
       
   785 	    RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false );
       
   786 	}
       
   787 	if (__qIsShortFloat(aNumber)) {
       
   788 	    RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false );
       
   789 	}
       
   790     }
       
   791 %}.
       
   792     ^ aNumber lessFromShortFloat:self
       
   793 
       
   794     "
       
   795      1.0 asShortFloat > (1/3)
       
   796     "
       
   797 !
       
   798 
       
   799 <= aNumber
       
   800     "return true, if the argument is greater or equal"
       
   801 
       
   802 %{  /* NOCONTEXT */
       
   803 
       
   804     if (__isSmallInteger(aNumber)) {
       
   805 	RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false );
       
   806     }
       
   807     if (aNumber != nil) {
       
   808 	if (__qIsFloatLike(aNumber)) {
       
   809 	    RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false );
       
   810 	}
       
   811 	if (__qIsShortFloat(aNumber)) {
       
   812 	    RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false );
       
   813 	}
       
   814     }
       
   815 %}.
       
   816     ^ self retry:#<= coercing:aNumber
       
   817 !
       
   818 
       
   819 = aNumber
       
   820     "return true, if the argument represents the same numeric value
       
   821      as the receiver, false otherwise"
       
   822 
       
   823 %{  /* NOCONTEXT */
       
   824 
       
   825     if (__isSmallInteger(aNumber)) {
       
   826 	RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false );
       
   827     }
       
   828     if (aNumber == nil) {
       
   829 	RETURN (false);
       
   830     }
       
   831     if (__qIsFloatLike(aNumber)) {
       
   832 	RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false );
       
   833     }
       
   834     if (__qIsShortFloat(aNumber)) {
       
   835 	RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false );
       
   836     }
       
   837 %}.
       
   838     ^ aNumber equalFromShortFloat:self
       
   839 !
       
   840 
       
   841 > aNumber
       
   842     "return true, if the argument is less"
       
   843 
       
   844 %{  /* NOCONTEXT */
       
   845 
       
   846     if (__isSmallInteger(aNumber)) {
       
   847 	RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false );
       
   848     }
       
   849     if (aNumber != nil) {
       
   850 	if (__qIsFloatLike(aNumber)) {
       
   851 	    RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false );
       
   852 	}
       
   853 	if (__qIsShortFloat(aNumber)) {
       
   854 	    RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false );
       
   855 	}
       
   856     }
       
   857 %}.
       
   858     ^ self retry:#> coercing:aNumber
       
   859 !
       
   860 
       
   861 >= aNumber
       
   862     "return true, if the argument is less or equal"
       
   863 
       
   864 %{  /* NOCONTEXT */
       
   865 
       
   866     if (__isSmallInteger(aNumber)) {
       
   867 	RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false );
       
   868     }
       
   869     if (aNumber != nil) {
       
   870 	if (__qIsFloatLike(aNumber)) {
       
   871 	    RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false );
       
   872 	}
       
   873 	if (__qIsShortFloat(aNumber)) {
       
   874 	    RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false );
       
   875 	}
       
   876     }
       
   877 %}.
       
   878     ^ self retry:#>= coercing:aNumber
       
   879 !
       
   880 
       
   881 hash
       
   882     "return a number for hashing; redefined, since floats compare
       
   883      by numeric value (i.e. 3.0 = 3), therefore 3.0 hash must be the same
       
   884      as 3 hash."
       
   885 
       
   886     |i|
       
   887 
       
   888     (self >= SmallInteger minVal and:[self <= SmallInteger maxVal]) ifTrue:[
       
   889 	i := self asInteger.
       
   890 	self = i ifTrue:[
       
   891 	    ^ i hash
       
   892 	].
       
   893     ].
       
   894 
       
   895     ^ self asFloat hash
       
   896 
       
   897     "
       
   898      1.2345 hash
       
   899      1.2345 asShortFloat hash
       
   900      1.0 hash
       
   901      1.0 asShortFloat hash
       
   902      0.5 asShortFloat hash
       
   903      0.25 asShortFloat hash
       
   904      0.5 hash
       
   905      0.25 hash
       
   906     "
       
   907 !
       
   908 
       
   909 ~= aNumber
       
   910     "return true, if the arguments value are not equal"
       
   911 
       
   912 %{  /* NOCONTEXT */
       
   913 
       
   914     if (aNumber != nil) {
       
   915 	if (__isSmallInteger(aNumber)) {
       
   916 	    RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false );
       
   917 	}
       
   918 	if (__qIsFloatLike(aNumber)) {
       
   919 	    RETURN ( (double)(__shortFloatVal(self) !=  __floatVal(aNumber)) ? true : false );
       
   920 	}
       
   921 	if (__qIsShortFloat(aNumber)) {
       
   922 	    RETURN ( (__shortFloatVal(self) !=  __shortFloatVal(aNumber)) ? true : false );
       
   923 	}
       
   924     } else {
       
   925 	RETURN ( true );
       
   926     }
       
   927 %}.
       
   928     ^ super ~= aNumber
       
   929 ! !
       
   930 
       
   931 !ShortFloat methodsFor:'mathematical functions'!
       
   932 
   652 fastInverseSqrt
   933 fastInverseSqrt
   653     "return a rough but fast approximation of (1 / self sqrt).
   934     "return a rough but fast approximation of (1 / self sqrt).
   654      The error is some 1%, which is ok for some 3D computatins.
   935      The error is some 1%, which is ok for many 3D computations or physics simulations.
   655      Do not use this for now: it is non-portable and probably not speeding things up
   936      Do not use this for now: it is non-portable and probably not speeding things up
   656      much, unless inlined into the sender code.
   937      much, unless inlined into the sender code.
   657      The code is here as a reminder and might be later used as a hint for the inliner
   938      The code is here as a reminder and might be later used as a hint for the inliner
   658      (to speed up 3D computations, for example)"
   939      (to speed up 3D computations, for example)"
   659 
   940 
   702      ].
   983      ].
   703      Transcript show:'empty: '; showCR:t0.
   984      Transcript show:'empty: '; showCR:t0.
   704      Transcript show:'fast: '; showCR:t1.
   985      Transcript show:'fast: '; showCR:t1.
   705      Transcript show:'regular: '; showCR:t2.
   986      Transcript show:'regular: '; showCR:t2.
   706     "
   987     "
   707 !
       
   708 
       
   709 negated
       
   710     "return myself negated"
       
   711 
       
   712 %{  /* NOCONTEXT */
       
   713     OBJ newFloat;
       
   714     float rslt = - __shortFloatVal(self);
       
   715 
       
   716     __qMKSFLOAT(newFloat, rslt);
       
   717     RETURN ( newFloat );
       
   718 %}.
       
   719     ^ 0.0 - self
       
   720 
       
   721 !
       
   722 
       
   723 uncheckedDivide:aNumber
       
   724     "return the quotient of the receiver and the argument, aNumber.
       
   725      Do not check for divide by zero (return NaN or Infinity).
       
   726      This operation is provided for emulators of other languages/semantics,
       
   727      where no exception is raised for these results (i.e. Java).
       
   728      Its only defined if the arguments type is the same as the receivers."
       
   729 
       
   730 %{  /* NOCONTEXT */
       
   731 
       
   732     OBJ newFloat;
       
   733     float result, val;
       
   734     double dResult, dVal;
       
   735 
       
   736     if (__isSmallInteger(aNumber)) {
       
   737 	result = __shortFloatVal(self) / (float)(__intVal(aNumber));
       
   738 retResult:
       
   739 	__qMKSFLOAT(newFloat, result);
       
   740 	RETURN ( newFloat );
       
   741     }
       
   742     if (__isShortFloat(aNumber)) {
       
   743 	val = __shortFloatVal(aNumber);
       
   744 	result = __shortFloatVal(self) / val;
       
   745 	goto retResult;
       
   746     }
       
   747     if (__isFloatLike(aNumber)) {
       
   748 	dVal = __floatVal(aNumber);
       
   749 	dResult = (double) __shortFloatVal(self) / dVal;
       
   750 	__qMKFLOAT(newFloat, dResult);
       
   751 	RETURN ( newFloat );
       
   752     }
       
   753 %}.
       
   754     ^ aNumber quotientFromShortFloat:self
       
   755 
       
   756     "
       
   757       0.0 asShortFloat uncheckedDivide:0
       
   758       1.0 asShortFloat uncheckedDivide:0.0
       
   759     "
       
   760 ! !
       
   761 
       
   762 !ShortFloat methodsFor:'coercing & converting'!
       
   763 
       
   764 asFloat
       
   765     "return a Float with same value as the receiver.
       
   766      Redefined for performance (machine can do it faster)"
       
   767 
       
   768 %{  /* NOCONTEXT */
       
   769 
       
   770     OBJ newFloat;
       
   771     double dVal = (double)__shortFloatVal(self);
       
   772 
       
   773     __qMKFLOAT(newFloat, dVal);
       
   774     RETURN ( newFloat );
       
   775 %}
       
   776 
       
   777     "
       
   778      1.0 asShortFloat asFloat
       
   779     "
       
   780 !
       
   781 
       
   782 asInteger
       
   783     "return an integer with same value - might truncate"
       
   784 
       
   785 %{  /* NOCONTEXT */
       
   786     float fVal;
       
   787 
       
   788     fVal = __shortFloatVal(self);
       
   789 #ifdef WIN32
       
   790     if (! isnanf(fVal))
       
   791 #endif
       
   792     {
       
   793 	if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) {
       
   794 	    RETURN ( __mkSmallInteger( (INT)fVal) );
       
   795 	}
       
   796     }
       
   797 %}.
       
   798     ^ super asInteger
       
   799 
       
   800     "
       
   801      12345.0 asShortFloat asInteger
       
   802      1e15 asShortFloat asInteger
       
   803     "
       
   804 !
       
   805 
       
   806 asLongFloat
       
   807     ^ LongFloat fromShortFloat:self
       
   808 !
       
   809 
       
   810 asShortFloat
       
   811     "return a ShortFloat with same value as the receiver - thats me"
       
   812 
       
   813     ^ self
       
   814 !
       
   815 
       
   816 coerce:aNumber
       
   817     "convert the argument aNumber into an instance of the receivers class and return it."
       
   818 
       
   819     ^ aNumber asShortFloat
       
   820 !
       
   821 
       
   822 generality
       
   823     "return the generality value - see ArithmeticValue>>retry:coercing:"
       
   824 
       
   825     ^ 70
       
   826 
       
   827 
       
   828 ! !
       
   829 
       
   830 !ShortFloat methodsFor:'comparing'!
       
   831 
       
   832 < aNumber
       
   833     "return true, if the argument is greater"
       
   834 
       
   835 %{  /* NOCONTEXT */
       
   836 
       
   837     if (__isSmallInteger(aNumber)) {
       
   838 	RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false );
       
   839     }
       
   840     if (aNumber != nil) {
       
   841 	if (__qIsFloatLike(aNumber)) {
       
   842 	    RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false );
       
   843 	}
       
   844 	if (__qIsShortFloat(aNumber)) {
       
   845 	    RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false );
       
   846 	}
       
   847     }
       
   848 %}.
       
   849     ^ aNumber lessFromShortFloat:self
       
   850 
       
   851     "
       
   852      1.0 asShortFloat > (1/3)
       
   853     "
       
   854 !
       
   855 
       
   856 <= aNumber
       
   857     "return true, if the argument is greater or equal"
       
   858 
       
   859 %{  /* NOCONTEXT */
       
   860 
       
   861     if (__isSmallInteger(aNumber)) {
       
   862 	RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false );
       
   863     }
       
   864     if (aNumber != nil) {
       
   865 	if (__qIsFloatLike(aNumber)) {
       
   866 	    RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false );
       
   867 	}
       
   868 	if (__qIsShortFloat(aNumber)) {
       
   869 	    RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false );
       
   870 	}
       
   871     }
       
   872 %}.
       
   873     ^ self retry:#<= coercing:aNumber
       
   874 !
       
   875 
       
   876 = aNumber
       
   877     "return true, if the argument represents the same numeric value
       
   878      as the receiver, false otherwise"
       
   879 
       
   880 %{  /* NOCONTEXT */
       
   881 
       
   882     if (__isSmallInteger(aNumber)) {
       
   883 	RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false );
       
   884     }
       
   885     if (aNumber == nil) {
       
   886 	RETURN (false);
       
   887     }
       
   888     if (__qIsFloatLike(aNumber)) {
       
   889 	RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false );
       
   890     }
       
   891     if (__qIsShortFloat(aNumber)) {
       
   892 	RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false );
       
   893     }
       
   894 %}.
       
   895     ^ aNumber equalFromShortFloat:self
       
   896 !
       
   897 
       
   898 > aNumber
       
   899     "return true, if the argument is less"
       
   900 
       
   901 %{  /* NOCONTEXT */
       
   902 
       
   903     if (__isSmallInteger(aNumber)) {
       
   904 	RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false );
       
   905     }
       
   906     if (aNumber != nil) {
       
   907 	if (__qIsFloatLike(aNumber)) {
       
   908 	    RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false );
       
   909 	}
       
   910 	if (__qIsShortFloat(aNumber)) {
       
   911 	    RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false );
       
   912 	}
       
   913     }
       
   914 %}.
       
   915     ^ self retry:#> coercing:aNumber
       
   916 !
       
   917 
       
   918 >= aNumber
       
   919     "return true, if the argument is less or equal"
       
   920 
       
   921 %{  /* NOCONTEXT */
       
   922 
       
   923     if (__isSmallInteger(aNumber)) {
       
   924 	RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false );
       
   925     }
       
   926     if (aNumber != nil) {
       
   927 	if (__qIsFloatLike(aNumber)) {
       
   928 	    RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false );
       
   929 	}
       
   930 	if (__qIsShortFloat(aNumber)) {
       
   931 	    RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false );
       
   932 	}
       
   933     }
       
   934 %}.
       
   935     ^ self retry:#>= coercing:aNumber
       
   936 !
       
   937 
       
   938 hash
       
   939     "return a number for hashing; redefined, since floats compare
       
   940      by numeric value (i.e. 3.0 = 3), therefore 3.0 hash must be the same
       
   941      as 3 hash."
       
   942 
       
   943     |i|
       
   944 
       
   945     (self >= SmallInteger minVal and:[self <= SmallInteger maxVal]) ifTrue:[
       
   946 	i := self asInteger.
       
   947 	self = i ifTrue:[
       
   948 	    ^ i hash
       
   949 	].
       
   950     ].
       
   951 
       
   952     ^ self asFloat hash
       
   953 
       
   954     "
       
   955      1.2345 hash
       
   956      1.2345 asShortFloat hash
       
   957      1.0 hash
       
   958      1.0 asShortFloat hash
       
   959      0.5 asShortFloat hash
       
   960      0.25 asShortFloat hash
       
   961      0.5 hash
       
   962      0.25 hash
       
   963     "
       
   964 !
       
   965 
       
   966 ~= aNumber
       
   967     "return true, if the arguments value are not equal"
       
   968 
       
   969 %{  /* NOCONTEXT */
       
   970 
       
   971     if (aNumber != nil) {
       
   972 	if (__isSmallInteger(aNumber)) {
       
   973 	    RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false );
       
   974 	}
       
   975 	if (__qIsFloatLike(aNumber)) {
       
   976 	    RETURN ( (double)(__shortFloatVal(self) !=  __floatVal(aNumber)) ? true : false );
       
   977 	}
       
   978 	if (__qIsShortFloat(aNumber)) {
       
   979 	    RETURN ( (__shortFloatVal(self) !=  __shortFloatVal(aNumber)) ? true : false );
       
   980 	}
       
   981     } else {
       
   982 	RETURN ( true );
       
   983     }
       
   984 %}.
       
   985     ^ super ~= aNumber
       
   986 ! !
   988 ! !
   987 
   989 
   988 !ShortFloat methodsFor:'printing & storing'!
   990 !ShortFloat methodsFor:'printing & storing'!
   989 
   991 
   990 printString
   992 printString
  1779 ! !
  1781 ! !
  1780 
  1782 
  1781 !ShortFloat class methodsFor:'documentation'!
  1783 !ShortFloat class methodsFor:'documentation'!
  1782 
  1784 
  1783 version
  1785 version
  1784     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.105 2011-05-04 13:16:38 cg Exp $'
  1786     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.106 2011-05-04 13:17:39 cg Exp $'
  1785 !
  1787 !
  1786 
  1788 
  1787 version_CVS
  1789 version_CVS
  1788     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.105 2011-05-04 13:16:38 cg Exp $'
  1790     ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.106 2011-05-04 13:17:39 cg Exp $'
  1789 ! !
  1791 ! !