ooo-build r12491 - in trunk: . patches/dev300
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r12491 - in trunk: . patches/dev300
- Date: Thu, 8 May 2008 16:48:50 +0100 (BST)
Author: kyoshida
Date: Thu May 8 15:48:50 2008
New Revision: 12491
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12491&view=rev
Log:
2008-05-08 Kohei Yoshida <kyoshida novell com>
* patches/dev300/sal-approx-value.diff: improved patch from cws odff03
(i#86775). By moving the approxValue() to sal, we can not only fix INT
but also FLOOR and CEILING functions as well.
* patches/dev300/sc-formula-int-precision.diff: removed; obsolete.
* patches/dev300/apply: apply the new patch instead of the old one.
Added:
trunk/patches/dev300/sal-approx-value.diff
Removed:
trunk/patches/dev300/sc-formula-int-precision.diff
Modified:
trunk/ChangeLog
trunk/patches/dev300/apply
Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply (original)
+++ trunk/patches/dev300/apply Thu May 8 15:48:50 2008
@@ -744,9 +744,10 @@
# button.
sc-cellformat-icon-toggle.diff, n#358548, i#86377, kohei
-# reduce precision to 15 significant digits for INT function before floor'ing
-# the value.
-sc-formula-int-precision.diff, n#310706, i#86775, kohei
+# reduce precision to 15 significant digits for INT, FLOOR, CEILING functions
+# and possibly others that use approxFloor() or approxCeil() functions
+# internally.
+sal-approx-value.diff, n#310706, i#86775, kohei
# overwrite character level font attributes when changing them at cell level.
sc-overwrite-char-font-attrs.diff, n#374580, kohei
Added: trunk/patches/dev300/sal-approx-value.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/sal-approx-value.diff Thu May 8 15:48:50 2008
@@ -0,0 +1,214 @@
+diff --git a/sal/inc/rtl/math.h b/sal/inc/rtl/math.h
+index 73c572b..8f1d6d0 100644
+--- sal/inc/rtl/math.h
++++ sal/inc/rtl/math.h
+@@ -399,6 +399,13 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
+ */
+ double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C();
+
++/** Rounds value to 15 significant decimal digits.
++
++ @param fValue
++ The value to be rounded.
++ */
++double SAL_CALL rtl_math_approxValue(double fValue) SAL_THROW_EXTERN_C();
++
+ #if defined __cplusplus
+ }
+ #endif /* __cplusplus */
+diff --git a/sal/inc/rtl/math.hxx b/sal/inc/rtl/math.hxx
+index 0e63cee..638dc63 100644
+--- sal/inc/rtl/math.hxx
++++ sal/inc/rtl/math.hxx
+@@ -193,6 +193,13 @@ inline double pow10Exp(double fValue, int nExp)
+ return rtl_math_pow10Exp(fValue, nExp);
+ }
+
++/** A wrapper around rtl_math_approxValue.
++ */
++inline double approxValue(double fValue)
++{
++ return rtl_math_approxValue(fValue);
++}
++
+ /** Test equality of two values with an accuracy of the magnitude of the
+ given values scaled by 2^-48 (4 bits roundoff stripped).
+
+@@ -238,38 +245,22 @@ inline double approxSub(double a, double b)
+ return a - b;
+ }
+
+-/** floor() method taking approxEqual() into account.
++/** floor() method taking approxValue() into account.
+
+ Use for expected integer values being calculated by double functions.
+-
+- @ATTENTION
+- The threshhold value is 3.55271e-015
+ */
+ inline double approxFloor(double a)
+ {
+- double b = floor( a );
+- // The second approxEqual() is necessary for values that are near the limit
+- // of numbers representable with 4 bits stripped off. (#i12446#)
+- if ( approxEqual( a - 1.0, b ) && !approxEqual( a, b ) )
+- return b + 1.0;
+- return b;
++ return floor( approxValue( a ));
+ }
+
+-/** ceil() method taking approxEqual() into account.
++/** ceil() method taking approxValue() into account.
+
+ Use for expected integer values being calculated by double functions.
+-
+- @ATTENTION
+- The threshhold value is 3.55271e-015
+ */
+ inline double approxCeil(double a)
+ {
+- double b = ceil( a );
+- // The second approxEqual() is necessary for values that are near the limit
+- // of numbers representable with 4 bits stripped off. (#i12446#)
+- if ( approxEqual( a + 1.0, b ) && !approxEqual( a, b ) )
+- return b - 1.0;
+- return b;
++ return ceil( approxValue( a ));
+ }
+
+ /** Tests whether a value is neither INF nor NAN.
+diff --git a/sal/rtl/source/math.cxx b/sal/rtl/source/math.cxx
+index c7a7d89..deb8a02 100644
+--- sal/rtl/source/math.cxx
++++ sal/rtl/source/math.cxx
+@@ -49,6 +49,37 @@
+ #include <math.h>
+ #include <stdlib.h>
+
++
++static int const n10Count = 16;
++static double const n10s[2][n10Count] = {
++ { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8,
++ 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16 },
++ { 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8,
++ 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16 }
++};
++
++// return pow(10.0,nExp) optimized for exponents in the interval [-16,16]
++static double getN10Exp( int nExp )
++{
++ if ( nExp < 0 )
++ {
++ if ( -nExp <= n10Count )
++ return n10s[1][-nExp-1];
++ else
++ return pow( 10.0, static_cast<double>( nExp ) );
++ }
++ else if ( nExp > 0 )
++ {
++ if ( nExp <= n10Count )
++ return n10s[0][nExp-1];
++ else
++ return pow( 10.0, static_cast<double>( nExp ) );
++ }
++ else // ( nExp == 0 )
++ return 1.0;
++}
++
++
+ namespace {
+
+ double const nKorrVal[] = {
+@@ -212,7 +243,7 @@ inline void doubleToString(StringT ** pResult,
+ if ( fValue > 0.0 )
+ {
+ nExp = static_cast< int >( floor( log10( fValue ) ) );
+- fValue /= pow( 10.0, static_cast< double >( nExp ) );
++ fValue /= getN10Exp( nExp );
+ }
+
+ switch ( eFormat )
+@@ -799,7 +830,7 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
+ if ( nDecPlaces < -20 || 20 < nDecPlaces || fValue > (DBL_MAX / 1e20) )
+ return bSign ? -fValue : fValue;
+
+- fFac = pow( 10.0, nDecPlaces );
++ fFac = getN10Exp( nDecPlaces );
+ fValue *= fFac;
+ }
+ //else //! uninitialized fFac, not needed
+@@ -891,30 +922,40 @@ double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
+ return bSign ? -fValue : fValue;
+ }
+
++
+ double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C()
+ {
+- static int const n10Count = 16;
+- static double const n10s[2][n10Count] = {
+- { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8,
+- 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16 },
+- { 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8,
+- 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16 }
+- };
++ return fValue * getN10Exp( nExp );
++}
+
+- if ( nExp < 0 )
+- {
+- if ( -nExp <= n10Count )
+- return fValue * n10s[1][-nExp-1];
+- else
+- return fValue * pow( 10.0, static_cast<double>( nExp ) );
+- }
+- else if ( nExp > 0 )
+- {
+- if ( nExp <= n10Count )
+- return fValue * n10s[0][nExp-1];
+- else
+- return fValue * pow( 10.0, static_cast<double>( nExp ) );
+- }
+- else
++
++double SAL_CALL rtl_math_approxValue( double fValue ) SAL_THROW_EXTERN_C()
++{
++ if (fValue == 0.0 || fValue == HUGE_VAL || !::rtl::math::isFinite( fValue))
++ // We don't handle these conditions. Bail out.
+ return fValue;
++
++ double fOrigValue = fValue;
++
++ bool bSign = ::rtl::math::isSignBitSet( fValue);
++ if (bSign)
++ fValue = -fValue;
++
++ int nExp = static_cast<int>( floor( log10( fValue)));
++ nExp = 14 - nExp;
++ double fExpValue = getN10Exp( nExp);
++
++ fValue *= fExpValue;
++ // If the original value was near DBL_MIN we got an overflow. Restore and
++ // bail out.
++ if (!rtl::math::isFinite( fValue))
++ return fOrigValue;
++ fValue = rtl_math_round( fValue, 0, rtl_math_RoundingMode_Corrected);
++ fValue /= fExpValue;
++ // If the original value was near DBL_MAX we got an overflow. Restore and
++ // bail out.
++ if (!rtl::math::isFinite( fValue))
++ return fOrigValue;
++
++ return bSign ? -fValue : fValue;
+ }
+diff --git a/sal/util/sal.map b/sal/util/sal.map
+index 9f69e5e..60ae875 100755
+--- sal/util/sal.map
++++ sal/util/sal.map
+@@ -572,6 +572,7 @@ UDK_3.7 { # OOo 2.4
+ UDK_3.8 { # OOo 3.0
+ global:
+ rtl_convertStringToUString;
++ rtl_math_approxValue;
+ } UDK_3.7;
+
+ PRIVATE_1.0 {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]