/* nag_is_finite (x07aac) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 24, 2013.
 */

#include <nag.h>
#include <nagx02.h>
#include <nagx07.h>
#include <stdio.h>

static void diagnose(const char *c, double x)
{
  Nag_Boolean isfin, isnan;
  printf("\nDiagnosis of value \"%s\" which prints as %12.4e\n", c, x);

  /* nag_is_finite (x07aac).
   * Determines whether its argument has a finite value. */
  isfin = nag_is_finite(x);
  if (isfin)
    printf("\"%s\" is finite\n", c);
  else
    printf("\"%s\" is not finite\n", c);

  /* nag_is_nan (x07abc).
   * Determines whether its argument is a NaN (Not A Number). */
  isnan = nag_is_nan(x);
  if (isnan)
    printf("\"%s\" is NaN\n", c);
  else
    printf("\"%s\" is not NaN\n", c);

  if (x < 0.0)
    printf("\"%s\" compares less than zero.\n", c);
  else
    printf("\"%s\" does not compare less than zero.\n", c);

  if (x == 0.0)
    printf("\"%s\" compares equal to zero.\n", c);
  else
    printf("\"%s\" does not compare equal to zero.\n", c);

  if (x > 0.0)
    printf("\"%s\" compares greater than zero.\n", c);
  else
    printf("\"%s\" does not compare greater than zero.\n", c);

}

int main(void)
{
  Integer exit_status = 0;
  double neginf, qnan, x, y, zero;
  Integer exmode[3], newexmode[3];

  printf("nag_is_finite (x07aac) Example Program Results\n\n");

  /* Turn exception halting mode off for the three common exceptions
   * overflow, division-by-zero, and invalid operation. */
  printf("Turn exception halting off ...\n");
  exmode[0] = exmode[1] = exmode[2] = 0;
  /* nag_set_ieee_exception_mode (x07cbc).
   * Sets behaviour of floating point exceptions. */
  nag_set_ieee_exception_mode(exmode);

  /* Check that exception halting mode for the three common exceptions
   * was really turned off. */
  /* nag_get_ieee_exception_mode (x07cac).
   * Gets current behaviour of floating point exceptions. */
  nag_get_ieee_exception_mode(newexmode);
  printf("Exception halting mode is now: %ld %ld %ld\n",
         newexmode[0], newexmode[1], newexmode[2]);

  /* Look at some ordinary numbers. */
  x = 1.0;
  diagnose("one", x);
  x = -2.0;
  diagnose("-two", x);
  zero = 0.0;
  diagnose("zero", zero);

  /* Generate an infinity and a NaN and look at their properties. */
  /* nag_create_infinity (x07bac). Creates a signed infinite value. */
  nag_create_infinity(-1, &neginf);
  diagnose("-Infinity", neginf);

  /* nag_create_nan (x07bbc). Creates a NaN (Not A Number). */
  nag_create_nan(1, &qnan);
  diagnose("Quiet NaN", qnan);

  /* Do some operations which purposely raise exceptions. */
  printf("\nTry to cause overflow - no trap should occur:\n");
  /* nag_real_largest_number (X02ALC). The largest positive model number. */
  x = nag_real_largest_number;
  y = -x * x;
  printf("y = -huge * huge = %12.4e\n\n", y);

  printf("Try to cause NaN - no trap should occur:\n");
  y = zero / zero;
  printf("y = 0.0 / 0.0 = %12.4e\n\n", y);

  printf("Try to cause division by zero - no trap should occur:\n");
  x = -1.0;
  y = x / zero;
  printf("y = -1.0 / 0.0 = %12.4e\n", y);

  return exit_status;
}