QIF Import fails out of CVS

Derek Atkins warlord@MIT.EDU
13 Feb 2001 18:16:38 -0500


grib@gnumatic.com (Bill Gribble) writes:

> On Tue, Feb 13, 2001 at 06:02:54PM -0500, Derek Atkins wrote:
> > Hey, try this patch to gnc-helpers.c instead of yours.  I think this
> > version of scm_to_gint64 should work in all cases (even large numbers
> > ;)
> 
> I just sent a patch that does it a different way, but I like your
> approach better.  I am sick of looking at this code :) so if you think
> your approach will work for large and small negative and positive
> numbers I'm happy to have it go in.  Could you resend it to
> gnucash-patches if you didn't already?

Sure, except my patch is based off of CVS, not off your patches...
Here it is, again.  If you want it uuencoded, I can resend it.

> b.g.

-derek

Index: src/guile/gnc-helpers.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/guile/gnc-helpers.c,v
retrieving revision 1.19
diff -u -r1.19 gnc-helpers.c
--- src/guile/gnc-helpers.c	2001/02/09 22:01:56	1.19
+++ src/guile/gnc-helpers.c	2001/02/13 22:57:48
@@ -564,7 +564,7 @@
 SCM
 gnc_gint64_to_scm(const gint64 x)
 {
-#if GUILE_LONG_LONG_OK
+#if GUILE_LONG_LONG_OK 
   return scm_long_long2num(x);
 #else
   const gchar negative_p = (x < 0);
@@ -587,34 +587,47 @@
 gint64
 gnc_scm_to_gint64(SCM num)
 {
-#if GUILE_LONG_LONG_OK
+#if GUILE_LONG_LONG_OK 
   return scm_num2long_long(num, (char *) SCM_ARG1, "gnc_scm_to_gint64");
 #else
-  static SCM upper_mask = SCM_BOOL_F;
-  SCM magnitude = scm_abs(num);
-  SCM upper = scm_ash(magnitude, SCM_MAKINUM(-32));
+  static SCM bits00to15_mask = SCM_BOOL_F;
+  SCM magnitude  = scm_abs(num);
+  SCM bits;
+  unsigned long c_bits;
+  long long     c_result = 0;
+  int		i;
+
   /* This doesn't work -- atm (bit-extract 4000 0 32) proves it */
   /*
   SCM lower = scm_bit_extract(magnitude, SCM_MAKINUM(0), SCM_MAKINUM(32));
   */
-
-  if (upper_mask == SCM_BOOL_F)
-  {
-    upper_mask = gh_ulong2scm(0xFFFFFFFF);
-    scm_protect_object (upper_mask);
+  
+  if (bits00to15_mask == SCM_BOOL_F) {
+    bits00to15_mask = gh_ulong2scm(0xFFFF);
+    scm_protect_object (bits00to15_mask);
   }
 
-  {
-    SCM lower = scm_logand(magnitude, upper_mask);
-    const unsigned long c_upper = gh_scm2ulong(upper);
-    const unsigned long c_lower = gh_scm2ulong(lower);
-    long long c_result = (((long long) c_upper) << 32) + c_lower;
-    
-    if(scm_negative_p(num) != SCM_BOOL_F) {
-      return(- c_result);
-    } else {
-      return(c_result);
-    }
+  /*
+   * This isn't very complicated (IMHO).  We work from the "top" of
+   * the number downwards.  We assume this is no more than a 64-bit
+   * number, otherwise it will fail right away.  Anyways, we keep
+   * taking the top 16 bits of the number and move it to c_result.
+   * Then we 'remove' those bits from the original number and continue
+   * with the next 16 bits down, and so on.  -- warlord@mit.edu
+   * 2001/02/13
+   */
+  for (i = 48; i >=0; i-= 16) {
+    bits = scm_ash(magnitude, SCM_MAKINUM(-i));
+    c_bits = gh_scm2ulong(scm_logand(bits, bits00to15_mask));
+    c_result += ((long long)c_bits << i);
+    magnitude = scm_difference(magnitude, scm_ash(bits, SCM_MAKINUM(i)));
+  }
+  
+  if(scm_negative_p(num) != SCM_BOOL_F) {
+    return(- c_result);
+  } 
+  else {
+    return(c_result);
   }
 #endif
 }


-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord@MIT.EDU                        PGP key available