diff options
| author | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-05-29 13:11:32 +0000 | 
|---|---|---|
| committer | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-05-29 13:11:32 +0000 | 
| commit | f262cbb6bea6b384a7fcdee837cda6c51a64fd99 (patch) | |
| tree | c57d8cb9d5c4313b2dcec8df7234100647c7ab55 | |
| parent | 64fc9478af7e83fbf0671d34ed29ed455a279082 (diff) | |
XPath round() is now fully compliant
git-svn-id: http://pugixml.googlecode.com/svn/trunk@461 99668b35-9821-0410-8761-19e4c4f06640
| -rw-r--r-- | src/pugixpath.cpp | 19 | ||||
| -rw-r--r-- | tests/test_xpath_functions.cpp | 3 | 
2 files changed, 12 insertions, 10 deletions
| 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();
 diff --git a/tests/test_xpath_functions.cpp b/tests/test_xpath_functions.cpp index 5fc61fc..0cf91d6 100644 --- a/tests/test_xpath_functions.cpp +++ b/tests/test_xpath_functions.cpp @@ -132,12 +132,9 @@ TEST(xpath_number_round)  	// round with argument in range [-0.5, -0] should result in minus zero
  	CHECK_XPATH_STRING(c, STR("string(1 div round(0))"), STR("Infinity"));
 -
 -#if 0 // $$$ commented out temporarily because round is not compliant yet
  	CHECK_XPATH_STRING(c, STR("string(1 div round(-0.5))"), STR("-Infinity"));
  	CHECK_XPATH_STRING(c, STR("string(1 div round(-0))"), STR("-Infinity"));
  	CHECK_XPATH_STRING(c, STR("string(1 div round(-0.1))"), STR("-Infinity"));
 -#endif
  }
  TEST_XML(xpath_boolean_boolean, "<node />")
 | 
