category-group: math
layer: 0
header file(s): z_mathsubs.h

synopsis.
The bulk of the math functions (not including class objects in the math domain) are contained here.

description.
Often, the math routines here that involve a list of numbers do not have bounds checking. They were written a long time ago, and where noted the interfaces may be cleaned up. Thus, using them would entail code breakage. Though this type of evolution is a someone rare event, it can happen. Hopefully doing the modifications will not be too painful on you.

most system-provided random number generators involve a bit of a learning curve, requiring you to study the meanings and usage of things like initstate(), setstate(), knowing the difference between rand(), srand() and srandom(), and having to supply massive lists of nubmers they call "state arrays". Vettrasoft considers that garbage knowledge arcane. We assume you pretty much know what a random number is, and would prefer to call z_big_random_number() to get your random number. However, a minimal bit of knowledge is in order: a random number occurs within a range of values, and most RNGs operate in 2 types of ranges: [0 .. 1], and from 0 to [a really big number]. Sometimes you need to know what those upper and lower bounds are. Hence, the functions z_max_random_number_value() and z_min_random_number_value().

Note also that at this layer, there is no provision to set the range of values for a random number (for that, please see the RNG_o class in layer 10). You can get values in a range by doing the following:

    int ie;
    count_t value, Min_Val = 10, Max_Val = 100;
    count_t n, val;

// [method 1] val = z_big_random_number (&ie); n = val + Min_Val; // make sure value is above the min. n = n % Max_Val; // this is it

// OR [method 2] count_t abs_val = z_max_random_number_value(); count_t j = abs_val / Max_Val + 1; val = z_big_random_number (&ie); val += Min_Val; val /= j;

[C] functions (aka subroutines):

z_column_value ()()
SIGNATURE: int z_column_value (count_t num, int col)
SYNOPSIS: return a digit's value, for specific digit-column
HEADER FILE: z_func.h
EXAMPLE:
lextract_digit (512, 0) = 2;
lextract_digit (512, 1) = 1;
lextract_digit (512, 2) = 5;

RETURNS: [value, 0..9]: value of the digit (base 10) -1: error (probably 'col' variable out of bounds)
 

z_num_digits()
SIGNATURE: int z_num_digits (count_t num)
SYNOPSIS: counts the number of digits in a number
HEADER FILE: z_func.h
EXAMPLE:

z_num_digits(6) -> 1
z_num_digits(15) -> 2
z_num_digits(1960) -> 4

 

get_rightmost_digit()
SIGNATURE: int get_rightmost_digit (double)
SYNOPSIS: yields the digit value in the "1's column" of a floating point number
HEADER FILE: z_func.h
 

istrchr()
SIGNATURE: int *istrchr (int *intbuff, int j)
SYNOPSIS: get pointer to a number, if found in an array of numbers. finds "j" in "intbuff[]"
HEADER FILE: z_func.h
TRAITS: a strange function; of dubious value
 

istrlen()
SIGNATURE: int istrlen (int *)
SYNOPSIS: returns index position of the first zero value in an array of integers
HEADER FILE: z_func.h
TRAITS: another strange function of dubious value
 

z_sum()
SIGNATURE: double z_sum (double *x, count_t n)
SYNOPSIS: the sum of the values in the array of real numbers "x". the number of elements to sum (length of the arrray) is "n"
WARNING: it is up to the user to provide good, valid input values
TRAITS: this function interface could be shored up
 

z_sum_darray()
SIGNATURE: double z_sum_darray (double *, cout_t)
SYNOPSIS: same as z_sum()
TRAITS: don't use; to be phased out
 

z_sum_sequence()
SIGNATURE: long z_sum_sequence (count_t lo, count_t hi, int *pi = NULL)
SYNOPSIS: calculate and return the sum of a sequence of integers specified by range [lo, hi]
EXAMPLE: z_sum_sequence(4,8) -> 4+5+6+7+8 z_sum_sequence(-3,5) -> -3-2-1+1+2+3+4+5
 

z_lcd()
SIGNATURE: count_t z_lcd (count_t *ival, count_t n, int *pi = NULL)
SYNOPSIS: computes the LCD (Least Common Denominator) of a list of numbers
PARAMETERS

  • ival - array of "countables"
  • n - the number of elements in 'ival'
  • pie - error indicator output variable. values:
  • 0: success
  • 1: bad user input (in the parameters)
  • 2: too many prime factors (a really big number)
RETURNS:
[value] - the result
-1: error occured (see output var)
WARNING: computationally very expensive. It may take a while
 

z_lcd_2vals()
SIGNATURE: count_t z_lcd_2vals (count_t, count_t, int *pi = NULL)
SYNOPSIS: computes the LCD (Least Common Denominator) for 2 numbers
 

z_factor()
SIGNATURE: int z_factor (count_t num, count_t primes[])
SYNOPSIS: provides the factors, aka divisors (up to 1024) of a number
DESCRIPTION:
provide a [large] array of countables ("count_t") to this function, as parameter 'primes'. That array will recieve the factors for a number.
EXAMPLE:
z_factor (10, primes[])
primes[0] = 1;
primes[1] = 2;
primes[2] = 5;
WARNING:
this function has the potential to overflow the output parameter! you'll be safe if you use an array with z_Maxnum_LCD_Factors number of elements (== 1024)
TRAITS: a rather odd parameter list

 

is_z_prime()
SIGNATURE: boolean is_z_prime (count_t n, int *pi = NULL)
SYNOPSIS: determine if a number is prime
PARAMETERS

  • n - the number to evaluate.
  • pi - [output] error indicator variable. Although this parameter is optional, it is STRONGLY ADVISED that you include it, as there are many values of 'n' that are unappropriate for this function. values:
    0: evaluation completed successfully
    zErr_Param_BadVal: 'n' is negative
WARNING: computationally expensive. Also,
 

z_num_digits()
SIGNATURE: count_t z_num_digits (count_t x, int base = 10, int *pi = NULL)
SYNOPSIS: returns the number of digits in the value, depending on the base.
EXAMPLE:
z_num_digits(66); // returns 2
z_num_digits(20, 16); // 20 -> 0x14; answer is 2
z_num_digits(20, 2); // 20 -> 010100; answer is 6
z_num_digits(90000); // returns 5
 

z_is_divisible_by()
SIGNATURE: boolean z_is_divisible_by (count_t num, count_t other)
SYNOPSIS: tests division of one number by another
EXAMPLE:
z_is_divisible_by (16, 3) -> FALSE
z_is_divisible_by (16, 4) -> TRUE
 

z_dmod()
SIGNATURE: double z_dmod (double num, double mod)
SYNOPSIS:
returns the remainder, or modulus, of division. for real numbers. Essentially a "%" for type double. Mathematically, this operation can be written thus:
z_dmod(a, b) = int (a - int(a/b)*b)
EXAMPLE: z_dmod (14.5, 3.0) -> 2.0
 

z_lcm()
SIGNATURE: count_t z_lcm (count_t x, count_t y)
SYNOPSIS:
returns "lowest common multiple" of 2 integers:

z_lcm (400, 500);       // returns 2,000
z_lcm (50,  150);       // returns 150
z_lcm (10, 15);         // returns 30
z_lcm (13, 7);          // returns 91
If the numbers are prime, returns x * y.
RETURNS:
[value > 0] - the result
0: error, user passed a bad parameter(s) in [x or y <= 1]
 

z_ilum()
SIGNATURE: count_t z_ilum (count_t num, count_t mult)
SYNOPSIS:
returns the "least upper multiple"; this is similar to z_lub(), but instead of rounding to the nearest integer, it rounds to the nearest unit of "mult".
EXAMPLE:

z_ilum (25, 100) = 100
z_ilum (40,  50) =  50
z_ilum (10,   3) =  12
z_ilum (5,    3) =   6

 

z_glb()
SIGNATURE: count_t z_glb (count_t num, count_t mult)
SYNOPSIS:
returns the integer "greatest lower bound"; this is similar to z_glb(), but is for integral values. Examples:

z_glb(401, 100);      // returns 400
z_glb(85, 9);         // returns 81

 

z_lub()
SIGNATURE: double z_lub (double base, double units)
SYNOPSIS:
find the least upper bound (LUB), the value that is less than the first parameter, and is the product of the second parameter with the largest possible integer value
EXAMPLE: lub (0.89, 0.1) -> 0.9
 

z_glb()
SIGNATURE: double z_glb (double base, double units)
SYNOPSIS:
yeilds the greatest lower bound (GLB), ie the value greater than "base" (the first parameter), which is the product of the second parameter to the smallest possible integer
EXAMPLE:
glb (0.89, 0.1) -> 0.8
glb (-66.29, 2.5) -> -67.5
 

z_iabs()
SIGNATURE: count_t z_iabs (count_t x)
SYNOPSIS: returns the absolute value of an integer-type number (int, long int, size_t).
 

z_abs()
SIGNATURE: double z_abs (double x)
SYNOPSIS: returns the absolute value of a floating-point number (float or double).
 

z_lround()
SIGNATURE: long z_lround (double)
SYNOPSIS: rounds a floating-point number (up or down).
 

z_ln()
SIGNATURE: double z_ln (double)
SYNOPSIS: calculates natural logarithm
 

z_squareroot()
SIGNATURE: double z_squareroot (double a, int *pi = NULL)
SYNOPSIS: exponentiation: calcuates a^b, for floating-point values
 

z_power()
SIGNATURE: double z_power (double a, double b, int *pi = NULL)
SYNOPSIS: exponentiation: calcuates a^b, for floating-point values
RETURNS:
[value >= 0.0] - the result; a^b
-1: error occured (bad input value; probably a < 0)
 

z_intpower()
SIGNATURE: count_t z_intpower (count_t a, count_t b, int *pi = NULL)
SYNOPSIS: returns a^b; for integer types. checks for a < 0
 

z_realnum_lookslike_one()
SIGNATURE: boolean z_realnum_lookslike_one (double d, double accu = zNum_EPSILON, int *pi = FALSE)
SYNOPSIS:
you set a real number variable to 1:

  double dx = 1;
how can you know it's value is exactly "1", when the value of a float or double is an approximation? You can call this subroutine to check it. it returns TRUE if 'd' is 1 (plus or minus the "accuracy" value, as set in the 2nd parameter, 'accu'. its default value is 0.0001).
This subroutine is a simple specialization of the routine 'z_realnum_lookslike_this_intval()', using a value of 1. See its documentation for infor about the parameters.
RETURNS:
TRUE: value of d is "exactly" 1
FALSE: otherwise
 

z_realnum_lookslike_this_intval()
SIGNATURE: boolean z_realnum_lookslike_this_intval (double d, count_t x, double accu = zNum_EPSILON, int *pi = FALSE)
SYNOPSIS:
how do you know the value of a "real" type variable (double or float) is exactly that of a specific integer-type variable (int, long int, unsigned int, etc)? call this function.
PARAMETERS

  • d - the real-type variable to inspect
  • x - the integer-type variable to compare 'd' to
  • accu - the "accuracy" factor. This double-type variable's value should be very small. "zNum_EPSILON" (0.0001) is the default value. You don't need to specify it.
  • pi - [output] error indicator variable. values:
    0: all ok. a successful check
    zErr_Param_TooBig: the value of 'accu' exceeds 1.0; the comparison is nonsensicle
RETURNS:
TRUE: value of d is "exactly" the value of 'x'
FALSE: otherwise
 

is_z_within()
SIGNATURE: boolean is_z_within (double x, double val, double in)
SYNOPSIS: tells if two numbers are "approximately equal". checks if val is in the interval [x - in, x + in]
DESCRIPTION:
this routine could be a substitutes for the inaccuracies resulting from this kind of comparision:

"double a, b; if (a == b) .."
It should be used when equality of two real numbers is to be regarded as when the numbers are 'mighty close', leaving the application (that means you) to interpret the meaning of "close".
EXAMPLE:
If you have 50.0001, and 49.9987291, and you regard them as equal if within an error of .01, this function can be used like so:
is_z_within (50.0001, 49.9987291, .01);

RETURNS:
TRUE: the #'s are equal, within the given interval
FALSE: "var" is outside the interval
 

z_max_random_number_value()
SIGNATURE: count_t z_max_random_number_value ()
SYNOPSIS:
returns the the maximum value possible for random numbers returned from z_big_random_number(). This function does not let you set a maximum value, it just tells you what the maximum value will be. See more on the discussion in this section.
 

z_min_random_number_value()
SIGNATURE: count_t z_min_random_number_value ()
SYNOPSIS: the minimum value of a random number (invariably, it is 0). See discussion below.
 

z_big_random_number()
SIGNATURE: count_t z_big_random_number (int * = NULL)
SYNOPSIS: returns a random number in the interval [0 .. < BIG #>]
 

 

z_random_number_viatime()
SIGNATURE: count_t z_random_number_viatime (int *pi = NULL)
SYNOPSIS: returns a random number in the interval [0 .. < BIG #>]
DESCRIPTION:
this is virtually identical to z_big_random_number(), but spins the result by basing the number on the current time. This is generally an improvement on its sibling function.
 

z_init_random()
SIGNATURE: int z_init_random (count_t, int)
SYNOPSIS:
initialize the random number generator. Usage of this function is unnecessary, as it is called internally by other functions in this group.
 

z_cumulative_normal()
SIGNATURE: double z_cumulative_normal (double x)
SYNOPSIS: calculates the integral of the normal value distribution function.
DESCRIPTION:
this estimates the value of the integral of the normal function (from -oo to x), or, in other words, computes the cumulative normal value for a given x. it does so by using a degree-5 polynomial that fits the curve within .00000015.

it is a very good approximation to the normal distribution function. negative values of y are obtained by adjustment at end of the function. This is the "default subroutine" for values of this curve. Another routine ("version 2") that approximates the curve is found below.
 

z_cumulative_normal_v2()
SIGNATURE: double z_cumulative_normal_v2 (double)
SYNOPSIS: calculates the integral of the normal value distribution function.
DESCRIPTION:
This function implements the equation "B(z) * e^(-x*x/2) / sqrt(2*PI)", where B(z) = .937298 * k^3 - .120168 * k^2 + .436184 * k, and k = 1/ (.33267 * |x| + 1).
this routine yields normal values within .00002. It is slightly less accurate than that of "cumnorm ()". however, this routine should be slightly faster. it uses the same basic types of equations, except for a 3rd degree polynomial, instead of one of degree 5.
 

z_normal_distribution()
SIGNATURE: double z_normal_distribution (double)
SYNOPSIS: retuns the value of the normal distribution at a given point
DESCRIPTION:
This function simply implements this equation:

e ^ (-x*x/2) / sqrt (2 * PI)

 

z_linear_regression()
SIGNATURE: int z_linear_regression (double *x, double *y, count_tn, double *m, double *b)
SYNOPSIS: computes regression line slope and intercept
PARAMETERS

  • x - an array of doubles, of x-values
  • y - an array of y values. The array must be same length as x
  • n - the number of points (eg, # of elements in x[], y[])
  • m - the slope. this should point to a single variable (not an array)
  • m - the abscissa. also should be a pointer to a single variable
DESCRIPTION:
given 2 arrays of data of equal length, and the number of points, this computes the slope ('m') and abscissa ('b') of the regression line (y = mx + b)
 

z_std_deviation()
SIGNATURE: double z_std_deviation (double x[], count_t n)
SYNOPSIS:
compute the standard deviation for a set of numbers. provide an array of values in "x" and the number of elements in "n"
WARNING: error checking is weak.
 

z_mean_avg()
SIGNATURE: double z_mean_avg (double *dvals, count_t n)
SYNOPSIS: computes the mean average of an array of doubles.
 

z_roman_to_int()
SIGNATURE: z_roman_to_int (const char *buf, int *pi = NULL)
SYNOPSIS:
converts the value of a Roman numeral, stored in 'buf', to a [regular digital] number. The contents of 'buf' must be of valid format for Roman numbering, consisting of the letters 'I', 'V', 'X', 'L', 'C', 'D', or 'M'.
PARAMETERS

  • buf [input] - a null-terminated character buffer containing the roman numeral to evaluate and convert to decimal.
  • pi [output] - error indicator variable. values:
    0: all ok. successful conversion
    zErr_Param_NullPointer: 'buf' is NULL;
    zErr_Param_NotSet: 'buf' is empty;
    zErr_Param_BadFormat: 'buf' contains illegal characters;
    zErr_Param_BadVal: the number represented by the contents of 'buf' does not represent a valid Roman numeral.
RETURNS:
[value >= 0] - the value of 'buf', as a regular [decimal] integer number;
-1: error (see 'pi')
 

z_int_to_roman()
SIGNATURE: z_int_to_roman (const int n, char *buf, int *pi = NULL)
SYNOPSIS:
converts a regular int-type [digital] number to Roman format. You must supply a character array buffer large enough to hold the result. The answer will be in upper-case Roman characters ('I', 'V', 'X', 'L', 'C', 'D', or 'M') and be null-terminated.
The value of 'n' must be positive and no greater than 10,000.
PARAMETERS

  • n: the number to convert.
  • buf [output] - a null-terminated character buffer containing the roman numeral to evaluate and convert to decimal.
  • pi [output] - error indicator variable. values:
    0: success
    zErr_Param_NullPointer: 'buf' is NULL
    zErr_Param_OuttaBounds: 'n' is negative or > 10000
RETURNS:
[n >= 0] - the number of digits in 'buf'
-1: error (see 'pi' - probably 'n' is out of range)
 

note.
All subroutines here use the header file z_mathsubs.h unless otherwise explicitly stated.

Most of the functions here, when they interact with a floating-point number, it is almost invariably of type "double". Type "float" is considered almost pointless in the Z Directory.

history.

??? 12/23/1988: z_lub(), z_glb() created
??? 07/06/1996: name changes; ex, "std()" -> "z_std_deviation()"
Fri 04/25/1997: z_intpower() put into z dir
Sat 11/15/1997: z_big_random_number() ported to hp-ux
Mon 12/09/1996: z_lcd() written
Sat 11/15/1997: {23:10:42 EST} ported random number funcs to hp-ux
Thu 08/09/2001: moved cumu. normal dist. functions; math.c -> stat.c