Re: 6 byte integer to string
From: Derrick Coetzee (dcnews_at_moonflare.com)
Date: 09/26/04
- Next message: S.Tobias: "Re: struct and union alignment"
- Previous message: Joe Wright: "Re: Clearly, it is too late to fix c99 - C is dead"
- In reply to: Alex Fraser: "Re: 6 byte integer to string"
- Next in thread: Derrick Coetzee: "Re: 6 byte integer to string"
- Reply: Derrick Coetzee: "Re: 6 byte integer to string"
- Reply: Ben Pfaff: "Re: 6 byte integer to string"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 26 Sep 2004 13:20:24 -0400
Alex Fraser wrote:
> If the platform can do 32-bit division (32-bit dividend and divisor to
> 32-bit quotient and remainder) in hardware, then the quickest way is
> probably to start by dividing the 48-bit number by 100000 in software. The
> remainder from that division contains the least significant five digits, and
> the quotient (which is guaranteed to fit in 32 bits) contains the most
> significant digits. Then use the hardware divide to extract the digits from
> each part (dividing by 10).
>
> If there is no hardware divide, I don't know of any better way than the
> obvious repeated division by 10.
I came up with a custom algorithm for doing unsigned 32-bit division of
x by 10 using only a couple shifts and x % 5 hardware multiplications.
I'm not sure if it's the most efficient approach, but it is pretty neat.
On a platform with 32-bit ints and it goes like this:
struct div_result {
unsigned int quotient;
unsigned int remainder;
};
#define FIVE_INVERSE 3435973837u
struct div_result divide10(unsigned int x) {
struct div_result result;
result.remainder = x & 1;
x >>= 1;
unsigned int xdiv4 = x >> 2;
result.quotient = x * FIVE_INVERSE;
if (result.quotient <= xdiv4) return result;
result.remainder += 2; x--;
result.quotient = x * FIVE_INVERSE;
if (result.quotient <= xdiv4) return result;
result.remainder += 2; x--;
result.quotient = x * FIVE_INVERSE;
if (result.quotient <= xdiv4) return result;
result.remainder += 2; x--;
result.quotient = x * FIVE_INVERSE;
if (result.quotient <= xdiv4) return result;
result.remainder += 2; x--;
result.quotient = x * FIVE_INVERSE;
return result;
}
I've tested this function on all 2^32 values of an unsigned int. It
effectively works by searching for the nearest number <= x/2 which is
divisible by 5 and then divides it by 5 by multiplying by the inverse of
5 in the group Z(2^32). It knows when it worked because otherwise it
gets a big result exceeding x/8.
-- Derrick Coetzee I grant this newsgroup posting into the public domain. I disclaim all express or implied warranty and all liability. I am not a professional.
- Next message: S.Tobias: "Re: struct and union alignment"
- Previous message: Joe Wright: "Re: Clearly, it is too late to fix c99 - C is dead"
- In reply to: Alex Fraser: "Re: 6 byte integer to string"
- Next in thread: Derrick Coetzee: "Re: 6 byte integer to string"
- Reply: Derrick Coetzee: "Re: 6 byte integer to string"
- Reply: Ben Pfaff: "Re: 6 byte integer to string"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|