[PATCH] Kill double conversion from NumericBox

Zolnai Tamás (via_Code_Review) gerrit at gerrit.libreoffice.org
Mon Mar 25 13:01:00 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/3035

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/35/3035/1

Kill double conversion from NumericBox

Change-Id: Id1161c40725f75ea0d7ec3f15a19ca14defd0a75
---
M vcl/inc/vcl/field.hxx
M vcl/source/control/field.cxx
2 files changed, 45 insertions(+), 37 deletions(-)



diff --git a/vcl/inc/vcl/field.hxx b/vcl/inc/vcl/field.hxx
index ec661c6..50888c6 100644
--- a/vcl/inc/vcl/field.hxx
+++ b/vcl/inc/vcl/field.hxx
@@ -170,7 +170,7 @@
     void                    FieldLast();
 
     SAL_DLLPRIVATE void     ImplLoadRes( const ResId& rResId );
-    SAL_DLLPRIVATE sal_Bool ImplNumericReformat( const OUString& rStr, double& rValue, OUString& rOutStr );
+    SAL_DLLPRIVATE sal_Bool ImplNumericReformat( const OUString& rStr, sal_Int64& rValue, OUString& rOutStr );
     SAL_DLLPRIVATE void     ImplNewFieldValue( sal_Int64 nNewValue );
     SAL_DLLPRIVATE void     ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection = NULL );
 
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
index 69cb02e..075f6fe 100644
--- a/vcl/source/control/field.cxx
+++ b/vcl/source/control/field.cxx
@@ -89,7 +89,7 @@
 
 // -----------------------------------------------------------------------
 
-static sal_Bool ImplNumericGetValue( const OUString& rStr, double& rValue,
+static sal_Bool ImplNumericGetValue( const OUString& rStr, sal_Int64& rValue,
                                  sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
                                  sal_Bool bCurrency = sal_False )
 {
@@ -196,7 +196,19 @@
     aStr  = aStr1.makeStringAndClear() + aStr2.makeStringAndClear();
 
     // check range
-    double nValue = rtl::OUString(aStr).toDouble();
+    sal_Int64 nValue = aStr.toInt64();
+    if( nValue == 0 )
+    {
+        // check if string is equivalent to zero
+        sal_Int16 nIndex = bNegatvie ? 1 : 0;
+        while( aStr[nIndex] == '0' && nIndex < aStr.getLength() )
+            ++nIndex;
+        if( nIndex < aStr.getLength() )
+        {
+            rValue = bNegative ? SAL_MIN_INT64 : SAL_MAX_INT64;
+            return sal_True;
+        }
+    }
     if (bRound)
     {
         if ( !bNegative )
@@ -428,23 +440,22 @@
 
 // -----------------------------------------------------------------------
 
-sal_Bool NumericFormatter::ImplNumericReformat( const OUString& rStr, double& rValue,
+sal_Bool NumericFormatter::ImplNumericReformat( const OUString& rStr, sal_Int64& rValue,
                                                 OUString& rOutStr )
 {
     if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
         return sal_True;
     else
     {
-        double nTempVal = rValue;
-        // caution: precision loss in double cast
+        sal_Int64 nTempVal = rValue;
         if ( nTempVal > mnMax )
-            nTempVal = (double)mnMax;
+            nTempVal = mnMax;
         else if ( nTempVal < mnMin )
-            nTempVal = (double)mnMin;
+            nTempVal = mnMin;
 
         if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
         {
-            mnCorrectedValue = (sal_Int64)nTempVal;
+            mnCorrectedValue = nTempVal;
             if ( !GetErrorHdl().Call( this ) )
             {
                 mnCorrectedValue = 0;
@@ -454,7 +465,7 @@
                 mnCorrectedValue = 0;
         }
 
-        rOutStr = CreateFieldText( (sal_Int64)nTempVal );
+        rOutStr = CreateFieldText( nTempVal );
         return sal_True;
     }
 }
@@ -627,17 +638,16 @@
     if ( !GetField() )
         return 0;
 
-    double nTempValue;
+    sal_Int64 nTempValue;
 
     if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
                               GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
     {
-        // caution: precision loss in double cast
         if ( nTempValue > mnMax )
-            nTempValue = (double)mnMax;
+            nTempValue = mnMax;
         else if ( nTempValue < mnMin )
-            nTempValue = (double)mnMin;
-        return (sal_Int64)nTempValue;
+            nTempValue = mnMin;
+        return nTempValue;
     }
     else
         return mnLastValue;
@@ -690,10 +700,9 @@
         return;
 
     OUString aStr;
-    // caution: precision loss in double cast
-    double nTemp = (double)mnLastValue;
+    sal_Int64 nTemp = mnLastValue;
     sal_Bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
-    mnLastValue = (sal_Int64)nTemp;
+    mnLastValue = nTemp;
     if ( !bOK )
         return;
 
@@ -1052,7 +1061,7 @@
 
 void NumericBox::ReformatAll()
 {
-    double nValue;
+    sal_Int64 nValue;
     OUString aStr;
     SetUpdateMode( sal_False );
     sal_uInt16 nEntryCount = GetEntryCount();
@@ -1407,14 +1416,16 @@
                                 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
 {
     // Zahlenwert holen
-    if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) )
+    sal_Int64 nValue;
+    if ( !ImplNumericGetValue( rStr, nValue, nDecDigits, rLocaleDataWrapper ) )
         return sal_False;
 
     // Einheit rausfinden
     FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
 
     // Einheiten umrechnen
-    rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
+    // caution: conversion to double loses precision
+    rValue = MetricField::ConvertDoubleValue( (double)nValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
 
     return sal_True;
 }
@@ -2064,7 +2075,7 @@
 
 // -----------------------------------------------------------------------
 
-inline sal_Bool ImplCurrencyGetValue( const OUString& rStr, double& rValue,
+inline sal_Bool ImplCurrencyGetValue( const OUString& rStr, sal_Int64& rValue,
                                   sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper )
 {
     // fetch number
@@ -2075,21 +2086,20 @@
 
 sal_Bool CurrencyFormatter::ImplCurrencyReformat( const OUString& rStr, OUString& rOutStr )
 {
-    double nValue;
+    sal_Int64 nValue;
     if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), sal_True ) )
         return sal_True;
     else
     {
-        double nTempVal = nValue;
-        // caution: precision loss in double cast
+        sal_Int64 nTempVal = nValue;
         if ( nTempVal > GetMax() )
-            nTempVal = (double)GetMax();
+            nTempVal = GetMax();
         else if ( nTempVal < GetMin())
-            nTempVal = (double)GetMin();
+            nTempVal = GetMin();
 
         if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
         {
-            mnCorrectedValue = (sal_Int64)nTempVal;
+            mnCorrectedValue = nTempVal;
             if ( !GetErrorHdl().Call( this ) )
             {
                 mnCorrectedValue = 0;
@@ -2099,7 +2109,7 @@
                 mnCorrectedValue = 0;
         }
 
-        rOutStr = CreateFieldText( (long)nTempVal );
+        rOutStr = CreateFieldText( nTempVal );
         return sal_True;
     }
 }
@@ -2154,15 +2164,14 @@
     if ( !GetField() )
         return 0;
 
-    double nTempValue;
+    sal_Int64 nTempValue;
     if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
     {
-        // caution: precision loss in double cast
         if ( nTempValue > mnMax )
-            nTempValue = (double)mnMax;
+            nTempValue = mnMax;
         else if ( nTempValue < mnMin )
-            nTempValue = (double)mnMin;
-        return (sal_Int64)nTempValue;
+            nTempValue = mnMin;
+        return nTempValue;
     }
     else
         return mnLastValue;
@@ -2183,10 +2192,9 @@
     if ( !aStr.isEmpty() )
     {
         ImplSetText( aStr  );
-        // caution: precision loss in double cast
-        double nTemp = (double)mnLastValue;
+        sal_Int64 nTemp = mnLastValue;
         ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
-        mnLastValue = (sal_Int64)nTemp;
+        mnLastValue = nTemp;
     }
     else
         SetValue( mnLastValue );

-- 
To view, visit https://gerrit.libreoffice.org/3035
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id1161c40725f75ea0d7ec3f15a19ca14defd0a75
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Zolnai Tamás <zolnaitamas2000 at gmail.com>



More information about the LibreOffice mailing list