From f262cbb6bea6b384a7fcdee837cda6c51a64fd99 Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Sat, 29 May 2010 13:11:32 +0000 Subject: XPath round() is now fully compliant git-svn-id: http://pugixml.googlecode.com/svn/trunk@461 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixpath.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 9562ca1..d20baad 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -436,9 +436,15 @@ namespace #endif } - double ieee754_round(double value) + double round_nearest(double value) { - return is_nan(value) ? value : floor(value + 0.5); + return floor(value + 0.5); + } + + double round_nearest_nzero(double value) + { + // same as round_nearest, but returns -0 for [-0.5, -0] + return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); } const char_t* local_name(const char_t* name) @@ -2104,8 +2110,7 @@ namespace pugi } case ast_func_round: - // correct except for negative zero (it returns positive zero instead of negative) - return ieee754_round(m_left->eval_number(c)); + return round_nearest_nzero(m_left->eval_number(c)); default: { @@ -2232,7 +2237,7 @@ namespace pugi case ast_func_substring_2: { string_t s = m_left->eval_string(c); - double first = ieee754_round(m_right->eval_number(c)); + double first = round_nearest(m_right->eval_number(c)); if (is_nan(first)) return string_t(); // NaN else if (first >= s.length() + 1) return string_t(); @@ -2245,8 +2250,8 @@ namespace pugi case ast_func_substring_3: { string_t s = m_left->eval_string(c); - double first = ieee754_round(m_right->eval_number(c)); - double last = first + ieee754_round(m_third->eval_number(c)); + double first = round_nearest(m_right->eval_number(c)); + double last = first + round_nearest(m_third->eval_number(c)); if (is_nan(first) || is_nan(last)) return string_t(); else if (first >= s.length() + 1) return string_t(); -- cgit v1.2.3