> June 2011 ~ Online tutorial


Maths Errors
Mathematical functions can be delicate animals. There exist mathematical functions which simply cannot produce sensible answers in all possible cases. Mathematical functions are not "user friendly"! One example of an unfriendly function is the inverse sine function asin(x) which only works for values of x in the range +1.0 to -1.0. The reason for this is a mathematical one: namely that the sine function (of which asin() is the opposite) only has values in this range. The statement
 y = asin (25.3);

is nonsense and it cannot possibly produce a value for y, because none exists. Similarly, there is no simple number which is the square root of a negative value, so an expression such as:
 x = sqrt(-2.0);

would also be nonsense. This doesn't stop the programmer from writing these statements though and it doesn't stop a faulty program from straying out of bounds. What happens then when an erroneous statement is executed? Some sort of error condition would certainly have to result.
In many languages, errors, like the ones above, are terminal: they cause a program to stop without any option to recover the damage. In C, as the reader might have come to expect, this is not the case. It is possible (in principle) to recover from any error, whilst still maintaining firm control of a program.
Errors like the ones above are called domain errors (the set of values which a function can accept is called the domain of the function). There are other errors which can occur too. For example, division by zero is illegal, because dividing by zero is "mathematical nonsense" - it can be done, but the answer can be all the numbers which exist at the same time! Obviously a program cannot work with any idea as vague as this. Finally, in addition to these "pathological" cases, mathematical operations can fail just because the numbers they deal with get too large for the computer to handle, or too small, as the case may be.
Domain error
Illegal value put into function
Division by zero
Dividing by zero is nonsense.
Overflow
Number became too large
Underflow
Number became too small.
Loss of accuracy
No meaningful answer could be calculated


Mathematical Functions
C has a library of standard mathematical functions which can be accessed by #including the appropriate header files (math.h etc.). It should be noted that all of these functions work with double or long float type variables. All of C's mathematical capabilities are written for long variable types. Here is a list of the functions which can be expected in the standard library file. The variables used are all to be declared long
int i;                   /* long int */
double x,y,result;       /* long float */

The functions themselves must be declared long float or double (which might be done automatically in the mathematics library file, or in a separate file) and any constants must be written in floating point form: for instance, write 7.0 instead of just 7.

ABS()
MACRO. Returns the unsigned value of the value in parentheses. See fabs() for a function version.
fabs()
Find the absolute or unsigned value of the value in parentheses:
 result = fabs(x);


ceil()
Find out what the ceiling integer is: that is, the integer which is just above the value in parentheses. This is like rounding up.
 i = ceil(x);

 /* ceil (2.2) is 3 */


floor()
Find out what the floor integer is: that is, the integer which is just below the floating point value in parentheses
 i = floor(x);

 /* floor(2.2) is 2 */


exp()
Find the exponential value.
 result = exp(x);
 result = exp(2.7);


log()
Find the natural (Naperian) logarithm. The value used in the parentheses must be unsigned: that is, it must be greater than zero. It does not have to be declared specifically as unsigned. e.g.
 result = log(x);
 result = log(2.71828);


log10()
Find the base 10 logarithm. The value used in the parentheses must be unsigned: that is, it must be greater than zero. It does not have to be declared specifically as unsigned.
 result = log10(x);
 result = log10(10000);


pow()
Raise a number to the power.
 result = pow(x,y); /*raise x to the power y */
 result = pow(x,2); /*find x-squared */

 result = pow(2.0,3.2); /* find 2 to the power 3.2 ...*/

sqrt()
Find the square root of a number.
 result = sqrt(x);
 result = sqrt(2.0);


sin()
Find the sine of the angle in radians.
 result = sin(x);
 result = sin(3.14);


cos()
Find the cosine of the angle in radians.
 result = cos(x);
 result = cos(3.14);


tan()
Find the tangent of the angle in radians.
 result = tan(x);
 result = tan(3.14);


asin()
Find the arcsine or inverse sine of the value which must lie between +1.0 and -1.0.
 result = asin(x);
 result = asin(1.0);


acos()
Find the arccosine or inverse cosine of the value which must lie between +1.0 and -1.0.
 result = acos(x);
 result = acos(1.0);


atan()
Find the arctangent or inverse tangent of the value.
 result = atan(x);
 result = atan(200.0);


atan2()
This is a special inverse tangent function for calculating the inverse tangent of x divided by y. This function is set up to find this result more accurately than atan().
 result = atan2(x,y);
 result = atan2(x/3.14);


sinh()
Find the hyperbolic sine of the value. (Pronounced "shine" or "sinch")
 result = sinh(x);
 result = sinh(5.0);


cosh()
Find the hyperbolic cosine of the value.
 result = cosh(x);
 result = cosh(5.0);


tanh()
Find the hyperbolic tangent of the value.
 result = tanh(x);
 result = tanh(5.0);


/************************************************/
/*                                              */
/* Prime Number Generator #1                    */
/*                                              */
/************************************************/

   /* Check for prime number by raw number */
   /* crunching. Try dividing all numbers  */
   /* up to half the size of a given i, if */
   /* remainder == 0 then not prime!       */

#include <stdio.h>

#define MAXINT  500
#define TRUE      1
#define FALSE     0

/*************************************************/
/* Level 0                                       */
/*************************************************/

main ()

{ int i;

for (i = 2; i <= MAXINT; i++)
   {
   if (prime(i))
      {
      printf ("%5d",i);
      }
   }
}

/*************************************************/
/* Level 1                                       */
/*************************************************/

prime (i)         /* check for a prime number */

int i;

{ int j;

for (j = 2; j <= i/2; j++)
   {
   if (i % j == 0)
      {
      return FALSE;
      }
   }

return TRUE;
}



/*********************************************************/
/*                                                       */
/* Structures Demo                                       */
/*                                                       */
/*********************************************************/

   /* Simple program to initialize some structures */
   /* and to print them out again. Does no error   */
   /* checking, so be wary of string sizes etc..   */

#include <stdio.h>

#define NAMESIZE    30
#define ADDRSIZE    80
#define NOOFPERSONS 20
#define NEWLINE()   putchar('\n');

/*********************************************************/

typedef struct
  {
  char *Name;
  char *Address;
  int YearOfBirth;
  int MonthOfBirth;
  int DayOfBirth;
  }
PersonDat;

/*********************************************************/

main ()                          /* Make some records */

{ PersonDat record[NOOFPERSONS];
  PersonDat PersonalDetails();
  int person;

printf ("Birth Records For Employees");
printf ("\n---------------------------");
printf ("\n\n");

printf ("Enter data\n");

for (person = 0; person < NOOFPERSONS; person++)
   {
   record[person] = PersonalDetails();
   NEWLINE();
   }

DisplayRecords (record);
}

/*********************************************************/

PersonDat PersonalDetails()     /* No error checking! */

{ PersonDat dat;
  char strbuff[ADDRSIZE], *malloc();

printf ("Name :");
dat.Name = malloc(NAMESIZE);
strcpy (dat.Name,gets(strbuff));

printf ("Address :");
dat.Address = malloc(ADDRSIZE);
strcpy (dat.Address,gets(strbuff));

printf ("Year of birth:");
dat.YearOfBirth = getint (1900,1987);

printf ("Month of birth:");
dat.MonthOfBirth = getint (1,12);

printf ("Day of birth:");
dat.DayOfBirth = getint(1,31);

return (dat);
}

/**********************************************************/

DisplayRecords (rec)

PersonDat rec[NOOFPERSONS];

{ int pers;

for (pers = 0; pers < NOOFPERSONS; pers++)
   {
   printf ("Name : %s\n", rec[pers].Name);
   printf ("Address : %s\n", rec[pers].Address);
   printf("Date of Birth: %1d/%1d/%1d\n",rec[pers].DayOfBirth,
              rec[pers].MonthOfBirth,rec[pers].YearOfBirth);
   NEWLINE();
   }
}

/**********************************************************/
/* Toolkit                                                */
/**********************************************************/

getint (a,b)             /* return int between a and b */

int a,b;

{ int  p, i = a - 1;

for (p=0; ((a > i) || (i > b)); p++)
   {
   printf ("? : ");
   scanf ("%d",&i);
   if (p > 2)
      {
      skipgarb();
      p = 0;
      }
   }
skipgarb();
return (i);
}

/**********************************************************/

skipgarb()       /* Skip input garbage corrupting scanf */

{
while (getchar() != '\n')
   {
   }
}