home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / lang / c / 19103 < prev    next >
Encoding:
Internet Message Format  |  1992-12-31  |  3.2 KB

  1. Path: sparky!uunet!spool.mu.edu!think.com!ames!ncar!noao!amethyst!organpipe.uug.arizona.edu!news
  2. From: dave@cs.arizona.edu (Dave Schaumann)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: WANTED: Fast addition for 64-bits integers in C
  5. Message-ID: <1993Jan1.025544.14366@organpipe.uug.arizona.edu>
  6. Date: 1 Jan 93 02:55:44 GMT
  7. References: <1992Dec31.142337.28023@donau.et.tudelft.nl>
  8. Sender: news@organpipe.uug.arizona.edu
  9. Reply-To: dave@cs.arizona.edu (Dave Schaumann)
  10. Organization: University of Arizona
  11. Lines: 72
  12. In-Reply-To: arlet@einstein.et.tudelft.nl (Arlet Ottens)
  13.  
  14. In article <1992Dec31.142337.28023@donau.et.tudelft.nl>, arlet@einstein (Arlet Ottens) writes:
  15. >I want to make an implementation of 64-bit integers in C, using
  16. >a pair of 32-bit integers.
  17.  
  18. If speed is your over-riding concern, use assembly language.  Unfortunately,
  19. this has several aspects that make it otherwise undesirable:
  20.  
  21.     -it's utterly unportable
  22.     -since speed is assumed to be a factor, you'll probably
  23.      want to define the various operations as macros as faux-inline
  24.      functions; unfortunately, many assembly language interfaces
  25.      work poorly or not at all with the preprocessor.
  26.  
  27. Another alternative is to do something like this:
  28.  
  29. #define N_LONG_BYTES 8 /* or whatever */
  30.  
  31. /* wrapping it in a struct allows you to pass it around using
  32.  * call-by-value semantics.  This has the advantage that you
  33.  * don't have to do dynamic allocation for every discrete value.
  34.  * The disadvantage, of course, is that copying bytes can get
  35.  * expensive...
  36.  */
  37. typedef struct { unsigned char bytes[N_LONG_BYTES] ; } hyper_long ;
  38.  
  39. hyper_long hl_add( hyper_long, hyper_long ) ;
  40. hyper_long hl_sub( hyper_long, hyper_long ) ;
  41. hyper_long hl_mul( hyper_long, hyper_long ) ;
  42. hyper_long hl_div( hyper_long, hyper_long ) ;
  43.  
  44. hyper_long hl_add( hyper_long a, hyper_long b ) {
  45.  
  46.   int i, sum ; hyper_long c ;
  47.  
  48.   for( i = 0 ; i < N_LONG_BYTES ; i++ ) c.bytes[i] = 0x00 ;
  49.   for( i = 0 ; i < N_LONG_BYTES ; i++ ) {
  50.     sum = a.bytes[i] + b.bytes[i] ; c.bytes[i] += 0xff & sum ;
  51.     if( sum > 0xff )
  52.       if( i+1 < N_LONG_BYTES ) c.bytes[i+1] = 1
  53.       else Hyper_Long_Error = HL_OVERFLOW_IN_ADD ;
  54.     }
  55.  
  56.   return c ;
  57.   }
  58.  
  59. /* similarly for hl_sub, hl_mul, hl_div, etc... */
  60. /* I haven't tested the above code so Use At Your Own Risk. */
  61.   
  62.  
  63. Of course, this wouldn't be as fast as an assembly language solution, but
  64. it could be made portable.  Hmm... in fact, one might even do something
  65. like
  66.  
  67. typedef struct {
  68.   unsigned char *bytes ;
  69.   unsigned int  nbytes ;
  70.   } hyper_long ;
  71.  
  72. So that you could decide on-the-fly how many bytes you want.  Of course,
  73. this would require an explicit allocation routine.  If this solution
  74. appeals to you, you might want to consider writing your application
  75. in C++, which would automatically call your allocation routine, as
  76. well as allow you to expand the definitions of all the arithmetic
  77. operators to include the "hyper_long" type.
  78.  
  79. The only other option that comes to mind is to switch to yet another
  80. language like Lisp, which has support for very large numbers built in.
  81.  
  82. -- 
  83. What I've learned from reading net news #1:
  84.   It's important to do a lot of outside reading, because you never know
  85.   where you might come across a clever quote you can use in your .sig file.
  86.