Using integer multiplication to avoid integer division

sun!attunix.sf.att.com!dfp sun!attunix.sf.att.com!dfp
Fri Jun 22 10:57:00 PDT 1990


Dave Hough writes:
>But Mike Powell pointed out in another context that integer division
>by a fixed constant can often be replaced by an integer multiplication
>and a shift.   When I understood what he had in mind I decided to apply
>it to see what kind of performance improvement was possible.  I was
>running on validgh, a 4/110 with SunOS 4.0, with a version of the C 1.1
>compiler, compiling -O4 -Bstatic.  Results:
>
>	obvious code in C		6.2 secs
>	assembler call to .udiv		3.7 secs
>	Powell improvement in C		2.2 secs
>
>And here's the code which avoids division entirely:
>
>
>unsigned short
>quorem10000(x, pr)
>	unsigned long   x;
>	unsigned short *pr;
>
>/* quorem gets x/10000 ; *pr gets x%10000              */
>
>{
>	long unsigned   t;
>
>	t = ((x >> 4) * 839) >> 19;
>	switch (t) {
>	case 0:
>		*pr = x;
>		break;
>	case 1:
>		*pr = x - 10000;
>		break;
>	case 2:
>		*pr = x - 20000;
>		break;
>	case 3:
>		*pr = x - 30000;
>		break;
>	case 4:
>		*pr = x - 40000;
>		break;
>	case 5:
>		*pr = x - 50000;
>		break;
>	case 6:
>		*pr = x - 60000;
>		break;
>	}
>	return t;
>}

Maybe I'm missing something obvious, but this seems a pretty
difficult way to determine which of [0,6] is x/10000.  Given
that we're talking about this small of a range, why not:

unsigned short quorem10000(unsigned long x, unsigned short *pr)
{
	if (x < 10000)		{ *pr = x - 00000; return 0; }
	else if (x < 20000)	{ *pr = x - 10000; return 1; }
	else if (x < 30000)	{ *pr = x - 20000; return 2; }
	else if (x < 40000)	{ *pr = x - 30000; return 3; }
	else if (x < 50000)	{ *pr = x - 40000; return 4; }
	else if (x < 60000)	{ *pr = x - 50000; return 5; }
	else if (x < 70000)	{ *pr = x - 60000; return 6; }
	else			{ fatal("bad quorem10000!"); }
}

A binary search through the multiples of 10000 will reduce the
maximum number of tests from 7 to 3.  Seems pretty cheap to me.

Dave



More information about the Numeric-interest mailing list