From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11759 invoked by alias); 7 Feb 2018 22:31:06 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 42344 Received: (qmail 20182 invoked by uid 1010); 7 Feb 2018 22:31:06 -0000 X-Qmail-Scanner-Diagnostics: from mail-wr0-f180.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(209.85.128.180):SA:0(-1.9/5.0):. Processed in 7.308957 secs); 07 Feb 2018 22:31:06 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: stephane.chazelas@gmail.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mail-followup-to:mime-version :content-disposition:user-agent; bh=gDDzet8x3bWk1fNYHj19ddFewoF4m5MHLsrwbi6llDY=; b=o1S0yHqLbmkh+hCA5zJFy9G9Sg/Qss3Wdf3wHSqyHRe6Fbp5ILNObvW6Gvy+sm3bwZ 08r7Vgj3t7QlA5T8w3WBTY4drAmlAdXIZUbHRSH1rqJn5Lero05wQT1kCMzbf7HJHESp gpc0AvI2xEBtQL7CJB8osQ7m4Cv5/qbeFxsOyKIMIVV8ttZTQ0Cem3M3piCGnt6chwgM wGlpKJAjhnpeEGLddmm/e6NryAYp3P98SyShwNPGEKMV7xWnhG11OR8YJii7Bw9hFkEd hphSYwYHiIETxcz0/8Et/yzglZVYPybxF/W5Zlb+cEFlgk3pDJeLkYROWQM9SvO9FbO+ F+pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mail-followup-to :mime-version:content-disposition:user-agent; bh=gDDzet8x3bWk1fNYHj19ddFewoF4m5MHLsrwbi6llDY=; b=D7y7pHrIJkii/ExdvRFUXm2bD+p4NOl73Z0WAdNUMCYSNQ/uiWQrALKoTxF26xh4Yx vpqYzmmuK8aHWJbMThCyCnHrsUSDw3QjkOf0moyZgDUtIqbenFeOO70oOkKktm8zMgKz OtobxLtf1fz0VX2LcMWGjQASH6hWxEFjg20ZYzpbUbFwzLWzEGLIboJbm+wjtbMaEzSP de+iqKFxFWOYaDKstg4vlj/uYYj7UDnjf0J+yqXwfz0EN5ELxCLjr1io1r1MScHXGx4A f3Xv0GwoniyrE7oWR0W3WjDxWjBSqITlrk3d97fFX2EYIOMG5FOC0sQMcGAW64tt2eEc fL/Q== X-Gm-Message-State: APf1xPC4B5tvoptir2VE5T6HgNFB02BMTBZU+WZMPY7WTk0bZjZhXlCn knPhkElf7hlYjbYr+GiQe2UAdQ== X-Google-Smtp-Source: AH8x226hMBnmtokMbuDYQaTFeeAqo7ZxehqjM9PNT27EOXVgfVvq9GGBciiGcNTDJGtRAl0M7a+Nvw== X-Received: by 10.223.144.163 with SMTP id i32mr7567929wri.73.1518042653941; Wed, 07 Feb 2018 14:30:53 -0800 (PST) Date: Wed, 7 Feb 2018 22:30:51 +0000 From: Stephane Chazelas To: Zsh hackers list Subject: inf and nan in arithmetic expansions Message-ID: <20180207223051.GA30393@chaz.gmail.com> Mail-Followup-To: Zsh hackers list MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) 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