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

Re: Floating point modulus



On 01/10/2015 11:10 PM, Bart Schaefer wrote:
Consequently the operands are silently converted to integers, instead
of the shell throwing an error.

The expectation is that you will know that zsh math is C math (same
as for why things are integer by default) and that you must do:

Expectation you say.  Wouldn't it be polite for the docs to at least
mention that? Modulo is in a list with other standard operators,
no indication whatsoever that it has different limitations. And,
given that modulo, even with floating point, is (dare I say)
near the simplest of  arithmetic operations, I'd have thought
that floating point modulo would have been near the first thing
implemented.

   mod-you-loh ()
   {
   setopt force_float
   echo "Your number is: $1"
   echo "Your modulator (what is the proper word for that?) is: $2"
   remainder=$1
   while [[ $remainder > $2 ]]; do
        let remainder=$remainder-$2
        echo "Chewing away ... $remainder"
        done
   echo "All done, the remainder is: $remainder"
   }

   $ mod-you-loh 7.5 2

   Your number is: 7.5
   Your modulator (what is the proper word for that?) is: 2
   Chewing away ... 5.5
   Chewing away ... 3.5
   Chewing away ... 1.5
   All done, the remainder is: 1.5

... even I can do it in three minutes. But it's not built in?

<anecdote>
Having zsh math brought to mind, I was thinking where I could use it
in my own  functions, and the first thing that came to mind is a place
where modulo would be just the thing.  (I am currently using
something like my pretend function above).  How nice to be able
to forget the function and have all that power in one symbol:  " % ".
Nope.  Integers only. :(
</>
     $ zmodload zsh/mathfunc
     $ echo $(( fmod(2.5, 2) ))
     0.5

The following patch would instead silently substitute the fmod() call
when using the % operator on a float.  I won't commit it without some
further discussion from the group.  With more effort it could be made
to do this only when FORCE_FLOAT is in effect, though I'm not sure
how many such special-cases we want to manage.


diff --git a/Src/math.c b/Src/math.c
index 438a170..6d096e0 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -288,11 +288,11 @@ static int type[TOKCOUNT] =
  {
  /*  0 */  LR, LR|OP_OP|OP_OPF, RL, RL, RL|OP_OP|OP_OPF,
  /*  5 */  RL|OP_OP|OP_OPF, RL, RL, LR|OP_A2IO, LR|OP_A2IO,
-/* 10 */  LR|OP_A2IO, LR|OP_A2, LR|OP_A2, LR|OP_A2IO, LR|OP_A2,
+/* 10 */  LR|OP_A2IO, LR|OP_A2, LR|OP_A2, LR|OP_A2, LR|OP_A2,
  /* 15 */  LR|OP_A2, LR|OP_A2IO, LR|OP_A2IO, LR|OP_A2IR, LR|OP_A2IR,
  /* 20 */  LR|OP_A2IR, LR|OP_A2IR, LR|OP_A2IR, LR|OP_A2IR, BOOL|OP_A2IO,
  /* 25 */  BOOL|OP_A2IO, LR|OP_A2IO, RL|OP_OP, RL|OP_OP, RL|OP_E2,
-/* 30 */  RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2IO,
+/* 30 */  RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2, RL|OP_E2,
  /* 35 */  RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO, RL|OP_E2IO,
  /* 40 */  BOOL|OP_E2IO, BOOL|OP_E2IO, RL|OP_A2IO, RL|OP_A2, RL|OP_OP,
  /* 45 */  RL, RL, LR|OP_OPF, LR|OP_OPF, RL|OP_A2,

I need to go and have a little cry.



@@ -1133,7 +1133,9 @@ op(int what)
  		 * Any integer mod -1 is the same as any integer mod 1
  		 * i.e. zero.
  		 */
-		if (b.u.l == -1)
+		if (c.type == MN_FLOAT)
+		    c.u.d = fmod(a.u.d, b.u.d);
+		else if (b.u.l == -1)
  		    c.u.l = 0;
  		else
  		    c.u.l = a.u.l % b.u.l;

Gentlemen. Perhaps it's presumptuous of me to discuss this, but could a time not come when zsh is no longer chained to past practice? When decisions are based on merit, not on what ksh '79 did? Just for argument's sake, supposing zsh 6.0 was the breakout version. Everything in it is there on merit. Floating point math there by default! 1/2 + 1/2 = 1! Shocking, unprecedented, revolutionary!

No rc compatibility. Mind, it's not that good things learned from rc would go away, it's just that they'd be there simply because they are good things and they might be modified to be even better, *even* if that was no longer rc compatible. Instead of having to drive forward while looking backwards out the rear window, imagine driving forward looking forward. Never forgetting the past, but not being limited by it either.

Honestly now: how many converts do we get from csh anymore? Haven't most of them already come in from the cold? I suggest that the future of zsh is not with welcoming in the few remaining csh long beards, but by making the shell more usable for brand new people. People who expect 1/2 + 1/2 = 1. People familiar with electronic calculators. "Zsh 6.0 ... the shell of the future!" No?

Even bash converts--we might think they come over because zsh is compatible, but perhaps even more would come over because it *isn't* compatible, it's better. Which is to say that if bash has some silliness, zsh would pointedly *not* have it no matter how venerable the silliness may be. Zsh already does that on several points. Ah have a dream today. People say the future is with Python and it's 'modern' cousins. Maybe, but shells will always be there, so why don't we make a forward looking one? I'm not saying that the ancient scrolls should be burned just that they no longer 'control' or limit or enforce counterproductive traditions on us. Battle cry: " 1/2 + 1/2 = 1 ".



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