[comp.lang.c] A comparison routine for numbers as strings

ken@aiai.ed.ac.uk (Ken Johnson) (02/19/91)

I just had to write this so I don't see why other people shouldn't share
it.  The problem is: On a system with no floating point library, compare
two numbers written as strings of characters.  The strings may begin
with a - sign and may contain an embedded decimal point.  You are
guaranteed that every number is in a canonical form (three is 3, never
3.0; the strings never contain illegal characters).  Share, use, enjoy,
and remember me when you make your first $million out of it ... :-)

-------------------------------- 8< cut here --------------------------------

#include <stdio.h>

#define	S1_GREATER	1
#define	S2_GREATER	(-1)

#define	INVERT	1
#define	S1G	2
#define	S2G	4

#ifdef TESTING
main(argc,argv)
int argc;
char **argv;
{
	int f;

	f = compare(argv[1],argv[2]);

	printf("%s is %s %s\n",
			argv[1],
			((f == 1) ? "greater than "
				  : ((f == -1) ? "less than"
				  : "equal to" )),
			argv[2]);
}
#endif

/* compare(s1,s21)
 * s1 and s2 are pointers to null-terminated strings of digits
 * The routine returns S1_GREATER or S2_GREATER according to whether
 * s1 or s2 points to the number with the greater value.
 * If it can't make up its mind it returns 0 (equality)
 * Ken Johnson 18-2-1991
 */

int compare(s1,s2)
char *s1;
char *s2;
{
	if (*s1 == '-')
	{
		++s1;

		if (*s2 == '-')
		{
			++s2;
			return(0 - icomp(s1,s2));
		}
		else
		{
			return(S2_GREATER);
		}
	}
	else
	{
		if (*s2 == '-')
		{
			return(S1_GREATER);
		}
		else
		{
			return(icomp(s1,s2));
		}
	}
}

icomp(s1,s2)
char *s1, *s2;
{
	unsigned flags = 0;

	for (;;)
	{
		if (*s1 == '\0' || *s1 == '.')
		{
			if (*s2 == '\0' || *s2 == '.')
			{
				if ((flags & S1G) != 0)
				{
					return(S1_GREATER);
				}
				else if ((flags & S2G) != 0)
				{
					return(S2_GREATER);
				}
				else
				{
					if (*s1 == '\0')
					{
						if (*s2 == '\0')
						{
							return(0);
						}
						else
						{
							return(S2_GREATER);
						}
					}
					else
					{
						if (*s2 == '\0')
						{
							return(S1_GREATER);
						}
					}
				}
			}
			else
			{
				return(S2_GREATER);
			}
		}
		else
		{
			if (*s2 == '\0' || *s2 == '.')
			{
				return(S1_GREATER);
			}
		}

		if ((flags & (S1G | S2G)) == 0)
		{
			if (*s1 > *s2 & (flags & (S1G | S2G)) == 0)
			{
				flags |= S1G;
			}
			else if (*s1 < *s2 & (flags & (S1G | S2G)) == 0)
			{
				flags |= S2G;
			}
		}

		++s1;
		++s2;
	}
}




-- 
``If God had meant us to use     *       Left %          Ken Johnson, AIAI
word-processors He would never   *     handed % 80 South Bridge, Edinburgh
have created Tippex''            *     people %   E-mail ken@aiai.ed.ac.uk
     --  me                      *   are best %   031-650 2756 direct line

dave@cs.arizona.edu (Dave P. Schaumann) (02/19/91)

In article <4169@skye.ed.ac.uk> ken@aiai.ed.ac.uk (Ken Johnson) writes:
>I just had to write this so I don't see why other people shouldn't share
>it. [155 lines of code deleted]

An admirable gesture, but comp.lang.c is really not the place to distribute
software.  That's why there is alt.sources, comp.sources.misc, and all the
other *.sources.* groups.
-- 
Dave Schaumann      | Is this question undecidable?
dave@cs.arizona.edu |