TOC PREV NEXT INDEX

Put your logo here!


19 Mathematical Functions, Trigonometic and Logarithmic (math.hhf)


The HLA math library module provides several large integer arithmetic/logical, trigonometic, and logarithmic routines that extend those provided directly in the FPU. Note that many of the transcendental functions place strict limits on the values of their parameters. Since a reasonable math text or the Intel documentation for details.

math.addq( left:qword; right:qword; var dest:qword ); 
 
math.addl( left:lword; right:lword; var dest:lword ); 
 

These routines add two quad-word 64-bit (addq) or long word 128-bit (addl) integer values. The values may be signed or unsigned. These two routines compute the following:

	dest := left + right;
 

 

These routines set the 80x86 flags exactly the same way that the standard ADD instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry and overflow flags denote unsigned or signed overflow (respectively).

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision addition requires about the same number of instructions has it takes to simply pass the parameters to the math.addq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision add sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "three-address" form that allows a different destination address (i.e., the destination does not have to be the same as one of the source operands). Certainly the math.addl routine is more cost effective to use than the math.addq routine, since there's a lot more work involved in doing a 128-bit addition vs. a 64-bit addition (the 64-bit addition takes only six instructions whereas the 128-bit addition requires twelve; therefore, the extra instructions involved in calling math.addl don't completely overshadow the actual work done).

The Standard Library does not provide an "ADd with Carry" version of this procedure. If you need to do extended precision arithmetic beyond 128 bits (or some size other than 64 or 128 bits), then use discrete x86 instructions.

math.andq( left:qword; right:qword; var dest:qword ); 
 
math.andl( left:lword; right:lword; var dest:lword ); 
 

These routines logically AND two quad-word 64-bit (andq) or long word 128-bit (andl) integer values. These two routines compute the following:

	dest := left & right;
 

 

These routines set the 80x86 flags exactly the same way that the standard AND instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry and overflow flags are both clear.

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision AND requires about the same number of instructions has it takes to simply pass the parameters to the math.andq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision AND sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "three-address" form that allows a different destination address (i.e., the destination does not have to be the same as one of the source operands). Certainly the math.andl routine is more cost effective to use than the math.andq routine, since there's a lot more work involved in doing a 128-bit AND vs. a 64-bit AND (the 64-bit AND takes only six instructions whereas the 128-bit AND requires twelve; therefore, the extra instructions involved in calling math.andl don't completely overshadow the actual work done).

math.divq( left:qword; right:qword; var dest:qword ); 
 
math.divl( left:lword; right:lword; var dest:lword ); 
 

These routines divide two quad-word 64-bit (divq) or long word 128-bit (divl) unsigned integer values. These two routines compute the following:

	dest := left div right;
 

 

Since the 80x86 flags don't contain useful values after the execution of the div instruction, these routines also leave the flags scrambled and you can't count on flag values upon return. This routines will raise an ex.DivideError exception if you attempt a division by zero.

math.idivq( left:qword; right:qword; var dest:qword ); 
 
math.idivl( left:lword; right:lword; var dest:lword ); 
 

These routines divide two quad-word 64-bit (idivq) or long word 128-bit (idivl) signed integer values. These two routines compute the following:

	dest := left div right;
 

 

Since the 80x86 flags don't contain useful values after the execution of the idiv instruction, these routines also leave the flags scrambled and you can't count on flag values upon return. This routines will raise an ex.DivideError exception if you attempt a division by zero.

math.modq( left:qword; right:qword; var dest:qword ); 
 
math.modl( left:lword; right:lword; var dest:lword ); 
 

These routines divide two quad-word 64-bit (modq) or long word 128-bit (modl) unsigned integer values and compute their remainder. These two routines compute the following:

	dest := left mod right;
 

 

Since the 80x86 flags don't contain useful values after the execution of the div instruction, these routines also leave the flags scrambled and you can't count on flag values upon return. This routines will raise an ex.DivideError exception if you attempt a division by zero.

math.imodq( left:qword; right:qword; var dest:qword ); 
 
math.imodl( left:lword; right:lword; var dest:lword ); 
 

These routines divide two quad-word 64-bit (imodq) or long word 128-bit (imodl) signed integer values and compute their remainder. These two routines compute the following:

	dest := left mod right;
 

 

Since the 80x86 flags don't contain useful values after the execution of the idiv instruction, these routines also leave the flags scrambled and you can't count on flag values upon return. This routines will raise an ex.DivideError exception if you attempt a division by zero.

math.imulq( left:qword; right:qword; var dest:qword ); 
 
math.imull( left:lword; right:lword; var dest:lword ); 
 

These routines multiply two quad-word 64-bit (mulq) or long word 128-bit (mull) unsigned integer values and compute their product. These two routines compute the following:

	dest := left * right;
 

 

These instructions set the carry and overflow flags if there is an unsigned overflow during the operation.

math.imulq( left:qword; right:qword; var dest:qword ); 
 
math.imull( left:lword; right:lword; var dest:lword ); 
 

These routines divide two quad-word 64-bit (imodq) or long word 128-bit (imodl) signed integer values and compute their remainder. These two routines compute the following:

	dest := left mod right;
 

 

Since the 80x86 flags don't contain useful values after the execution of the idiv instruction, these routines also leave the flags scrambled and you can't count on flag values upon return. This routines will raise an ex.DivideError exception if you attempt a division by zero.

math.negq( source:qword; var dest:qword ); 
 
math.negl( source:lword; var dest:lword ); 
 

These routines negate the source operand and store the result into the destination operand. These two routines compute the following:

	dest := -source;
 

 

These functions leave the 80x86 flags containing the same values one would expect after the execution of the neg instruction. Extended precision NEG is a trivial operation to compute manually; you should carefully consider whether you really want to use this function since doing the NEG manually isn't a whole lot more work.

math.notq( source:qword; var dest:qword ); 
 
math.notl( source:lword; var dest:lword ); 
 

These routines invert all the bits in the source operand and store the result into the destination operand. These two routines compute the following:

	dest := ~source;
 

 

These functions leave the 80x86 flags containing the same values one would expect after the execution of the not instruction. Extended precision NOT is an especially trivial operation to compute manually; you should carefully consider whether you really want to use this function since doing the NOT manually isn't a whole lot more work.

math.orq( left:qword; right:qword; var dest:qword ); 
 
math.orl( left:lword; right:lword; var dest:lword ); 
 

These routines logically OR two quad-word 64-bit (andq) or long word 128-bit (andl) integer values. These two routines compute the following:

	dest := left | right;
 

 

These routines set the 80x86 flags exactly the same way that the standard OR instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry and overflow flags are both clear.

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision OR requires about the same number of instructions has it takes to simply pass the parameters to the math.orq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision OR sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "three-address" form that allows a different destination address (i.e., the destination does not have to be the same as one of the source operands). Certainly the math.orl routine is more cost effective to use than the math.orq routine, since there's a lot more work involved in doing a 128-bit OR vs. a 64-bit OR (the 64-bit OR takes only six instructions whereas the 128-bit OR requires twelve; therefore, the extra instructions involved in calling math.orl don't completely overshadow the actual work done).

math.shlq( count:uns32; source:qword; var dest:qword ); 
 
math.shll( count:uns32; source:lword; var dest:lword ); 
 

These routines logically shift left a quad-word 64-bit (shlq) or long word 128-bit (shll) integer value the number of bits specified by the count operand. These two routines compute the following:

	dest := source << count;
 

 

These routines set the 80x86 flags exactly the same way that the standard SHL instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry flag contains the last carry out of the H.O. bit, and the overflow flag is set if the last shift caused a sign change.

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision SHL requires fewer instructions than it takes to simply pass the parameters to the math.shlq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision SHL sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "two-address" form that allows a different destination address (i.e., the destination does not have to be the same as the source operand). Certainly the math.shll routine is more cost effective to use than the math.shlq routine, since there's a lot more work involved in doing a 128-bit SHL vs. a 64-bit SHL.

math.shrq( count:uns32; source:qword; var dest:qword ); 
 
math.shrl( count:uns32; source:lword; var dest:lword ); 
 

These routines logically shift right a quad-word 64-bit (shlq) or long word 128-bit (shll) integer value the number of bits specified by the count operand. These two routines compute the following:

	dest := source >> count;
 

 

These routines set the 80x86 flags exactly the same way that the standard SHR instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry flag contains the last carry out of the L.O. bit, and the overflow flag is set if the last shift caused a sign change.

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision SHR requires fewer instructions than it takes to simply pass the parameters to the math.shrq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision SHR sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "two-address" form that allows a different destination address (i.e., the destination does not have to be the same as the source operand). Certainly the math.shrl routine is more cost effective to use than the math.shrq routine, since there's a lot more work involved in doing a 128-bit SHR vs. a 64-bit SHR.

math.subq( left:qword; right:qword; var dest:qword ); 
 
math.subl( left:lword; right:lword; var dest:lword ); 
 

These routines subtract two quad-word 64-bit (subq) or long word 128-bit (subl) integer values. The values may be signed or unsigned. These two routines compute the following:

	dest := left - right;
 

 

These routines set the 80x86 flags exactly the same way that the standard SUB instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry and overflow flags denote unsigned or signed overflow (respectively).

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision subtraction requires about the same number of instructions has it takes to simply pass the parameters to the math.subq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision subtract sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "three-address" form that allows a different destination address (i.e., the destination does not have to be the same as one of the source operands). Certainly the math.subl routine is more cost effective to use than the math.subq routine, since there's a lot more work involved in doing a 128-bit subtraction vs. a 64-bit subtractopm (the quad word takes only six instructions whereas the long word subtraction requires twelve; therefore, the extra instructions involved in calling math.subl don't completely overshadown the actual work done).

The Standard Library does not provide an "SuBtract with Borrow" version of this procedure. If you need to do extended precision arithmetic beyond 128 bits (or some size other than 64 or 128 bits), then use discrete x86 instructions.

math.xorq( left:qword; right:qword; var dest:qword ); 
 
math.xorl( left:lword; right:lword; var dest:lword ); 
 

These routines logically XOR two quad-word 64-bit (xorq) or long word 128-bit (xorl) integer values. These two routines compute the following:

	dest := left ^ right;
 

 

These routines set the 80x86 flags exactly the same way that the standard XOR instruction does. In particular, you may test the zero flag afterwards for a zero result, you can test the sign flag to determine if there was a negative result, the carry and overflow flags are both clear.

Extended precision arithmetic (especially 64-bits) is fairly trivial and an in-line coding of these functions will always be faster than calling these functions. For example, a full 64-bit extended precision XOR requires about the same number of instructions has it takes to simply pass the parameters to the math.xorq routine. Therefore, do not call these routines if performance is important, use in-line code instead. Another reason (beyond the procedure call overhead) that these procedures are slower than the in-line code is that the standard extended precision XOR sequence does not set the zero flag properly; these procedures have to execute several additional instructions to preserve the carry, sign, and overflow flags as well as properly set the zero flag. If you don't use the value of the zero flag upon return, all this extra work goes to waste.

These procedures are convenient to use and are perfectly acceptable when performance is not an issue. Another advantage is that these routines work memory to memory and don't disturb the values in any registers; and also, these routines use a "three-address" form that allows a different destination address (i.e., the destination does not have to be the same as one of the source operands). Certainly the math.orl routine is more cost effective to use than the math.xorq routine, since there's a lot more work involved in doing a 128-bit SXOR vs. a 64-bit XOR (the 64-bit XOR takes only six instructions whereas the 128-bit XOR requires twelve; therefore, the extra instructions involved in calling math.xorl don't completely overshadow the actual work done).

math.cot; @returns( "st0" );					// Macro that overloads the following functions:
 
math._cot;  @returns( "st0" );
 
math.cot32( r32:real32 ); @returns( "st0" );
 
math.cot64( r64: real64 );  @returns( "st0" );
 
math.cot80( r80: real80 );  @returns( "st0" );
 

These five functions compute the cotangent (1/tan) of their parameter value. The parameter value must specify an angle in radians.

The math.cot function is actually a macro that overloads the remaining four functions. If a math.cot invocation doesn't contain any parameters, then this macro expands to a call to the math._cot function which computes the cotangent of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._cot();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.csc
 
math._csc;  @returns( "st0" );
 
math.csc32( r32:real32 ); @returns( "st0" );
 
math.csc64( r64: real64 );  @returns( "st0" );
 
math.csc80( r80: real80 );  @returns( "st0" );
 

These five functions compute the cosecant (1/sin) of their parameter value. The parameter value must specify an angle in radians.

The math.csc function is actually a macro that overloads the remaining four functions. If a math.csc invocation doesn't contain any parameters, then this macro expands to a call to the math._csc function which computes the cosecant of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._csc;" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.sec
 
math._sec;  @returns( "st0" );
 
math.sec32( r32:real32 ); @returns( "st0" );
 
math.sec64( r64: real64 );  @returns( "st0" );
 
math.sec80( r80: real80 );  @returns( "st0" );
 

These five functions compute the secant (1/cos) of their parameter value. The parameter value must specify an angle in radians.

The math.sec function is actually a macro that overloads the remaining four functions. If a math.sec invocation doesn't contain any parameters, then this macro expands to a call to the math._sec function which computes the secant of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._sec();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.asin
 
math._asin;  @returns( "st0" );
 
math.asin32( r32:real32 ); @returns( "st0" );
 
math.asin64( r64: real64 );  @returns( "st0" );
 
math.asin80( r80: real80 );  @returns( "st0" );
 

These five functions compute the arc sine (sin-1) of their parameter value. They return an angle in radians.

The math.asin function is actually a macro that overloads the remaining four functions. If a math.asin invocation doesn't contain any parameters, then this macro expands to a call to the math._asin function which computes the arc sin of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._asin();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.acos
 
math._acos;  @returns( "st0" );
 
math.acos32( r32:real32 ); @returns( "st0" );
 
math.acos64( r64: real64 );  @returns( "st0" );
 
math.acos80( r80: real80 );  @returns( "st0" );
 

These five functions compute the arc cosine (cos-1) of their parameter value. They return an angle in radians.

The math.acos function is actually a macro that overloads the remaining four functions. If a math.acos invocation doesn't contain any parameters, then this macro expands to a call to the math._acos function which computes the arc cosine of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._acos();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.acot
 
math._acot;  @returns( "st0" );
 
math.acot32( r32:real32 ); @returns( "st0" );
 
math.acot64( r64: real64 );  @returns( "st0" );
 
math.acot80( r80: real80 );  @returns( "st0" );
 

These five functions compute the arc cotangent (cot-1) of their parameter value. They return an angle in radians.

The math.acos function is actually a macro that overloads the remaining four functions. If a math.acos invocation doesn't contain any parameters, then this macro expands to a call to the math._acos function which computes the arc cotangent of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._acos();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.acsc
 
math._acsc;  @returns( "st0" );
 
math.acsc32( r32:real32 ); @returns( "st0" );
 
math.acsc64( r64: real64 );  @returns( "st0" );
 
math.acsc80( r80: real80 );  @returns( "st0" );
 

These five functions compute the arc cosecant (csc-1) of their parameter value. They return an angle in radians.

The math.acsc function is actually a macro that overloads the remaining four functions. If a math.acsc invocation doesn't contain any parameters, then this macro expands to a call to the math._acsc function which computes the arc cosecant of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._acsc();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.asec
 
math._asec;  @returns( "st0" );
 
math.asec32( r32:real32 ); @returns( "st0" );
 
math.asec64( r64: real64 );  @returns( "st0" );
 
math.asec80( r80: real80 );  @returns( "st0" );
 

These five functions compute the arc secant (sec-1) of their parameter value. They return an angle in radians.

The math.asec function is actually a macro that overloads the remaining four functions. If a math.asec invocation doesn't contain any parameters, then this macro expands to a call to the math._asec function which computes the arc secant of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._asec();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.twoToX
 
math._twoToX;  @returns( "st0" );
 
math.twoToX32( r32:real32 ); @returns( "st0" );
 
math.twoToX64( r64: real64 );  @returns( "st0" );
 
math.twoToX80( r80: real80 );  @returns( "st0" );
 

These five functions compute 2x of their parameter value (which is the value of x).

The math.twoToX function is actually a macro that overloads the remaining four functions. If a math.twoToX invocation doesn't contain any parameters, then this macro expands to a call to the math._twoToX function which computes 2x of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._twoToX();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.TenToX
 
math._tenToX;  @returns( "st0" );
 
math.tenToX32( r32:real32 ); @returns( "st0" );
 
math.tenToX64( r64: real64 );  @returns( "st0" );
 
math.tenToX80( r80: real80 );  @returns( "st0" );
 

These five functions compute 10x of their parameter value (which is the value of x).

The math.tenToX function is actually a macro that overloads the remaining four functions. If a math.tenToX invocation doesn't contain any parameters, then this macro expands to a call to the math._tenToX function which computes the 10x of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._tenToX();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.exp
 
math._exp;  @returns( "st0" );
 
math.exp32( r32:real32 ); @returns( "st0" );
 
math.exp64( r64: real64 );  @returns( "st0" );
 
math.exp80( r80: real80 );  @returns( "st0" );
 

These five functions compute ex of their parameter value (which is the value of x).

The math.exp function is actually a macro that overloads the remaining four functions. If a math.exp invocation doesn't contain any parameters, then this macro expands to a call to the math._exp function which computes ex of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._exp();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.ytoX;  @returns( "st0" );
 
math._yToX;					// Y is at ST1, X is at ST0.
 
math.yToX32( y32Var, x32Var ); @returns( "st0" );
 
math.yToX64( y64Var, x64Var ); @returns( "st0" );
 
math.yToX80( y80Var, x80Var ); @returns( "st0" );
 

These five functions compute Yx of their parameter values (which are the values of y and x).

The math.yToX function is actually a macro that overloads the remaining four functions. If a math.yToX invocation doesn't contain any parameters, then this macro expands to a call to the math._yToX function which computes Yx using the values on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._yToX();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.log
 
math._log;  @returns( "st0" );
 
math.log32( r32:real32 ); @returns( "st0" );
 
math.log64( r64: real64 );  @returns( "st0" );
 
math.log80( r80: real80 );  @returns( "st0" );
 

These five functions compute log10(x) of their parameter value (which is the value of x).

The math.log function is actually a macro that overloads the remaining four functions. If a math.log invocation doesn't contain any parameters, then this macro expands to a call to the math._log function which computes the base 10 log of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._log();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.

math.ln
 
math._ln;  @returns( "st0" );
 
math.ln32( r32:real32 ); @returns( "st0" );
 
math.ln64( r64: real64 );  @returns( "st0" );
 
math.ln80( r80: real80 );  @returns( "st0" );
 

ln( x ) [loge(x)]

These five functions compute loge(x) of their parameter value (which is the value of x).

The math.ln function is actually a macro that overloads the remaining four functions. If a math.ln invocation doesn't contain any parameters, then this macro expands to a call to the math._ln function which computes the base e log of the value on the FPU stack (ST0). With a single real parameter, the macro expands to one of the other three functions with the appropriate parameter type.

The "math._ln();" call expects the parameter on the FPU stack, the other three forms pass their parameter by value on the stack using the standard HLA parameter passing mechanism.



TOC PREV NEXT INDEX