Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1090089 into 
lp:zorba.

Commit message:
Rewrote decimal reduction code -- fixes rounding and FOTS distinct-values tests.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1090089 in Zorba: "fn-distinct-values different results from test"
  https://bugs.launchpad.net/zorba/+bug/1090089

For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-1090089/+merge/163085

Rewrote decimal reduction code -- fixes rounding and FOTS distinct-values tests.
-- 
https://code.launchpad.net/~paul-lucas/zorba/bug-1090089/+merge/163085
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/zorbatypes/decimal.cpp'
--- src/zorbatypes/decimal.cpp	2013-05-05 03:16:33 +0000
+++ src/zorbatypes/decimal.cpp	2013-05-09 05:21:28 +0000
@@ -73,98 +73,62 @@
 }
 
 /**
- * Remove trailing .99999 or .000001.
- * Find four or five consecutive 9 or 0 after decimal point and eliminate them.
+ * Removes trailing .999 or .001.
  */
 void Decimal::reduce( char *s ) {
-  char *dot = strrchr( s, '.' );
-  if ( !dot )                           // not a floating point number
+  if ( !strrchr( s, '.' ) )             // not a floating-point number
     return;
 
-  bool has_e = false;
-  char *e = strrchr( s, 'E' );
-  if ( !e )
-    e = strrchr( s, 'e' );
-  if ( !e )
-    e = s + strlen( s );
-  else
-    has_e = true;
-
-  char *digits = e - 1;
-  for ( int pos = (int)(digits - dot); pos > 8; --pos, --digits ) {
-    if ( *digits == '9' ) {
-      if ( digits[-1] == '9' && digits[-2] == '9' && digits[-3] == '9' ) {
-        if ( ascii::is_digit( digits[1] ) && digits[1] >= '5' )
-          digits -= 4;
-        else if ( digits[-4] == '9' )
-          digits -= 5;
-        else
-          continue;
-
-        // now add 1 to remaining digits
-        char *last_digit = digits;
-        while ( digits >= s ) {
-          if ( digits[0] == '.' ) {
-            // skip
-          } else if ( digits[0] == '9' ) {
-            digits[0] = '0';
-            if ( last_digit == digits )
-              --last_digit;
-          } else {
-            if ( ascii::is_digit( digits[0] ) )
-              digits[0]++;
-            break;
-          }
-          --digits;
-        }
-        if ( last_digit[0] != '.' )
-          ++last_digit;
-        else if ( has_e ) {
-          last_digit[1] = '0';
-          last_digit += 2;
-        }
-        if ( digits < s || !ascii::is_digit( digits[0] ) ) {
-          memmove( s + 1, s, last_digit - s );
-          ++last_digit;
-          if ( ascii::is_digit( s[0] ) )
-            s[0] = '1';
-          else
-            s[1] = '1';
-          if ( has_e ) {                // increment the exponent
-            ++dot;
-            dot[0] = dot[-1];
-            dot[-1] = '.';
-            sprintf( e + 1, "%d", atoi( e + 1 ) + 1 );
-            --last_digit;
-          }
-        }
-        int const e_len = strlen( e );
-        memmove( last_digit, e, e_len );
-        last_digit[ e_len ] = 0;
-        break;
-      }
-    } else if ( *digits == '0' ) {
-      if ( digits[-1] == '0' && digits[-2] == '0' && digits[-3] == '0' ) {
-        if ( ascii::is_digit( digits[1] ) && digits[1] < '5' )
-          digits -= 4;
-        else if ( digits[-4] == '0' )
-          digits -= 5;
-        else
-          continue;
-        while ( *digits == '0' )
-          --digits;
-        if ( *digits != '.' )
-          ++digits;
-        else if ( has_e ) {
-          digits[1] = '0';
-          digits += 2;
-        }
-        int const e_len = strlen( e );
-        memmove( digits, e, e_len );
-        digits[ e_len ] = '\0';
-        break;
-      }
-    }
+  char *e = strpbrk( s, "eE" );
+  if ( !e )
+    e = s + strlen( s );                // eliminates special-case
+
+  char *digit = e - 1;
+  switch ( *digit ) {
+    case '0':                           // trim trailing zeros
+      while ( *digit == '0' )
+        *digit-- = '\0';
+      if ( *digit == '.' )
+        *digit = '\0';
+      break;
+    case '1':
+      int zeros;
+      for ( zeros = 0; *--digit == '0'; ++zeros )
+        ;
+      if ( zeros >= 3 )                 // this seems arbitrary
+        digit[ *digit != '.' ] = '\0';
+      break;
+    case '9':
+      int nines;
+      for ( nines = 1; *--digit == '9'; ++nines )
+        ;
+      if ( nines > 1 ) {
+        if ( *digit != '.' ) {          // 123.4...99...
+          ++digit[0];
+          ++digit;
+          // slide to the left: 123.4...99...[E12] => 123.4...[E12]
+          memmove( digit, digit + nines, strlen( e ) + 1 );
+        } else {                        // 123.99...
+          *digit-- = '\0';
+          char const *const first = *s == '-' ? s + 1 : s;
+          while ( true ) {
+            if ( *digit == '9' ) {
+              *digit = '0';
+              if ( digit == first ) {
+                // slide to the right to insert a leading '1'
+                memmove( digit + 1, digit, strlen( digit ) + 1 );
+                *digit = '1';
+                break;
+              }
+              --digit;
+            } else {
+              ++digit[0];
+              break;
+            }
+          }
+        }
+      }
+      break;
   }
 }
 

=== modified file 'src/zorbatypes/floatimpl.cpp'
--- src/zorbatypes/floatimpl.cpp	2013-05-04 17:29:21 +0000
+++ src/zorbatypes/floatimpl.cpp	2013-05-09 05:21:28 +0000
@@ -351,11 +351,7 @@
     return "0";
   if ( isNegZero() )
     return "-0";
-
-  // TODO: make xs_int
-  char buf[174];
-  sprintf( buf, "%d", (int)value_ );
-  return buf;
+  return ztd::to_string( static_cast<long long>( value_ ) );
 }
 
 template<typename F>
@@ -379,9 +375,9 @@
 #if 1
     // This is the "spec" implementation, i.e., it is an exact application of
     // the spec in  http://www.w3.org/TR/xpath-functions/#casting
-    MAPM decimal_mapm( value_ );
-    decimal_mapm = decimal_mapm.round( precision_ );
-    return Decimal::toString( decimal_mapm, isNegZero(), max_precision() );
+    MAPM temp( value_ );
+    temp = temp.round( precision_ );
+    return Decimal::toString( temp, isNegZero(), precision_ );
 #else
     std::stringstream stream;
     stream.precision(7);

=== modified file 'src/zorbatypes/integer.cpp'
--- src/zorbatypes/integer.cpp	2013-05-07 00:39:46 +0000
+++ src/zorbatypes/integer.cpp	2013-05-09 05:21:28 +0000
@@ -19,7 +19,6 @@
 // standard
 #include <cerrno>
 #include <cstdlib>
-#include <sstream>
 
 // Zorba
 #include <zorba/internal/unique_ptr.h>
@@ -38,12 +37,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-ostream& operator<<( ostream &o, MAPM const &m ) {
-  unique_ptr<char[]> const buf( new char[ m.exponent() + 3 ] );
-  m.toIntegerString( buf.get() );
-  return o << buf.get();
-}
-
 void integer_traits::throw_error( string const &what, bool throw_range_error ) {
   if ( throw_range_error )
     throw range_error( what );
@@ -52,9 +45,9 @@
 
 void integer_traits::throw_error( MAPM const &n, char const *op,
                                   bool throw_range_error ) {
-  ostringstream oss;
-  oss << n;
-  string const what( BUILD_STRING( oss.str(), ": not ", op, " 0" ) );
+  unique_ptr<char[]> const buf( new char[ n.exponent() + 3 ] );
+  n.toIntegerString( buf.get() );
+  string const what( BUILD_STRING( buf.get(), ": not ", op, " 0" ) );
   throw_error( what, throw_range_error );
 }
 

=== modified file 'src/zorbatypes/integer.h'
--- src/zorbatypes/integer.h	2013-05-07 00:39:46 +0000
+++ src/zorbatypes/integer.h	2013-05-09 05:21:28 +0000
@@ -50,8 +50,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-std::ostream& operator<<( std::ostream&, MAPM const& );
-
 struct integer_traits {
   static int const default_value = 0;
 

=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt	2013-05-08 20:14:47 +0000
+++ test/fots/CMakeLists.txt	2013-05-09 05:21:28 +0000
@@ -157,8 +157,6 @@
 EXPECTED_FOTS_FAILURE (fn-available-environment-variables fn-available-environment-variables-011 0)
 EXPECTED_FOTS_FAILURE (fn-deep-equal K2-SeqDeepEqualFunc-36 0)
 EXPECTED_FOTS_FAILURE (fn-deep-equal K2-SeqDeepEqualFunc-37 0)
-EXPECTED_FOTS_FAILURE (fn-distinct-values cbcl-distinct-values-002 1090089)
-EXPECTED_FOTS_FAILURE (fn-distinct-values cbcl-distinct-values-002b 1090089)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-005 0)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-006 0)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-007 0)

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-01.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-01.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+1.9

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-02.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-02.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+2

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-03.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+1.6

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-04.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-04.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-04.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+10

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-05.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-05.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-05.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+-1.9

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-06.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-06.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-06.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+-2

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-07.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-07.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-07.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+-1.6

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-08.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-08.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-08.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+-10

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-09.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-09.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-09.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+1

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-10.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-10.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-10.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+1

=== added file 'test/rbkt/ExpQueryResults/zorba/numerics/xs_float-11.xml.res'
--- test/rbkt/ExpQueryResults/zorba/numerics/xs_float-11.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/xs_float-11.xml.res	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+1.234

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-01.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-01.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-01.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.899)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-02.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-02.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-02.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.99)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-03.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-03.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-03.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.599)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-04.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-04.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-04.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(9.999)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-05.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-05.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-05.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(-1.899)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-06.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-06.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-06.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(-1.99)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-07.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-07.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-07.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(-1.599)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-08.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-08.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-08.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(-9.999)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-09.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-09.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-09.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.0001)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-10.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-10.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-10.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.00001)

=== added file 'test/rbkt/Queries/zorba/numerics/xs_float-11.xq'
--- test/rbkt/Queries/zorba/numerics/xs_float-11.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/numerics/xs_float-11.xq	2013-05-09 05:21:28 +0000
@@ -0,0 +1,1 @@
+xs:float(1.2340001)

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to