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 |