r16 - 08 Mar 2007 - 23:44:36 - Sergej ZnamenskijВы сейчас здесь: TWiki >  Раздел Support/Bugs > Item4

Item4: SpreadSheetPlugin: $ROUND gives incorrect result

Срочность: Текущее состояние: Относится к: Компонента: Кого ждёт:
Urgent Closed Extensions   Sergej Znamenskij

Подробности

Hello!

Using SpreadSheetPlugin for electronic engineering, we encountered incorrect behaviour of the $ROUND function. Here is an example demonstrating the problem.

ROUND(3.15, 1) expect 3.2 got 3.2 OK
ROUND(3.149, 1) expect 3.1 got 3.1 OK
ROUND(-2.475, 2) expect -2.48 got -2.48 OK
ROUND(34.9, -1) expect 30 got 30 OK
ROUND(0.0000275, 3) expect 0.000 got 0 WRONG
ROUND(1.0443e-05,4) expect 0 got 0 WRONG

Thank you

-- Yury Shevchuk - 05 Mar 2007

The last line looked like this:

ROUND(0.0000275, 3) expect 0.000 got 2.75 WRONG

I have hacked SpreadSheetPlugin/Calc.pm, sub _getNumber. Now it returns 0 which maybe even better than 0.000 that I originally suggested.

Original Calc.pm is saved as /tmp/Calc.pm.orig. Here is the patch:


http://twiki.org/cgi-bin/viewfile/Plugins/TreeBrowserPlugin?rev=12;filename=TreeBrowserPlugin.zip--- /home/twiki/_TWikiFace.twiki/lib/TWiki/Plugins/SpreadSheetPlugin/Calc.pm.orig       2007-03-07 10:12:53.000000000 +0300
+++ /home/twiki/_TWikiFace.twiki/lib/TWiki/Plugins/SpreadSheetPlugin/Calc.pm    2007-03-07 10:11:47.000000000 +0300
@@ -930,14 +930,20 @@
 sub _getNumber
 {
     my( $theText ) = @_;
+warn "_getNumber($theText)";
     return 0 unless( $theText );
     $theText =~ s/([0-9])\,(?=[0-9]{3})/$1/go;          # "1,234,567" ==> "1234567"
+    if ($theText =~ /[0-9]e/i) {                        # "1.5e-3"    ==> "0.0015"
+        $theText = sprintf "%.20f", $theText;
+        $theText =~ s/0+$//;
+    }
     unless( $theText =~ s/^.*?(\-?[0-9\.]+).*$/$1/o ) { # "xy-1.23zz" ==> "-1.23"
         $theText = 0;
     }
     $theText =~ s/^(\-?)0+([0-9])/$1$2/o;               # "-0009.12"  ==> "-9.12"
     $theText =~ s/^(\-?)\./${1}0\./o;                   # "-.25"      ==> "-0.25"
     $theText =~ s/^\-0$/0/o;                            # "-0"        ==> "0"
+warn "_getNumber returning $theText";
     return $theText;
 }

@@ -945,11 +951,10 @@
 sub safeEvalPerl
 {
     my( $theText ) = @_;
-
     # Allow only simple math with operators - + * / % ( )
     $theText =~ s/\%\s*[^\-\+\*\/0-9\.\(\)]+//go; # defuse %hash but keep modulus
     # keep only numbers and operators (shh... don't tell anyone, we support comparison operators)
-    $theText =~ s/[^\!\<\=\>\-\+\*\/\%0-9\.\(\)]*//go;
+    $theText =~ s/[^\!\<\=\>\-\+\*\/\%0-9e\.\(\)]*//go;
     $theText =~ /(.*)/;
     $theText = $1;  # untainted variable
     return "" unless( $theText );

Мне не удалочсь воспроизвести сбой с потерей verbatim. Возможно он был как-то связан с строкой

<!--
выше

Патч доведен до разработчиков: http://develop.twiki.org/~twiki4/cgi-bin/view/Bugs/Item3743

-- Sergej Znamenskij - 07 Mar 2007

 

ItemTemplate
Summary SpreadSheetPlugin: $ROUND gives incorrect result
ReportedBy Yury Shevchuk
AppliesTo Extensions
Priority Urgent
Current State Closed
Waiting For Sergej Znamenskij
 
Powered by TWiki

This site is powered by the TWiki collaboration platformАвторские права © закреплены за авторами проекта. Все материалы по этой платформе сотрудничества являются их собственностью.
Есть идеи, вопросы или проблемы, связанные с TWiki? Свяжитесь с нами