/* Copyright 1989-93 GROUPE BULL -- See license conditions in file COPYRIGHT */
/******************************************************\
*                                                      *
* KlO: Number                                          *
* DEFINITIONS                                          *
*                                                      *
* Note: for historical reasons, all *Number* functions *
* should have been labelled *Integer*, but aren't.     *
*                                                      *
\******************************************************/

#ifdef SYSV
#include <limits.h>
#endif /* SYSV */

#ifndef INCLUDE_Kl_NUMBER_H
#define INCLUDE_Kl_NUMBER_H

#include <math.h>

/* type */

typedef struct _KlNumber {
    KlKLONE_HEADER;
    Int number;
}        *KlNumber;

typedef struct _KlReal {		/* real can be handled like a number */
    KlKLONE_HEADER;
    Int number;
    Kl_REAL_PADDING
    double real;
}      *KlReal;



/* exported functions */

EXT KlNumber KlNumberMake();
EXT KlO KlNumberPrint();
EXT KlO KlNumberFree();
EXT KlO KlNumberEqual();
EXT KlReal KlRealMake();
EXT KlO KlNumberCoerce();
EXT KlO KlRealCoerce();
EXT KlO KlNumbersCoerce();
KlO KlGenericNumberAdd1();
KlO KlGenericNumberMult();
KlO KlGenericNumberDiv();
int KlGenericNumberCompare();
void KlDeclareGenericNumber();

#define KlMaxInt 2147483647
#define KlMinInt -2147483648

/* PB: we cannot use floor to cast float into ints in SCO */
#ifdef CHECK_DOUBLE_INT_CAST
#ifndef LONG_MAX
#define LONG_MAX 2147483647
#endif /* LONG_MAX */
        /* update integer value */
/* A Floating Point Exeption occurs on some machines when a double is casted
   in integer. */
#if defined (__GNUC__) && defined (i386)
/* Sorry, I can't use LONG_MIN in the test because gcc/Sco casts it
   in LONG_MAX. */
#define KlRealFix(o) (o)->number = ((o)->real <= LONG_MAX \
                && (o)->real >= -2147483647) ? (o)->real : -1
#else           /* defined (__GNUC__) && defined (i386) */
#define KlRealFix(o) (o)->number = ((o)->real <= LONG_MAX \
                && (o)->real >= LONG_MIN) ? (o)->real : -1
#endif          /* defined (__GNUC__) && defined (i386) */

#else           /* !CHECK_DOUBLE_INT_CAST */
#define KlRealFix(o) ((o)->number = (o)->real) /* update integer value */
#endif          /* !CHECK_DOUBLE_INT_CAST */

 /* get a C double from any number */
#define KlNumberRealValue(o) (KlIsAReal(o) \
    ? ((KlReal)o)->real : (double) (((KlNumber)o)->number))

/* number = any number, integer = only integers, real = only reals */

#define KlIsANumber(obj) KlHasTrait(obj, KlTrait_number)
#define KlMustBeNumber(o, n) KlArgumentMustHaveTrait(o, n, KlTrait_number)

#define KlIsAnInteger(obj) ((obj)->type == KlNumberType)
#define KlMustBeInteger(o, n) KlArgumentMustBe(o, n, KlNumberType)

#define KlIsAReal(obj) ((obj)->type == KlRealType)
#define KlMustBeReal(o, n) KlArgumentMustBe(o, n, KlRealType)


/* methods */

EXT KlType KlMagnitudeType;		/* pseudo type */
EXT KlType KlNumbersType;		/* pseudo type */
EXT KlType KlNumberType;
EXT KlType KlRealType;

/* pre-calculated numbers for efficiency */
#define MIN_BUILT_IN_NUMBER -2
#define MAX_BUILT_IN_NUMBER 20
EXT KlNumber KlBuiltInNumbers[MAX_BUILT_IN_NUMBER - MIN_BUILT_IN_NUMBER + 1];

#endif					/* INCLUDE_Kl_NUMBER_H */


syntax highlighted by Code2HTML, v. 0.9.1