=head1	NAME

dkma - mathematical operations

=head1	SYNOPSIS

  #include <dkma.h>

  int dkma_get_error (int del);
  
  unsigned long dkma_add_ulong_ok (
    unsigned long u1, unsigned long u2, int *ok
  );
  unsigned long dkma_sub_ulong_ok ( 
    unsigned long u1, unsigned long u2, int *ok
  );
  unsigned long dkma_mul_ulong_ok (
    unsigned long u1, unsigned long u2, int *ok
  );
  unsigned long dkma_div_ulong_ok (
    unsigned long u1, unsigned long u2, int *ok
  );
  unsigned long dkma_add_ulong (unsigned long u1, unsigned long u2);
  unsigned long dkma_sub_ulong (unsigned long u1, unsigned long u2);
  unsigned long dkma_mul_ulong (unsigned long u1, unsigned long u2);
  unsigned long dkma_div_ulong (unsigned long u1, unsigned long u2);
  
  long dkma_add_long_ok (long u1, long u2, int *ok);
  long dkma_sub_long_ok (long u1, long u2, int *ok);
  long dkma_mul_long_ok (long u1, long u2, int *ok);
  long dkma_div_long_ok (long u1, long u2, int *ok);
  long dkma_add_long (long u1, long u2);
  long dkma_sub_long (long u1, long u2);
  long dkma_mul_long (long u1, long u2);
  long dkma_div_long (long u1, long u2);
  
  double dkma_add_double_ok (double u1, double u2, int *ok);
  double dkma_sub_double_ok (double u1, double u2, int *ok);
  double dkma_mul_double_ok (double u1, double u2, int *ok);
  double dkma_div_double_ok (double u1, double u2, int *ok);
  double dkma_add_double (double u1, double u2);
  double dkma_sub_double (double u1, double u2);
  double dkma_mul_double (double u1, double u2);
  double dkma_div_double (double u1, double u2);

  dk_long_long_unsigned_t
  dkma_add_ull_ok (
    dk_long_long_unsigned_t o1,
    dk_long_long_unsigned_t o2,
    int *ok
  );
  dk_long_long_unsigned_t
  dkma_add_ull (
    dk_long_long_unsigned_t o1,
    dk_long_long_unsigned_t o2
  );
  
  double dkma_ul_to_double_ok (unsigned long u1, int *ok);
  double dkma_ull_to_double_ok (dk_long_long_unsigned_t ul, int *ok);
  double dkma_ul_to_double (unsigned long u1);
  double dkma_ull_to_double (dk_long_long_unsigned_t ul);
  double dkma_l_to_double_ok (long l1, int *ok);
  double dkma_l_to_double (long l1);
  unsigned long dkma_double_to_ul_ok (double d, int *ok);
  unsigned long dkma_double_to_ul (double d);
  long dkma_double_to_l_ok (double d, int *ok);
  long dkma_double_to_l (double d);
  
  double dkma_rint (double d);

=head1	DESCRIPTION

The dkma module contains functions for mathematic operations.
Checks to avoid range overflows and division by 0 are performed.

The ..._ok() functions store check results in the variable
specified by the I<ok> pointer. This variable should be set to
0 before performing the first operation.

If there was no error the variable is left unchanged. On errors
the variable is set to either I<DK_ERR_MATH_OOR> (result out of
range) or I<DK_ERR_DIV_ZERO> (division by zero).

Functions without ..._ok in the name store check results into
a module-static variable. Note: This is not thread-safe.

The functions dkma_add_ulong_ok() ... dkma_add_ull() perform
basic mathematic operations and return the result.

The functions dkma_ul_to_double_ok() ... dkma_double_to_l()
convert between different data types.

The dkma_rint() function is for rounding. It is intended as
a fallback function for systems having no rint() function in
their mathemtics library.

The dkma_get_error() function returns the error code of the
last error occured in functions without I<..._ok> in the name.
The I<del> parameter specified whether or not to reset the
module-static error code.

=head1	AUTHOR

Dirk Krause

=head1	COPYRIGHT AND LICENSE

Copyright (c) 2001-2008, Dirk Krause
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above
   copyright notice, this list of conditions and the
   following disclaimer.

 * Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials
   provided with the distribution.

 * Neither the name of the Dirk Krause nor the names of
   contributors may be used to endorse or promote products
   derived from this software without specific prior written
   permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
