home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!spool.mu.edu!think.com!ames!ncar!noao!amethyst!organpipe.uug.arizona.edu!news
- From: dave@cs.arizona.edu (Dave Schaumann)
- Newsgroups: comp.lang.c
- Subject: Re: WANTED: Fast addition for 64-bits integers in C
- Message-ID: <1993Jan1.025544.14366@organpipe.uug.arizona.edu>
- Date: 1 Jan 93 02:55:44 GMT
- References: <1992Dec31.142337.28023@donau.et.tudelft.nl>
- Sender: news@organpipe.uug.arizona.edu
- Reply-To: dave@cs.arizona.edu (Dave Schaumann)
- Organization: University of Arizona
- Lines: 72
- In-Reply-To: arlet@einstein.et.tudelft.nl (Arlet Ottens)
-
- In article <1992Dec31.142337.28023@donau.et.tudelft.nl>, arlet@einstein (Arlet Ottens) writes:
- >I want to make an implementation of 64-bit integers in C, using
- >a pair of 32-bit integers.
-
- If speed is your over-riding concern, use assembly language. Unfortunately,
- this has several aspects that make it otherwise undesirable:
-
- -it's utterly unportable
- -since speed is assumed to be a factor, you'll probably
- want to define the various operations as macros as faux-inline
- functions; unfortunately, many assembly language interfaces
- work poorly or not at all with the preprocessor.
-
- Another alternative is to do something like this:
-
- #define N_LONG_BYTES 8 /* or whatever */
-
- /* wrapping it in a struct allows you to pass it around using
- * call-by-value semantics. This has the advantage that you
- * don't have to do dynamic allocation for every discrete value.
- * The disadvantage, of course, is that copying bytes can get
- * expensive...
- */
- typedef struct { unsigned char bytes[N_LONG_BYTES] ; } hyper_long ;
-
- hyper_long hl_add( hyper_long, hyper_long ) ;
- hyper_long hl_sub( hyper_long, hyper_long ) ;
- hyper_long hl_mul( hyper_long, hyper_long ) ;
- hyper_long hl_div( hyper_long, hyper_long ) ;
-
- hyper_long hl_add( hyper_long a, hyper_long b ) {
-
- int i, sum ; hyper_long c ;
-
- for( i = 0 ; i < N_LONG_BYTES ; i++ ) c.bytes[i] = 0x00 ;
- for( i = 0 ; i < N_LONG_BYTES ; i++ ) {
- sum = a.bytes[i] + b.bytes[i] ; c.bytes[i] += 0xff & sum ;
- if( sum > 0xff )
- if( i+1 < N_LONG_BYTES ) c.bytes[i+1] = 1
- else Hyper_Long_Error = HL_OVERFLOW_IN_ADD ;
- }
-
- return c ;
- }
-
- /* similarly for hl_sub, hl_mul, hl_div, etc... */
- /* I haven't tested the above code so Use At Your Own Risk. */
-
-
- Of course, this wouldn't be as fast as an assembly language solution, but
- it could be made portable. Hmm... in fact, one might even do something
- like
-
- typedef struct {
- unsigned char *bytes ;
- unsigned int nbytes ;
- } hyper_long ;
-
- So that you could decide on-the-fly how many bytes you want. Of course,
- this would require an explicit allocation routine. If this solution
- appeals to you, you might want to consider writing your application
- in C++, which would automatically call your allocation routine, as
- well as allow you to expand the definitions of all the arithmetic
- operators to include the "hyper_long" type.
-
- The only other option that comes to mind is to switch to yet another
- language like Lisp, which has support for very large numbers built in.
-
- --
- What I've learned from reading net news #1:
- It's important to do a lot of outside reading, because you never know
- where you might come across a clever quote you can use in your .sig file.
-