| 1 | /* Copyright (c) 1995, 1996, 1997, 2001 by Arkkra Enterprises */ |
| 2 | /* All rights reserved */ |
| 3 | /* |
| 4 | * rational.h definitions for using rational numbers |
| 5 | */ |
| 6 | #ifndef _RATIONAL |
| 7 | #define _RATIONAL |
| 8 | |
| 9 | |
| 10 | /* |
| 11 | * The code in rational.h/rational.c is written in a way that depends on |
| 12 | * certain variables being 32-bit numbers stored in two's complement form. For |
| 13 | * most compilers, "long" works for this, but for some compilers, "long" is |
| 14 | * 64 bits, or maybe something else. C standards after (and not including) the |
| 15 | * 1994 version guarantee the existence of a header file stdint.h which defines |
| 16 | * typedefs int32_t and uint32_t. So for those standards we will use those |
| 17 | * typedefs from that header when defining our INT32B and UINT32B. Otherwise |
| 18 | * we will just use long and unsigned long. If these aren't 32-bit, two's |
| 19 | * complement, you will have to change this code. |
| 20 | */ |
| 21 | #if __STDC_VERSION__ > 199409L |
| 22 | #include <stdint.h> |
| 23 | #define INT32B int32_t |
| 24 | #define UINT32B uint32_t |
| 25 | #else |
| 26 | #define INT32B long |
| 27 | #define UINT32B unsigned long |
| 28 | #endif |
| 29 | |
| 30 | /* |
| 31 | * Define the structure that represents a rational number. The number |
| 32 | * should be kept in standard form; that is, in lowest terms with a positive |
| 33 | * denominator. Zero should be stored as 0/1. |
| 34 | */ |
| 35 | struct rational { |
| 36 | INT32B n; /* numerator */ |
| 37 | INT32B d; /* denominator */ |
| 38 | }; |
| 39 | |
| 40 | typedef struct rational RATIONAL; |
| 41 | |
| 42 | |
| 43 | /* macros for comparing rational numbers */ |
| 44 | /* numbers must be in standard form */ |
| 45 | |
| 46 | #define EQ(a, b) ((a).n == (b).n && (a).d == (b).d) |
| 47 | #define NE(a, b) ((a).n != (b).n || (a).d != (b).d) |
| 48 | |
| 49 | /* must call function for inequalities, because overflow possibilities */ |
| 50 | |
| 51 | #define GT(a, b) gtrat(a, b) |
| 52 | #define LT(a, b) gtrat(b, a) |
| 53 | #define GE(a, b) ( ! gtrat(b, a) ) |
| 54 | #define LE(a, b) ( ! gtrat(a, b) ) |
| 55 | |
| 56 | |
| 57 | /* macros for testing a rational number */ |
| 58 | /* numbers must be in standard form, or at least have positive denominator */ |
| 59 | |
| 60 | #define ZE(a) ((a).n == 0) |
| 61 | #define PL(a) ((a).n > 0) |
| 62 | #define MI(a) ((a).n < 0) |
| 63 | #define NZ(a) ((a).n != 0) |
| 64 | #define NM(a) ((a).n >= 0) |
| 65 | #define NP(a) ((a).n <= 0) |
| 66 | |
| 67 | |
| 68 | /* definitions for error handling */ |
| 69 | |
| 70 | #define RATNOERR 0 |
| 71 | #define RATOVER 1 |
| 72 | #define RATDIV0 2 |
| 73 | #define RATPARM 3 |
| 74 | |
| 75 | #ifndef MAXLONG |
| 76 | #define MAXLONG 0x7fffffff |
| 77 | #endif |
| 78 | |
| 79 | extern int raterrno; /* holds error code */ |
| 80 | #ifdef __STDC__ |
| 81 | extern void (*raterrfuncp)(int); /* pointer to user error handler */ |
| 82 | #else |
| 83 | extern void (*raterrfuncp)(); /* pointer to user error handler */ |
| 84 | #endif |
| 85 | |
| 86 | |
| 87 | /* functions to do operations on rational numbers */ |
| 88 | |
| 89 | #ifdef __STDC__ |
| 90 | extern RATIONAL radd(RATIONAL x, RATIONAL y); |
| 91 | extern RATIONAL rsub(RATIONAL x, RATIONAL y); |
| 92 | extern RATIONAL rmul(RATIONAL x, RATIONAL y); |
| 93 | extern RATIONAL rdiv(RATIONAL x, RATIONAL y); |
| 94 | extern RATIONAL rneg(RATIONAL x); |
| 95 | extern RATIONAL rinv(RATIONAL x); |
| 96 | extern RATIONAL rrai(RATIONAL x, int n); |
| 97 | extern void rred(RATIONAL *ap); |
| 98 | extern char *ator(RATIONAL *rp, char s[]); |
| 99 | extern char *rtoa(char s[], RATIONAL *rp); |
| 100 | extern int gtrat(RATIONAL x, RATIONAL y); |
| 101 | #else |
| 102 | extern RATIONAL radd(), rsub(), rmul(), rdiv(), rneg(), rinv(), rrai(); |
| 103 | extern void rred(); |
| 104 | extern char *ator(), *rtoa(); |
| 105 | extern int gtrat(); |
| 106 | #endif |
| 107 | |
| 108 | #endif |