Commit | Line | Data |
---|---|---|
69695f33 MW |
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 |