enhanced the coding for xmlXPathCastNumberToString in order to produce the
* xpath.c: enhanced the coding for xmlXPathCastNumberToString
in order to produce the required number of significant digits
(bug #437179)
svn path=/trunk/; revision=3615
diff --git a/ChangeLog b/ChangeLog
index aecf060..3809d2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri May 11 22:45:18 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+ * xpath.c: enhanced the coding for xmlXPathCastNumberToString
+ in order to produce the required number of significant digits
+ (bug #437179)
+
Thu May 10 01:52:42 CEST 2007 Daniel Veillard <daniel@veillard.com>
* list.c: applied patch to fix xmlListAppend() from
diff --git a/xpath.c b/xpath.c
index 8c35e30..20ab273 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2648,9 +2648,10 @@
#define UPPER_DOUBLE 1E9
#define LOWER_DOUBLE 1E-5
+#define LOWER_DOUBLE_EXP 5
#define INTEGER_DIGITS DBL_DIG
-#define FRACTION_DIGITS (DBL_DIG + 1)
+#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
#define EXPONENT_DIGITS (3 + 2)
/**
@@ -2701,8 +2702,16 @@
*ptr = 0;
}
} else {
- /* 3 is sign, decimal point, and terminating zero */
- char work[DBL_DIG + EXPONENT_DIGITS + 3];
+ /*
+ For the dimension of work,
+ DBL_DIG is number of significant digits
+ EXPONENT is only needed for "scientific notation"
+ 3 is sign, decimal point, and terminating zero
+ LOWER_DOUBLE_EXP is max number of leading zeroes in fraction
+ Note that this dimension is slightly (a few characters)
+ larger than actually necessary.
+ */
+ char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
int integer_place, fraction_place;
char *ptr;
char *after_fraction;
@@ -2725,24 +2734,25 @@
size = snprintf(work, sizeof(work),"%*.*e",
integer_place, fraction_place, number);
while ((size > 0) && (work[size] != 'e')) size--;
- after_fraction = work + size;
}
else {
/* Use regular notation */
- if (absolute_value > 0.0)
- integer_place = 1 + (int)log10(absolute_value);
- else
- integer_place = 0;
- fraction_place = (integer_place > 0)
- ? DBL_DIG - integer_place
- : DBL_DIG;
+ if (absolute_value > 0.0) {
+ integer_place = (int)log10(absolute_value);
+ if (integer_place > 0)
+ fraction_place = DBL_DIG - integer_place - 1;
+ else
+ fraction_place = DBL_DIG - integer_place;
+ } else {
+ fraction_place = 1;
+ }
size = snprintf(work, sizeof(work), "%0.*f",
fraction_place, number);
- after_fraction = work + size;
}
/* Remove fractional trailing zeroes */
+ after_fraction = work + size;
ptr = after_fraction;
while (*(--ptr) == '0')
;