*X-seq*: zsh-workers 34235*From*: Ray Andrews <rayandrews@xxxxxxxxxxx>*To*: zsh-workers@xxxxxxx*Subject*: Re: Floating point modulus*Date*: Sun, 11 Jan 2015 11:25:37 -0800*In-reply-to*: <150110231017.ZM24021@torch.brasslantern.com>*List-help*: <mailto:zsh-workers-help@zsh.org>*List-id*: Zsh Workers List <zsh-workers.zsh.org>*List-post*: <mailto:zsh-workers@zsh.org>*Mailing-list*: contact zsh-workers-help@xxxxxxx; run by ezmlm*References*: <1420807419-9270-1-git-send-email-mikachu@gmail.com> <54B013C5.6090307@eastlink.ca> <CAHYJk3TfLxqaHxPF6Vn+HNXzip8VbXLpsNo5Oyej8cVdFZteyw@mail.gmail.com> <54B04A7A.1010402@eastlink.ca> <20150109223028.6e003bff@ntlworld.com> <54B066C5.3010008@eastlink.ca> <CAH+w=7baPVRYOz0SwhnnkqAn2V09r5kFHqsF2He_PYNZRW5e_Q@mail.gmail.com> <54B0D893.4080202@eastlink.ca> <510FB8E2-EA0C-4582-BD31-527E9755F0FB@larryv.me> <54B1ACA3.1050001@eastlink.ca> <150110175849.ZM21774@torch.brasslantern.com> <54B20E23.8090900@eastlink.ca> <150110231017.ZM24021@torch.brasslantern.com>

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;

**Follow-Ups**:**Re: Floating point modulus***From:*Bart Schaefer

**References**:**PATCH: hist: remove wrong NULL terminator***From:*Mikael Magnusson

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Re: PATCH: hist: remove wrong NULL terminator***From:*Mikael Magnusson

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Re: PATCH: hist: remove wrong NULL terminator***From:*Peter Stephenson

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Re: PATCH: hist: remove wrong NULL terminator***From:*Bart Schaefer

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Re: PATCH: hist: remove wrong NULL terminator***From:*Lawrence Velázquez

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Re: PATCH: hist: remove wrong NULL terminator***From:*Bart Schaefer

**Re: PATCH: hist: remove wrong NULL terminator***From:*Ray Andrews

**Floating point modulus***From:*Bart Schaefer

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