=========================================================================== BBS: The Abacus * HST/DS * Potterville MI Date: 04-04-93 (07:11) Number: 97 From: BOB STOUT Refer#: NONE To: ALL Recvd: NO Subj: Something useful Conf: (36) C Language --------------------------------------------------------------------------- While preparing the next SNIPPETS release, I needed to form an index into a te xt array to demonstrate Michelangelo Jones' moon phase code. I didn't want to re sort to floating point, so I used a *really* old utility I wrote years ago to co nvert reals to integer ratios. I wrote it back in the days of 8-bit micros, so t he integers are all in the range of 0..255, but it's proven useful enough over t he years, I decided to include it in the next SNIPPETS in hopes someone else mig ht be able to use it. Here's a preview: /* ** FRACTION.C - Convert a floating point value to an integer ratio ** ** public domain by Bob Stout */ #include #include #include unsigned char n, d; double real2ratio(double Realnum) { int i, Trial, Seed = 255; double Residue, Minres = 255.; if (1. == Realnum || 0. == Realnum) { n = (unsigned char) Realnum; d = (unsigned char) 1; return Realnum; } if (1.0 < Realnum) { Seed = (int)(255./Realnum); if (255 % (int)Realnum) ++Seed; } for (i = Seed; i; --i) { Trial = (int)((Realnum * (double)i) + 0.5); if (255 < Trial) continue; Residue = Realnum - ((double)Trial/(double)i); if (0. > Residue) Residue = 0. - Residue; if (Residue < Minres) { d = (unsigned char) i; n = (unsigned char) Trial; Minres = Residue; } } return ((double)n / (double)d); } void blow_off(void) { puts("\aUsage: FRACTION decimal_fraction"); puts("returns: decimal_fraction = integer / integer"); } void range_error(double err_num, char *string) { blow_off(); printf("\ndecimal_fraction must be %G or %s.\n", err_num, string); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { double Fraction, result; if (argc < 2) { blow_off(); return EXIT_FAILURE; } Fraction = atof(argv[1]); if (255. < Fraction) range_error((255.), "less"); if ((1./255.) > Fraction && Fraction != 0.) range_error((1./255.), "greater"); result = real2ratio(Fraction); printf("\nClosest integer fraction approximating %G is:\n", Fraction); printf("%d / %d (%Xh / %Xh) = %G", n, d, n, d, result); printf(" (Error = %6.3G%%)\n", 100. * (Fraction - result) / Fraction); return EXIT_SUCCESS; } --- QM v1.00 * Origin: MicroFirm : Down to the C in chips (1:106/2000.6) SEEN-BY: 1/211 11/2 4 13/13 101/1 108/89 109/25 110/69 114/5 123/19 124/1 SEEN-BY: 153/752 154/40 77 157/2 159/100 125 575 950 203/23 209/209 280/1 SEEN-BY: 390/1 396/1 5 15 2270/1 3603/20