Article View: comp.lang.misc
Article #633Re: Fast conversions, another urban myth?
From: Peter Montgomery
Date: Fri, 22 Sep 1989 20:36
Date: Fri, 22 Sep 1989 20:36
69 lines
3546 bytes
3546 bytes
In article <3902@yunexus.UUCP> davecb@yunexus.UUCP (David Collier-Brown) writes:
>mash@mips.COM (John Mashey) writes:
> But the ICL did ascii (well, excess-3) arithmetic because it was
>easy, not because it ran COBOL (it did not), and the CISC had both
>conversion and ascii-arithmetic instructions... Which means that
>these techniques were not necessarily backed up by evidence.
>
> Who has evidence? And how "easy" is, for example,
> word *add(word *,word*); /* A "word" is 2 ascii characters. */
>on a given RISC machine?
>
Let W1 and W2 be two words containing decimal numbers in ASCII.
I assume that W1, W2 contain only digits (no signs, decimal points,
or blanks) and that the less significant ASCII digit
is stored in the less significant binary position. Recall the ASCII
digits are 0x30 hex (= 48 decimal) to 0x39 (= 57).
We want to form (cnew, Wsum) = W1 + W2 + cold where cold, cnew
are binary carries (0 or 1). A first algorithm could resemble:
W3 = W1 + W2 + cold - 0x3030;
if ((W3 & 0x00FF) > 0x0039)
W3 = W3 + (0x0100 - 0x000A); /* Carry ones to tens */
if ((W3 & 0xFF00) > 0x3900) {
W3 = W3 - 0x0A00;
cnew = 1; /* Carry tens to hundreds */
} else {
cnew = 0;
}
If no (decimal) carries during the ASCII add, then the first
estimate for W3 will be correct. The above algorithm separately checks
each byte in W3 for validity, generating a carry if needed.
We can avoid the IFs by checking all the places at once,
but must be prepared for carry propagation
(e.g., 434 + 168 = 602; the carry from the units digits
affects the hundreds digit). Here is a more sophisticated
algorithm, which adds two 4-byte ASCII strings (32-bits each),
producing sum and carry:
T = W1 + W2 + cold - 0x30303030;
Tc = (0x39393939 - T) & 0x80808080;
/* Identify where carries generated */
W3 = T + (256 - 10)*(Tc >> 7);
cnew = Tc >> 31;
This code uses 5 integer additions/subtractions, 2 shifts, 1 AND,
1 integer multiply. If your RISC architecture lacks an integer
multiply (shame!), then use (note four adjacent bits will be set
in Tc wherever a carry is generated, and 256 - 10 = 16*15 + 16*3/8):
T = W1 + W2 + cold - 0x30303030;
Tc = (0x39393939 - T) & 0xF0F0F0F0;
W3 = T + Tc + ((Tc & 0x30303030) >> 3);
cnew = Tc >> 31;
If the ASCII digits are stored in a string,
this algorithm requires you be able to convert a four-character
string to a 32-bit binary number and vice versa.
Just yesterday, I wanted this operation in order to use
the system hostname as part of the initial seed for a random number
generator, but I didn't know how to do it easily in C or FORTRAN 77
(the TRANSFER intrinsic function in the FORTRAN 8x draft may do it).
How many higher level languages make this primitive operation available?
--------
Peter Montgomery
pmontgom@MATH.UCLA.EDU
Technical Details
Message-ID:
<1741@sunset.MATH.UCLA.EDU>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!cs.utexas.edu!uwm.edu!gem.mps.ohio-state.edu!apple!usc!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!ucla-cs!math.ucla.edu!sonia!pmontgomReferences:
<832@dms.UUCP> <688@UALTAVM.BITNET> <9dAz02zs58y201@amdahl.uts.amdahl.com> <27935@winchester.mips.COM> <3902@yunexus.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!cs.utexas.edu!uwm.edu!gem.mps.ohio-state.edu!apple!usc!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!ucla-cs!math.ucla.edu!sonia!pmontgom From: pmontgom@sonia.math.ucla.edu (Peter Montgomery) Newsgroups: comp.lang.misc,comp.arch Subject: Re: Fast conversions, another urban myth? Message-ID: <1741@sunset.MATH.UCLA.EDU> Date: 22 Sep 89 20:36:00 GMT References: <832@dms.UUCP> <688@UALTAVM.BITNET> <9dAz02zs58y201@amdahl.uts.amdahl.com> <27935@winchester.mips.COM> <3902@yunexus.UUCP> Sender: news@MATH.UCLA.EDU Reply-To: pmontgom@math.ucla.edu (Peter Montgomery) Organization: UCLA Mathematics Department Lines: 69