fs_value fn_numeric_equal(fs_query *q, fs_value a, fs_value b) { #if 0 fs_value_print(a); printf(" "); fs_value_print(b); printf("\n"); #endif a = fs_value_promote(q, a, b); b = fs_value_promote(q, b, a); if (a.attr == b.attr && a.attr != FS_RID_NULL && a.attr != fs_c.empty) { if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) { return fs_value_boolean(a.fp == b.fp); } if (a.attr == fs_c.xsd_decimal) { return fs_value_boolean(fs_decimal_equal(&a.de, &b.de)); } if (a.attr == fs_c.xsd_integer) { return fs_value_boolean(a.in == b.in); } if (a.attr == fs_c.xsd_boolean) { return fs_value_boolean((a.in ? 1 : 0) == (b.in ? 1 : 0)); } } return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:numeric-equal"); }
int fs_value_equal(fs_value a, fs_value b) { if ((a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) && (b.valid & fs_valid_bit(FS_V_TYPE_ERROR))) { return 1; } if (a.valid & fs_valid_bit(FS_V_RID) && b.valid & fs_valid_bit(FS_V_RID)) { return a.rid == b.rid; } if (a.attr != b.attr) { return 0; } if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) { return a.fp == b.fp; } else if (a.attr == fs_c.xsd_decimal) { return fs_decimal_equal(&a.de, &b.de); } else if (a.attr == fs_c.xsd_integer) { return a.in == b.in; } else if (a.attr == fs_c.xsd_boolean) { return (a.in ? 1: 0) == (b.in ? 1: 0); } else if (a.attr == fs_c.xsd_datetime) { return a.in == b.in; } else if (a.attr == fs_c.xsd_string && a.lex && b.lex) { return !strcmp(a.lex, b.lex); } else if (a.attr == b.attr && a.lex && b.lex) { return !strcmp(a.lex, b.lex); } return 0; }
int fs_decimal_divide(const fs_decimal *n, const fs_decimal *d, fs_decimal *q) { fs_decimal norm; int shift = 0; /* catch divide by zero error */ if (fs_decimal_is_zero(d)) { return 1; } /* use Newton-Raphson series approximation to calculate 1/d */ fs_decimal_normalise(d, &norm, &shift); fs_decimal x; if (norm.digit[FS_D_OVER_DIGITS + FS_D_INT_DIGITS] >= 5) { /* for 0.5 < norm < 1.0 we can use x = 2.914 - 2d as starting pt */ fs_decimal twod; fs_decimal_multiply(&d2_val, &norm, &twod); fs_decimal_subtract(&d2_914_val, &twod, &x); } else { /* otherwise, don't know where to start, use 1.0 */ x = d1_val; } fs_decimal last = zero_val; /* if it hasn't converged after 30 iterations it usually doesn't */ for (int i=0; i<30; i++) { #if 0 printf("step %2d = ", i); fs_decimal_print(&x, stdout); printf("\n"); #endif /* calculate x = x(2-dx) */ fs_decimal dx, tmp; fs_decimal_multiply(&norm, &x, &dx); fs_decimal_subtract(&d2_val, &dx, &tmp); fs_decimal_multiply(&tmp, &x, &x); if (fs_decimal_equal(&x, &last)) break; last = x; } /* round up to nearest representable number */ fs_decimal_add(&x, &unit_val, &x); #if 0 printf("step N = "); fs_decimal_print(&x, stdout); printf("\n"); #endif /* shift the aproximate reciprocal back to correct power */ decimal_shift(&x, &x, shift); /* q = n * 1/d */ fs_decimal_multiply(n, &x, q); q->flags ^= (d->flags & FS_D_NEGATIVE); return 0; }
int fs_value_is_true(fs_value a) { if (a.attr == fs_c.xsd_boolean) { return a.in; } if (a.attr == fs_c.xsd_integer) { return a.in != 0; } if (a.attr == fs_c.xsd_double || fs_c.xsd_float) { return fabs(a.fp) != 0.0; } if (a.attr == fs_c.xsd_decimal) { return !fs_decimal_equal(&a.de, fs_decimal_zero); } if (a.lex) { return strlen(a.lex); } return 0; }
fs_value fn_ebv(fs_value a) { if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) { return a; } if (a.rid == FS_RID_NULL) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (a.attr == fs_c.xsd_boolean || a.attr == fs_c.xsd_integer) { return fs_value_boolean(a.in); } if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) { return fs_value_boolean(fabs(a.fp) != 0.0); } if (a.attr == fs_c.xsd_decimal) { return fs_value_boolean(!fs_decimal_equal(&a.de, fs_decimal_zero)); } if (a.lex && (a.attr == fs_c.xsd_string || a.attr == fs_c.empty)) { return fs_value_boolean(a.lex && a.lex[0]); } return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); }