sqlite> select roundhe(3.255, 2); 3.26 sqlite> select printf('%!.18f', 3.255); 3.254999999999999893 sqlite> select printf('%!.18f', roundhe(3.255, 2)); 3.259999999999999787 sqlite> select printf('%!.18f', pow(10.0, 2)); 100.0 sqlite> select printf('%!.18f', pow(10.0, 2) * 3.255); 325.5
The good: proper rounding (half-even) within the limits of the floating-point math processor/library of your computer. The bad: drags in your platform math library and requires that it work according to specifications. Requires: IEEE-754 representation is "round nearest" (which it usually is). and never round intermediates. Using intermediates to which rounding has been applied invalidates the precision guarantees (such as they are) of IEEE-754. SQLITE_PRIVATE void _heroundingFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { int p = 0; double x, scale, xval, ipart, fpart, sgn; if ((argc == 0) || (argc > 2)) return; if (sqlite3_value_type(argv[0]) == SQLITE_NULL) return; x = sqlite3_value_double(argv[0]); if (argc == 2) { if (sqlite3_value_type(argv[1]) == SQLITE_NULL) return; p = sqlite3_value_int(argv[1]); p = p > 15 ? 15 : (p < 0 ? 0 : p); } scale = pow(10.0, p); sgn = 1.0; if (x < 0) sgn = -1.0; xval = sgn * x * scale; if (log10(xval) > 16.0) { sqlite3_result_double(context, x); return; } fpart = modf(xval, &ipart); if ((fpart > 0.5) || ((fpart == 0.5) && (fmod(ipart, 2.0) == 1.0))) ipart += 1.0; xval = sgn * ipart / scale; sqlite3_result_double(context, xval); } Note that you can implement "grade school" rounding (round half away from zero) by changing: if ((fpart > 0.5) || ((fpart == 0.5) && (fmod(ipart, 2.0) == 1.0))) ipart += 1.0; to if (fpart => 0.5) ipart += 1.0; This is the part that implements the rounding since you know the sign (sgn), the integer part (ipart), and the remainder (fpart) and unless you change the ipart then the result is merely the truncation of the value (towards zero). --- The fact that there's a Highway to Hell but only a Stairway to Heaven says a lot about anticipated traffic volume. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users