Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Math expression evaluation error?



On Wed, 14 Jan 2015 16:02:58 +0100
Vincent Lefevre <vincent@xxxxxxxxxx> wrote:
> FORCE_FLOAT doesn't
> force a floating-point evaluation; it just converts *constants* to
> floating-point. See the differences:
> 
> ypig% setopt FORCE_FLOAT
> ypig% integer a=1 b=2
> ypig% echo $((1/2))
> 0.5
> ypig% echo $((a/b))
> 0
> 
> I'm wondering whether this is the expected behavior, though.

I wouldn't have thought so --- I would guess when forcing floating
point calculations people would expect this to happen everywhere,
despite what the documentation for the option says.

This shouldn't be problematic if it's already working for constants
since variables appear in just the same contexts.

diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 076aaf4..8a0222c 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -496,9 +496,10 @@ pindex(NOFORCEFLOAT)
 cindex(floating point, forcing use of)
 cindex(forcing use of floating point)
 item(tt(FORCE_FLOAT))(
-Constants in arithmetic evaluation will be treated as floating point
-even without the use of a decimal point.  Integers in any base
-will be converted.
+Constants in arithmetic evaluation will be treated as
+floating point even without the use of a decimal point; the
+values of integer variables will be converted to floating point when
+used in arithmetic expressions.  Integers in any base will be converted.
 )
 pindex(GLOB)
 pindex(NO_GLOB)
diff --git a/Src/math.c b/Src/math.c
index db42d0f..c047725 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -336,16 +336,27 @@ enum prec_type {
 static mnumber
 getmathparam(struct mathvalue *mptr)
 {
+    mnumber result;
     if (!mptr->pval) {
 	char *s = mptr->lval;
 	mptr->pval = (Value)zhalloc(sizeof(struct value));
 	if (!getvalue(mptr->pval, &s, 1))
 	{
 	    mptr->pval = NULL;
+	    if (isset(FORCEFLOAT)) {
+		result.type = MN_FLOAT;
+		result.u.d = 0.0;
+		return result;
+	    }
 	    return zero_mnumber;
 	}
     }
-    return getnumvalue(mptr->pval);
+    result = getnumvalue(mptr->pval);
+    if (isset(FORCEFLOAT) && result.type == MN_INTEGER) {
+	result.type = MN_FLOAT;
+	result.u.d = (double)result.u.l;
+    }
+    return result;
 }
 
 static mnumber
diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst
index 8e0730d..ea87af2 100644
--- a/Test/C01arith.ztst
+++ b/Test/C01arith.ztst
@@ -308,3 +308,13 @@
 >2
 >2
 # It's hard to test for integer to float.
+
+  integer ff1=3 ff2=4
+  print $(( ff1/ff2 ))
+  setopt force_float
+  print $(( ff1/ff2 ))
+  unsetopt force_float
+0:Variables are forced to floating point where necessary
+# 0.75 is exactly representable, don't expect rounding error.
+>0
+>0.75



Messages sorted by: Reverse Date, Date, Thread, Author