QIF Import fails out of CVS
Derek Atkins
warlord@MIT.EDU
13 Feb 2001 18:02:54 -0500
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
;)
-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