2018-07-18 12:39:53 +00:00
|
|
|
/* Float arithmetic
|
|
|
|
*
|
|
|
|
* (c) Copyright 1999, Artran, Inc.
|
|
|
|
* Written by Greg Garner (gmg@artran.com)
|
|
|
|
* Modified in March 2001 to include user defined
|
|
|
|
* operators for the floating point functions.
|
|
|
|
*
|
|
|
|
* This file is provided as is (no warranties).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if defined _float_included
|
|
|
|
#endinput
|
|
|
|
#endif
|
|
|
|
#define _float_included
|
|
|
|
|
|
|
|
#pragma rational Float
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Different methods of rounding
|
|
|
|
*/
|
|
|
|
enum floatround_method {
|
|
|
|
floatround_round = 0,
|
|
|
|
floatround_floor,
|
|
|
|
floatround_ceil,
|
|
|
|
floatround_tozero
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Different units of measurement for angles
|
|
|
|
*/
|
|
|
|
enum anglemode {
|
|
|
|
radian = 0,
|
|
|
|
degrees,
|
|
|
|
grades
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts an integer into a floating point value.
|
|
|
|
*
|
|
|
|
* @param value Value to be converted
|
|
|
|
*
|
|
|
|
* @return Converted value
|
|
|
|
*/
|
|
|
|
native Float:float(value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a string into a floating point value.
|
|
|
|
*
|
|
|
|
* @param string Input string to be converted
|
|
|
|
*
|
|
|
|
* @return Converted value
|
|
|
|
*/
|
|
|
|
native Float:floatstr(const string[]);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the fractional part of a floating point value
|
|
|
|
*
|
|
|
|
* @param string Floating point value to get the fractional part from
|
|
|
|
*
|
|
|
|
* @return The fractional part
|
|
|
|
*/
|
|
|
|
native Float:floatfract(Float:value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rounds a floating point value to an integer value
|
|
|
|
*
|
|
|
|
* @note For the list of available rounding methods look at
|
|
|
|
* floatround_method enumeration.
|
|
|
|
*
|
|
|
|
* @param value Floating point value to be rounded
|
|
|
|
* @param method Rounding method
|
|
|
|
*
|
|
|
|
* @return Converted value
|
|
|
|
*/
|
|
|
|
native floatround(Float:value, floatround_method:method=floatround_round);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compares two floating point values.
|
|
|
|
*
|
|
|
|
* @param fOne First value to be compared
|
|
|
|
* @param fTwo Second value to be compared
|
|
|
|
*
|
|
|
|
* @return If arguments are equal, returns 0.
|
|
|
|
* If the first one is greater, returns 1.
|
|
|
|
* If the second one is greater, returns -1.
|
|
|
|
*/
|
|
|
|
native floatcmp(Float:fOne, Float:fTwo);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the square root of a floating point value
|
|
|
|
*
|
|
|
|
* @note Same as floatpower(value, 0.5)
|
|
|
|
*
|
|
|
|
* @param value Floating point value to get square root from
|
|
|
|
*
|
|
|
|
* @return Square root of the input value
|
|
|
|
*/
|
|
|
|
native Float:floatsqroot(Float:value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the value raised to the power of the exponent
|
|
|
|
*
|
|
|
|
* @param value Floating point value to be raised
|
|
|
|
* @param exponent The exponent
|
|
|
|
*
|
|
|
|
* @return Value raised to the power of the exponent
|
|
|
|
*/
|
|
|
|
native Float:floatpower(Float:value, Float:exponent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the logarithm of value
|
|
|
|
*
|
|
|
|
* @param value Floating point value to calculate the logarithm for
|
|
|
|
* @param base The optional logarithmic base to use.
|
|
|
|
* Defaults to 10, or the natural logarithm
|
|
|
|
*
|
|
|
|
* @return Square root of the input value
|
|
|
|
*/
|
|
|
|
native Float:floatlog(Float:value, Float:base=10.0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the sine of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the sine from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The sine of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floatsin(Float:value, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the cosine of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the cosine from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The cosine of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floatcos(Float:value, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the tangent of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the tangent from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The tangent of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floattan(Float:value, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the hyperbolic sine of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the hyperbolic sine from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The hyperbolic sine of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floatsinh(Float:angle, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the hyperbolic cosine of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the hyperbolic cosine from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The hyperbolic cosine of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floatcosh(Float:angle, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the hyperbolic tangent of a given angle
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The angle to calculate the hyperbolic tangent from
|
|
|
|
* @param mode What unit of measurement is the angle specified in
|
|
|
|
* Defaults to radians
|
|
|
|
*
|
|
|
|
* @return The hyperbolic tangent of a given angle
|
|
|
|
*/
|
|
|
|
native Float:floattanh(Float:angle, anglemode:mode=radian);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the absolute value of a floating point value
|
|
|
|
*
|
|
|
|
* @param value The floating point value to get the absolute value from
|
|
|
|
*
|
|
|
|
* @return The absolute value
|
|
|
|
*/
|
|
|
|
native Float:floatabs(Float:value);
|
|
|
|
|
|
|
|
/* Return the angle of a sine, cosine or tangent.
|
|
|
|
* The output angle may be in radians, degrees, or grades. */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the angle of the given tangent
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The tangent to calculate the angle from
|
|
|
|
* @param mode What unit of measurement should the output angle be in
|
|
|
|
*
|
|
|
|
* @return The angle of a tangent
|
|
|
|
*/
|
|
|
|
native Float:floatatan(Float:angle, {anglemode,_}:radix);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the angle of the given cosine
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The cosine to calculate the angle from
|
|
|
|
* @param mode What unit of measurement should the output angle be in
|
|
|
|
*
|
|
|
|
* @return The angle of a cosine
|
|
|
|
*/
|
|
|
|
native Float:floatacos(Float:angle, {anglemode,_}:radix);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the angle of the given sine
|
|
|
|
*
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param value The sine to calculate the angle from
|
|
|
|
* @param mode What unit of measurement should the output angle be in
|
|
|
|
*
|
|
|
|
* @return The angle of a sine
|
|
|
|
*/
|
|
|
|
native Float:floatasin(Float:angle, {anglemode,_}:radix);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Computes the principal value of arctangent of y/x
|
|
|
|
*
|
|
|
|
* @note Someone should verify this native, not sure what it actually does.
|
|
|
|
* @note For available units of measurements(modes) look at the anglemode enum
|
|
|
|
*
|
|
|
|
* @param x Value representing the proportion of the x-coordinate.
|
|
|
|
* @param y Value representing the proportion of the x-coordinate.
|
|
|
|
* @param mode What unit of measurement should the output angle be in
|
|
|
|
*
|
|
|
|
* @return Arctangent of y/x
|
|
|
|
*/
|
|
|
|
native Float:floatatan2(Float:x, Float:y, {anglemode,_}:radix);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Multiply two floats together */
|
|
|
|
native Float:floatmul(Float:oper1, Float:oper2);
|
|
|
|
|
|
|
|
/* Divide the dividend float by the divisor float */
|
|
|
|
native Float:floatdiv(Float:dividend, Float:divisor);
|
|
|
|
|
|
|
|
/* Add two floats together */
|
|
|
|
native Float:floatadd(Float:dividend, Float:divisor);
|
|
|
|
|
|
|
|
/* Subtract oper2 float from oper1 float */
|
|
|
|
native Float:floatsub(Float:oper1, Float:oper2);
|
|
|
|
|
|
|
|
/* user defined operators */
|
|
|
|
native Float:operator*(Float:oper1, Float:oper2) = floatmul;
|
|
|
|
native Float:operator/(Float:oper1, Float:oper2) = floatdiv;
|
|
|
|
native Float:operator+(Float:oper1, Float:oper2) = floatadd;
|
|
|
|
native Float:operator-(Float:oper1, Float:oper2) = floatsub;
|
|
|
|
|
|
|
|
stock Float:operator++(Float:oper)
|
|
|
|
return oper+1.0;
|
|
|
|
|
|
|
|
stock Float:operator--(Float:oper)
|
|
|
|
return oper-1.0;
|
|
|
|
|
|
|
|
stock Float:operator-(Float:oper)
|
|
|
|
return oper^Float:cellmin; /* IEEE values are sign/magnitude */
|
|
|
|
|
|
|
|
stock Float:operator*(Float:oper1, oper2)
|
|
|
|
return floatmul(oper1, float(oper2)); /* "*" is commutative */
|
|
|
|
|
|
|
|
stock Float:operator/(Float:oper1, oper2)
|
|
|
|
return floatdiv(oper1, float(oper2));
|
|
|
|
|
|
|
|
stock Float:operator/(oper1, Float:oper2)
|
|
|
|
return floatdiv(float(oper1), oper2);
|
|
|
|
|
|
|
|
stock Float:operator+(Float:oper1, oper2)
|
|
|
|
return floatadd(oper1, float(oper2)); /* "+" is commutative */
|
|
|
|
|
|
|
|
stock Float:operator-(Float:oper1, oper2)
|
|
|
|
return floatsub(oper1, float(oper2));
|
|
|
|
|
|
|
|
stock Float:operator-(oper1, Float:oper2)
|
|
|
|
return floatsub(float(oper1), oper2);
|
|
|
|
|
|
|
|
stock bool:operator==(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) == 0;
|
|
|
|
|
|
|
|
stock bool:operator==(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) == 0; /* "==" is commutative */
|
|
|
|
|
|
|
|
stock bool:operator!=(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) != 0;
|
|
|
|
|
|
|
|
stock bool:operator!=(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) != 0; /* "==" is commutative */
|
|
|
|
|
|
|
|
stock bool:operator>(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) > 0;
|
|
|
|
|
|
|
|
stock bool:operator>(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) > 0;
|
|
|
|
|
|
|
|
stock bool:operator>(oper1, Float:oper2)
|
|
|
|
return floatcmp(float(oper1), oper2) > 0;
|
|
|
|
|
|
|
|
stock bool:operator>=(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) >= 0;
|
|
|
|
|
|
|
|
stock bool:operator>=(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) >= 0;
|
|
|
|
|
|
|
|
stock bool:operator>=(oper1, Float:oper2)
|
|
|
|
return floatcmp(float(oper1), oper2) >= 0;
|
|
|
|
|
|
|
|
stock bool:operator<(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) < 0;
|
|
|
|
|
|
|
|
stock bool:operator<(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) < 0;
|
|
|
|
|
|
|
|
stock bool:operator<(oper1, Float:oper2)
|
|
|
|
return floatcmp(float(oper1), oper2) < 0;
|
|
|
|
|
|
|
|
stock bool:operator<=(Float:oper1, Float:oper2)
|
|
|
|
return floatcmp(oper1, oper2) <= 0;
|
|
|
|
|
|
|
|
stock bool:operator<=(Float:oper1, oper2)
|
|
|
|
return floatcmp(oper1, float(oper2)) <= 0;
|
|
|
|
|
|
|
|
stock bool:operator<=(oper1, Float:oper2)
|
|
|
|
return floatcmp(float(oper1), oper2) <= 0;
|
|
|
|
|
|
|
|
stock bool:operator!(Float:oper)
|
|
|
|
return (_:oper & ((-1)/2)) == 0; /* -1 = all bits to 1; /2 = remove most significant bit (sign)
|
|
|
|
works on both 32bit and 64bit systems; no constant required */
|
|
|
|
/* forbidden operations */
|
|
|
|
forward operator%(Float:oper1, Float:oper2);
|
|
|
|
forward operator%(Float:oper1, oper2);
|
|
|
|
forward operator%(oper1, Float:oper2);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whichever value is the smaller one
|
|
|
|
*
|
|
|
|
* @param ValueA The first value
|
|
|
|
* @param ValueB The second value
|
|
|
|
*
|
|
|
|
* @return ValueA if it is smaller than ValueB, and vice versa
|
|
|
|
*/
|
|
|
|
stock Float:floatmin(Float:ValueA, Float:ValueB)
|
|
|
|
{
|
|
|
|
if (ValueA<=ValueB)
|
|
|
|
{
|
|
|
|
return ValueA;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ValueB;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whichever value is the greater one
|
|
|
|
*
|
|
|
|
* @param ValueA The first value
|
|
|
|
* @param ValueB The second value
|
|
|
|
*
|
|
|
|
* @return ValueA if it is greater than ValueB, and vice versa
|
|
|
|
*/
|
|
|
|
stock Float:floatmax(Float:ValueA, Float:ValueB)
|
|
|
|
{
|
|
|
|
if (ValueA>=ValueB)
|
|
|
|
{
|
|
|
|
return ValueA;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ValueB;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clamps a value between a minimum and a maximum floating point value
|
|
|
|
*
|
|
|
|
* @param Value The value to be clamped
|
|
|
|
* @param MinValue Minimum value
|
|
|
|
* @param MaxValue Maximum value
|
|
|
|
*
|
|
|
|
* @return The Value clamped between MinValue and MaxValue
|
|
|
|
*/
|
|
|
|
stock Float:floatclamp(Float:Value, Float:MinValue, Float:MaxValue)
|
|
|
|
{
|
|
|
|
if (Value<=MinValue)
|
|
|
|
{
|
|
|
|
return MinValue;
|
|
|
|
}
|
|
|
|
if (Value>=MaxValue)
|
|
|
|
{
|
|
|
|
return MaxValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Value;
|
2017-12-08 23:22:43 +00:00
|
|
|
}
|