zsh-workers
 help / color / mirror / code / Atom feed
From: Stephane Chazelas <stephane.chazelas@gmail.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: inf and nan in arithmetic expansions
Date: Wed, 7 Feb 2018 22:30:51 +0000	[thread overview]
Message-ID: <20180207223051.GA30393@chaz.gmail.com> (raw)

Hi,

While looking into:
https://unix.stackexchange.com/questions/422122/why-does-0-1-expand-to-0-10000000000000001-in-zsh

I noted that zsh is very good at making sure that the result of
floating point arithmetic expansions are always suitable for
reinput inside other arithmetic expansions as floats.

For instance $((0.5 * 2)) expands to 1. and not 1 so that
when used in arithmetic expressions, it is still a float.

Or that is (I think) why numbers are expressed with 17 digits,
the full precision of IEEE 754 doubles, so that when reinput, we
get the same double.

Now, there's one case where it doesn't work is when the
expansion results into nan or inf

$ echo $((1e500))
inf.
$ echo $(($((1e500))))
zsh: bad floating point constant
$ a=$((1e200**2))
$ echo $((a))
zsh: bad floating point constant
$ echo $((1e500/1e500))
-nan.
$ echo $(($((1e500/1e500))))
zsh: bad floating point constant

See also:

$ typeset -F a; a=$((1e500))
zsh: bad floating point constant


neither "inf." nor "inf" are understood in arithmetic
expressions (and for "inf.", nor by other tools like awk, or
even the builtin printf):

$ printf '%f\n' inf nan infinity NAN
inf
nan
inf
nan
$ printf '%f\n' inf. nan.
zsh: bad floating point constant
zsh: bad floating point constant
0.000000
0.000000

Not sure what's the best way to address that. 

At the moment, $((inf)) is meant to expand to the result of
the arithmetic expression in $inf

$ inf=1+1 zsh -c 'echo $((inf))'
2

It should be safe to change zsh so that inf. (and Inf. INF. NAN.
nan., maybe also Infinity.) are recognised in arithmetic
expression, as it's currently invalid, but that leaves the
problem of "inf." not being recognised by other tools
(awk/printf).

yash and ksh93 are the two other POSIX-like shells (that I know)
that support floating point arithmetics. yash is not much
better:

$ echo $((1e400))
yash: arithmetic: `1e500' is not a valid number
$ echo $((1e200*1e200))
inf
$ inf=42; echo $(($((1e200*1e200))))
42

ksh93 recognises inf (not infinity, same for its printf) and nan
on input:

$ echo $((1e6000))
inf
$ echo $((INF))
inf
$ echo $((nan))
nan
$ echo $((infinity))
0

It is documented (though not the fact that all case variants are
supported).

Slightly related:

The printf builtin understands the C99 hex with binary
exponent on input (where strtod supports them), but not on
output (%a, %A) and not in arithmetic expressions

$ printf "%g\n" 0x1p4
16
$ printf "%a\n" 16
printf: %a: invalid directive
$ echo $((0x1p4))
zsh: bad math expression: operator expected at `p4'

yash and ksh93 do support them.

(not that I would need them, that would be more for
consistency).

-- 
Stephane


             reply	other threads:[~2018-02-07 22:31 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-07 22:30 Stephane Chazelas [this message]
2018-02-07 23:25 ` Oliver Kiddle
2018-02-08  9:38   ` Peter Stephenson
2018-02-08 12:46   ` Daniel Shahaf
2018-02-08 14:22     ` Stephane Chazelas
2018-02-09 15:31       ` Daniel Shahaf
2018-02-09 21:09         ` Stephane Chazelas
2018-02-10  0:10           ` Bart Schaefer
2018-02-16 16:51     ` Oliver Kiddle
2018-02-17  0:38       ` Daniel Shahaf
2018-02-19 14:19         ` Stephane Chazelas
2018-02-27 13:02       ` Vincent Lefevre
2018-02-27 15:25         ` Oliver Kiddle
2018-02-27 16:56           ` Vincent Lefevre
2018-03-21 23:46       ` Oliver Kiddle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180207223051.GA30393@chaz.gmail.com \
    --to=stephane.chazelas@gmail.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).