Float.st
changeset 1695 465e1eba8e8e
parent 1688 8a42db1eea60
child 1879 26df273349c4
equal deleted inserted replaced
1694:29791fde790e 1695:465e1eba8e8e
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 LimitedPrecisionReal variableByteSubclass:#Float
    13 LimitedPrecisionReal variableByteSubclass:#Float
    14 	instanceVariableNames:''
    14 	instanceVariableNames:''
    15 	classVariableNames:'LastErrorNumber'
    15 	classVariableNames:''
    16 	poolDictionaries:''
    16 	poolDictionaries:''
    17 	category:'Magnitude-Numbers'
    17 	category:'Magnitude-Numbers'
    18 !
    18 !
    19 
    19 
    20 !Float primitiveDefinitions!
    20 !Float primitiveDefinitions!
    68     Also, subclassing is complicated by the fact, that the VM creates floats as results
    68     Also, subclassing is complicated by the fact, that the VM creates floats as results
    69     of arithmetic operations (even if the operands are subclass-instances).
    69     of arithmetic operations (even if the operands are subclass-instances).
    70     (It does the float-check by probing a bit in the classes flag instVar).
    70     (It does the float-check by probing a bit in the classes flag instVar).
    71 
    71 
    72     [Class Variables:]
    72     [Class Variables:]
    73 
       
    74         LastErrorNumber <Integer>       value of errno (after a trig- or other math err)
       
    75 
       
    76 
    73 
    77     [see also:]
    74     [see also:]
    78         Number
    75         Number
    79         ShortFloat Fraction Integer
    76         ShortFloat Fraction Integer
    80         FloatArray DoubleArray
    77         FloatArray DoubleArray
    96      binary stored in a device independent format."
    93      binary stored in a device independent format."
    97 
    94 
    98 %{  /* NOCONTEXT */
    95 %{  /* NOCONTEXT */
    99     OBJ newFloat;
    96     OBJ newFloat;
   100 
    97 
   101     __qMKFLOAT(newFloat, 0.0, SENDER);
    98     __qMKFLOAT(newFloat, 0.0);
   102     RETURN (newFloat);
    99     RETURN (newFloat);
   103 %}
   100 %}
   104 
   101 
   105 ! !
   102 ! !
   106 
   103 
   259      Here, true is returned for myself, false for subclasses."
   256      Here, true is returned for myself, false for subclasses."
   260 
   257 
   261     ^ self == Float
   258     ^ self == Float
   262 
   259 
   263     "Modified: 23.4.1996 / 15:59:04 / cg"
   260     "Modified: 23.4.1996 / 15:59:04 / cg"
   264 !
       
   265 
       
   266 lastErrorNumber
       
   267     "return the value of errno after an error"
       
   268 
       
   269     ^ LastErrorNumber
       
   270 
       
   271     "
       
   272      2 arcSin.
       
   273      OperatingSystem errorTextForNumber:(Float lastErrorNumber)
       
   274     "
       
   275 ! !
   261 ! !
   276 
   262 
   277 !Float methodsFor:'arithmetic'!
   263 !Float methodsFor:'arithmetic'!
   278 
   264 
   279 * aNumber
   265 * aNumber
   285     double result;
   271     double result;
   286 
   272 
   287     if (__isSmallInteger(aNumber)) {
   273     if (__isSmallInteger(aNumber)) {
   288 	result = __floatVal(self) * (double)(__intVal(aNumber));
   274 	result = __floatVal(self) * (double)(__intVal(aNumber));
   289 retResult:
   275 retResult:
   290 	__qMKFLOAT(newFloat, result, SENDER);
   276 	__qMKFLOAT(newFloat, result);
   291 	RETURN ( newFloat );
   277 	RETURN ( newFloat );
   292     }
   278     }
   293     if (__isFloatLike(aNumber)) {
   279     if (__isFloatLike(aNumber)) {
   294 	result = __floatVal(self) * __floatVal(aNumber);
   280 	result = __floatVal(self) * __floatVal(aNumber);
   295 	goto retResult;
   281 	goto retResult;
   308     double result;
   294     double result;
   309 
   295 
   310     if (__isSmallInteger(aNumber)) {
   296     if (__isSmallInteger(aNumber)) {
   311 	result = __floatVal(self) + (double)(__intVal(aNumber));
   297 	result = __floatVal(self) + (double)(__intVal(aNumber));
   312 retResult:
   298 retResult:
   313 	__qMKFLOAT(newFloat, result, SENDER);
   299 	__qMKFLOAT(newFloat, result);
   314 	RETURN ( newFloat );
   300 	RETURN ( newFloat );
   315     }
   301     }
   316     if (__isFloatLike(aNumber)) {
   302     if (__isFloatLike(aNumber)) {
   317 	result = __floatVal(self) + __floatVal(aNumber);
   303 	result = __floatVal(self) + __floatVal(aNumber);
   318 	goto retResult;
   304 	goto retResult;
   331     double result;
   317     double result;
   332 
   318 
   333     if (__isSmallInteger(aNumber)) {
   319     if (__isSmallInteger(aNumber)) {
   334 	result = __floatVal(self) - (double)(__intVal(aNumber));
   320 	result = __floatVal(self) - (double)(__intVal(aNumber));
   335 retResult:
   321 retResult:
   336 	__qMKFLOAT(newFloat, result, SENDER);
   322 	__qMKFLOAT(newFloat, result);
   337 	RETURN ( newFloat );
   323 	RETURN ( newFloat );
   338     }
   324     }
   339     if (__isFloatLike(aNumber)) {
   325     if (__isFloatLike(aNumber)) {
   340 	result = __floatVal(self) - __floatVal(aNumber);
   326 	result = __floatVal(self) - __floatVal(aNumber);
   341 	goto retResult;
   327 	goto retResult;
   355 
   341 
   356     if (__isSmallInteger(aNumber)) {
   342     if (__isSmallInteger(aNumber)) {
   357 	if (aNumber != __MKSMALLINT(0)) {
   343 	if (aNumber != __MKSMALLINT(0)) {
   358 	    result = __floatVal(self) / ( (double)__intVal(aNumber)) ;
   344 	    result = __floatVal(self) / ( (double)__intVal(aNumber)) ;
   359 retResult:
   345 retResult:
   360 	    __qMKFLOAT(newFloat, result, SENDER);
   346 	    __qMKFLOAT(newFloat, result);
   361 	    RETURN ( newFloat );
   347 	    RETURN ( newFloat );
   362 	}
   348 	}
   363     } else {
   349     } else {
   364 	if (__isFloatLike(aNumber)) {
   350 	if (__isFloatLike(aNumber)) {
   365 	    val = __floatVal(aNumber);
   351 	    val = __floatVal(aNumber);
   386 %{  /* NOCONTEXT */
   372 %{  /* NOCONTEXT */
   387 
   373 
   388     OBJ newFloat;
   374     OBJ newFloat;
   389     double rslt = - __floatVal(self);
   375     double rslt = - __floatVal(self);
   390 
   376 
   391     __qMKFLOAT(newFloat, rslt, SENDER);
   377     __qMKFLOAT(newFloat, rslt);
   392     RETURN ( newFloat );
   378     RETURN ( newFloat );
   393 %}
   379 %}
   394 ! !
   380 ! !
   395 
   381 
   396 !Float methodsFor:'binary storage'!
   382 !Float methodsFor:'binary storage'!
   437 
   423 
   438     OBJ dummy = @global(ShortFloat);
   424     OBJ dummy = @global(ShortFloat);
   439     OBJ newFloat;
   425     OBJ newFloat;
   440     float fVal = (float)__floatVal(self);
   426     float fVal = (float)__floatVal(self);
   441 
   427 
   442     __qMKSFLOAT(newFloat, fVal, SENDER);
   428     __qMKSFLOAT(newFloat, fVal);
   443     RETURN ( newFloat );
   429     RETURN ( newFloat );
   444 %}
   430 %}
   445 !
   431 !
   446 
   432 
   447 coerce:aNumber
   433 coerce:aNumber
   582 	RETURN ( (__floatVal(self) != (double)(__intVal(aNumber))) ? true : false );
   568 	RETURN ( (__floatVal(self) != (double)(__intVal(aNumber))) ? true : false );
   583     }
   569     }
   584     if (__isFloatLike(aNumber)) {
   570     if (__isFloatLike(aNumber)) {
   585 	RETURN ( (__floatVal(self) != __floatVal(aNumber)) ? true : false );
   571 	RETURN ( (__floatVal(self) != __floatVal(aNumber)) ? true : false );
   586     }
   572     }
   587 %}
   573 %}.
   588 .
       
   589     ^ self retry:#~= coercing:aNumber
   574     ^ self retry:#~= coercing:aNumber
   590 ! !
   575 ! !
   591 
   576 
   592 !Float methodsFor:'mathematical functions'!
   577 !Float methodsFor:'mathematical functions'!
   593 
   578 
   595     "return the arccosine of myself as radians"
   580     "return the arccosine of myself as radians"
   596 
   581 
   597 %{  /* NOCONTEXT */
   582 %{  /* NOCONTEXT */
   598 
   583 
   599     double acos();
   584     double acos();
   600     double result;
   585     double rslt;
       
   586     OBJ newFloat;
   601 
   587 
   602     errno = 0;
   588     errno = 0;
   603     result = acos(__floatVal(self));
   589     rslt = acos(__floatVal(self));
   604     if (errno == 0)
   590     if (errno == 0) {
   605 	RETURN ( __MKFLOAT(result COMMA_SND) );
   591         __qMKFLOAT(newFloat, rslt);
   606     Float_LastErrorNumber = __MKSMALLINT(errno);
   592 	RETURN ( newFloat );
   607 %}
   593     }
   608 .
   594 %}.
   609     ^ DomainErrorSignal raise
   595     ^ DomainErrorSignal raise
   610 !
   596 !
   611 
   597 
   612 arcSin
   598 arcSin
   613     "return the arcsine of myself as radians"
   599     "return the arcsine of myself as radians"
   614 
   600 
   615 %{  /* NOCONTEXT */
   601 %{  /* NOCONTEXT */
   616 
   602 
   617     double asin();
   603     double asin();
   618     double result;
   604     double rslt;
       
   605     OBJ newFloat;
   619 
   606 
   620     errno = 0;
   607     errno = 0;
   621     result = asin(__floatVal(self));
   608     rslt = asin(__floatVal(self));
   622     if (errno == 0)
   609     if (errno == 0) {
   623 	RETURN ( __MKFLOAT(result COMMA_SND) );
   610 	__qMKFLOAT(newFloat, rslt);
   624     Float_LastErrorNumber = __MKSMALLINT(errno);
   611 	RETURN ( newFloat );
   625 %}
   612     }
   626 .
   613 %}.
   627     ^ DomainErrorSignal raise
   614     ^ DomainErrorSignal raise
   628 !
   615 !
   629 
   616 
   630 arcTan
   617 arcTan
   631     "return the arctangent of myself as radians"
   618     "return the arctangent of myself as radians"
   632 
   619 
   633 %{  /* NOCONTEXT */
   620 %{  /* NOCONTEXT */
   634 
   621 
   635     double atan();
   622     double atan();
   636     double result;
   623     double rslt;
       
   624     OBJ newFloat;
   637 
   625 
   638     errno = 0;
   626     errno = 0;
   639     result = atan(__floatVal(self));
   627     rslt = atan(__floatVal(self));
   640     if (errno == 0)
   628     if (errno == 0) {
   641 	RETURN ( __MKFLOAT(result COMMA_SND) );
   629 	__qMKFLOAT(newFloat, rslt);
   642     Float_LastErrorNumber = __MKSMALLINT(errno);
   630 	RETURN ( newFloat );
   643 %}
   631     }
   644 .
   632 %}.
   645     ^ DomainErrorSignal raise
   633     ^ DomainErrorSignal raise
   646 !
   634 !
   647 
   635 
   648 cos
   636 cos
   649     "return the cosine of myself interpreted as radians"
   637     "return the cosine of myself interpreted as radians"
   650 
   638 
   651 %{  /* NOCONTEXT */
   639 %{  /* NOCONTEXT */
   652 
   640 
   653     double cos();
   641     double cos();
   654     double result;
   642     double rslt;
       
   643     OBJ newFloat;
   655 
   644 
   656     errno = 0;
   645     errno = 0;
   657     result = cos(__floatVal(self));
   646     rslt = cos(__floatVal(self));
   658     if (errno == 0)
   647     if (errno == 0) {
   659 	RETURN ( __MKFLOAT(result COMMA_SND) );
   648 	__qMKFLOAT(newFloat, rslt);
   660     Float_LastErrorNumber = __MKSMALLINT(errno);
   649 	RETURN ( newFloat );
   661 %}
   650     }
   662 .
   651 %}.
   663     ^ DomainErrorSignal raise
   652     ^ DomainErrorSignal raise
   664 !
   653 !
   665 
   654 
   666 exp
   655 exp
   667     "return e raised to the power of the receiver"
   656     "return e raised to the power of the receiver"
   668 
   657 
   669 %{  /* NOCONTEXT */
   658 %{  /* NOCONTEXT */
   670 
   659 
   671     double exp();
   660     double exp();
   672     double result;
   661     double rslt;
       
   662     OBJ newFloat;
   673 
   663 
   674     errno = 0;
   664     errno = 0;
   675     result = exp(__floatVal(self));
   665     rslt = exp(__floatVal(self));
   676     if (errno == 0)
   666     if (errno == 0) {
   677 	RETURN ( __MKFLOAT(result COMMA_SND) );
   667 	__qMKFLOAT(newFloat, rslt);
   678     Float_LastErrorNumber = __MKSMALLINT(errno);
   668 	RETURN ( newFloat );
   679 %}
   669     }
   680 .
   670 %}.
   681     ^ DomainErrorSignal raise
   671     ^ DomainErrorSignal raise
   682 !
   672 !
   683 
   673 
   684 ln
   674 ln
   685     "return the natural logarithm of myself"
   675     "return the natural logarithm of myself"
   686 
   676 
   687 %{  /* NOCONTEXT */
   677 %{  /* NOCONTEXT */
   688 
   678 
   689     double log();
   679     double log();
   690     double result;
   680     double rslt;
       
   681     OBJ newFloat;
   691 
   682 
   692     errno = 0;
   683     errno = 0;
   693     result = log(__floatVal(self));
   684     rslt = log(__floatVal(self));
   694     if (errno == 0)
   685     if (errno == 0) {
   695 	RETURN ( __MKFLOAT(result COMMA_SND) );
   686 	__qMKFLOAT(newFloat, rslt);
   696     Float_LastErrorNumber = __MKSMALLINT(errno);
   687 	RETURN ( newFloat );
   697 %}
   688     }
   698 .
   689 %}.
   699     "
   690     "
   700      an invalid value for logarithm
   691      an invalid value for logarithm
   701     "
   692     "
   702     ^ DomainErrorSignal raise
   693     ^ DomainErrorSignal raise
   703 !
   694 !
   707     |n|
   698     |n|
   708 
   699 
   709     n := aNumber asFloat.
   700     n := aNumber asFloat.
   710 %{
   701 %{
   711     double pow();
   702     double pow();
   712     double result;
   703     double rslt;
       
   704     OBJ newFloat;
   713 
   705 
   714     if (__isFloatLike(n)) {
   706     if (__isFloatLike(n)) {
   715 	errno = 0;
   707 	errno = 0;
   716 	result = pow(__floatVal(self), __floatVal(n));
   708 	rslt = pow(__floatVal(self), __floatVal(n));
   717 	errno = 0;  /* XXXX */
   709 	errno = 0;  /* XXXX */
   718 	if (errno == 0)
   710         if (errno == 0) {
   719 	    RETURN ( __MKFLOAT(result) );
   711 	    __qMKFLOAT(newFloat, rslt);
   720 	Float_LastErrorNumber = __MKSMALLINT(errno);
   712 	    RETURN ( newFloat );
   721     }
   713         }
   722 %}
   714     }
   723 .
   715 %}.
   724     "
   716     "
   725      an invalid argument (not convertable to float ?)
   717      an invalid argument (not convertable to float ?)
   726     "
   718     "
   727     ^ DomainErrorSignal raise
   719     ^ DomainErrorSignal raise
   728 !
   720 !
   731     "return the sine of myself interpreted as radians"
   723     "return the sine of myself interpreted as radians"
   732 
   724 
   733 %{  /* NOCONTEXT */
   725 %{  /* NOCONTEXT */
   734 
   726 
   735     double sin();
   727     double sin();
   736     double result;
   728     double rslt;
       
   729     OBJ newFloat;
   737 
   730 
   738     errno = 0;
   731     errno = 0;
   739     result = sin(__floatVal(self));
   732     rslt = sin(__floatVal(self));
   740     if (errno == 0)
   733     if (errno == 0) {
   741 	RETURN ( __MKFLOAT(result COMMA_SND) );
   734 	__qMKFLOAT(newFloat, rslt);
   742     Float_LastErrorNumber = __MKSMALLINT(errno);
   735 	RETURN ( newFloat );
   743 %}
   736     }
   744 .
   737 %}.
   745     ^ DomainErrorSignal raise
   738     ^ DomainErrorSignal raise
   746 !
   739 !
   747 
   740 
   748 sqrt
   741 sqrt
   749     "return the square root of myself"
   742     "return the square root of myself"
   750 
   743 
   751 %{  /* NOCONTEXT */
   744 %{  /* NOCONTEXT */
   752 
   745 
   753     double sqrt();
   746     double sqrt();
   754     double result;
   747     double rslt;
       
   748     OBJ newFloat;
   755 
   749 
   756     errno = 0;
   750     errno = 0;
   757     result = sqrt(__floatVal(self));
   751     rslt = sqrt(__floatVal(self));
   758     if (errno == 0)
   752     if (errno == 0) {
   759 	RETURN ( __MKFLOAT(result COMMA_SND) );
   753 	__qMKFLOAT(newFloat, rslt);
   760     Float_LastErrorNumber = __MKSMALLINT(errno);
   754 	RETURN ( newFloat );
   761 %}
   755     }
   762 .
   756 %}.
   763     ^ DomainErrorSignal raise
   757     ^ DomainErrorSignal raise
   764 !
   758 !
   765 
   759 
   766 tan
   760 tan
   767     "return the tangent of myself interpreted as radians"
   761     "return the tangent of myself interpreted as radians"
   768 
   762 
   769 %{  /* NOCONTEXT */
   763 %{  /* NOCONTEXT */
   770 
   764 
   771     double tan();
   765     double tan();
   772     double result;
   766     double rslt;
       
   767     OBJ newFloat;
   773 
   768 
   774     errno = 0;
   769     errno = 0;
   775     result = tan(__floatVal(self));
   770     rslt = tan(__floatVal(self));
   776     if (errno == 0)
   771     if (errno == 0) {
   777 	RETURN ( __MKFLOAT(result COMMA_SND) );
   772 	__qMKFLOAT(newFloat, rslt);
   778     Float_LastErrorNumber = __MKSMALLINT(errno);
   773 	RETURN ( newFloat );
   779 %}
   774     }
   780 .
   775 %}.
   781     ^ DomainErrorSignal raise
   776     ^ DomainErrorSignal raise
   782 ! !
   777 ! !
   783 
   778 
   784 !Float methodsFor:'printing & storing'!
   779 !Float methodsFor:'printing & storing'!
   785 
   780 
  1089 ! !
  1084 ! !
  1090 
  1085 
  1091 !Float  class methodsFor:'documentation'!
  1086 !Float  class methodsFor:'documentation'!
  1092 
  1087 
  1093 version
  1088 version
  1094     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.42 1996-10-02 11:32:32 cg Exp $'
  1089     ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.43 1996-10-07 17:47:12 cg Exp $'
  1095 ! !
  1090 ! !