diff options
17 files changed, 5105 insertions, 2445 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html index eb355ab053d..7055bf2e04e 100644 --- a/Master/texmf-dist/doc/generic/xint/CHANGES.html +++ b/Master/texmf-dist/doc/generic/xint/CHANGES.html @@ -4,1099 +4,2904 @@ <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> - <meta name="author" content="xint 1.4j" /> + <meta name="author" content="xint 1.4k" /> <title>CHANGE LOG</title> - <style type="text/css"> - code{white-space: pre-wrap;} - span.smallcaps{font-variant: small-caps;} - span.underline{text-decoration: underline;} - div.column{display: inline-block; vertical-align: top; width: 50%;} - </style> - <style type="text/css"> - body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 12pt;} - pre {white-space: pre-wrap;} - code {white-space: pre-wrap;} - #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px;} + <style> + html { + line-height: 1.5; + font-family: Georgia, serif; + font-size: 20px; + color: #1a1a1a; + background-color: #fdfdfd; + } + body { + margin: 0 auto; + max-width: 36em; + padding-left: 50px; + padding-right: 50px; + padding-top: 50px; + padding-bottom: 50px; + hyphens: auto; + overflow-wrap: break-word; + text-rendering: optimizeLegibility; + font-kerning: normal; + } + @media (max-width: 600px) { + body { + font-size: 0.9em; + padding: 1em; + } + h1 { + font-size: 1.8em; + } + } + @media print { + body { + background-color: transparent; + color: black; + font-size: 12pt; + } + p, h2, h3 { + orphans: 3; + widows: 3; + } + h2, h3, h4 { + page-break-after: avoid; + } + } + p { + margin: 1em 0; + } + a { + color: #1a1a1a; + } + a:visited { + color: #1a1a1a; + } + img { + max-width: 100%; + } + h1, h2, h3, h4, h5, h6 { + margin-top: 1.4em; + } + h5, h6 { + font-size: 1em; + font-style: italic; + } + h6 { + font-weight: normal; + } + ol, ul { + padding-left: 1.7em; + margin-top: 1em; + } + li > ol, li > ul { + margin-top: 0; + } + blockquote { + margin: 1em 0 1em 1.7em; + padding-left: 1em; + border-left: 2px solid #e6e6e6; + color: #606060; + } + code { + font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace; + font-size: 85%; + margin: 0; + } + pre { + margin: 1em 0; + overflow: auto; + } + pre code { + padding: 0; + overflow: visible; + overflow-wrap: normal; + } + .sourceCode { + background-color: transparent; + overflow: visible; + } + hr { + background-color: #1a1a1a; + border: none; + height: 1px; + margin: 1em 0; + } + table { + margin: 1em 0; + border-collapse: collapse; + width: 100%; + overflow-x: auto; + display: block; + font-variant-numeric: lining-nums tabular-nums; + } + table caption { + margin-bottom: 0.75em; + } + tbody { + margin-top: 0.5em; + border-top: 1px solid #1a1a1a; + border-bottom: 1px solid #1a1a1a; + } + th { + border-top: 1px solid #1a1a1a; + padding: 0.25em 0.5em 0.25em 0.5em; + } + td { + padding: 0.125em 0.5em 0.25em 0.5em; + } + header { + margin-bottom: 4em; + text-align: center; + } + #TOC li { + list-style: none; + } + #TOC ul { + padding-left: 1.3em; + } + #TOC > ul { + padding-left: 0; + } + #TOC a:not(:hover) { + text-decoration: none; + } + code{white-space: pre-wrap;} + span.smallcaps{font-variant: small-caps;} + span.underline{text-decoration: underline;} + div.column{display: inline-block; vertical-align: top; width: 50%;} + div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} + ul.task-list{list-style: none;} + body{margin: 0; margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 20px; font-family: serif; max-width: 100%; padding: 0; } + pre {white-space: pre-wrap;} + code {white-space: pre-wrap;} + a:link { color: blue; } + a:visited { color: green; } + a:hover { text-decoration: underline; color: hotpink } + a:active { color: brown; } + #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px; margin-left: 20px;} + .display.math{display: block; text-align: center; margin: 0.5rem auto;} </style> <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script> <![endif]--> </head> <body> -<header> +<header id="title-block-header"> <h1 class="title">CHANGE LOG</h1> -<p class="author">xint 1.4j</p> -<p class="date">2021/07/13</p> +<p class="author">xint 1.4k</p> +<p class="date">2022/05/18</p> </header> -<nav id="TOC"> +<nav id="TOC" role="doc-toc"> +<ul> +<li><a href="#k-20220518" +id="toc-k-20220518"><code>1.4k (2022/05/18)</code></a> <ul> -<li><a href="#j-20210713"><code>1.4j (2021/07/13)</code></a><ul> -<li><a href="#bug-fixes">Bug fixes</a></li> +<li><a href="#breaking-changes" id="toc-breaking-changes">Breaking +changes</a></li> +<li><a href="#bug-fixes" id="toc-bug-fixes">Bug fixes</a></li> +<li><a href="#new-features" id="toc-new-features">New features</a></li> </ul></li> -<li><a href="#i-20210611"><code>1.4i (2021/06/11)</code></a><ul> -<li><a href="#new-features">New features</a></li> -<li><a href="#bug-fixes-1">Bug fixes</a></li> +<li><a href="#j-20210713" +id="toc-j-20210713"><code>1.4j (2021/07/13)</code></a> +<ul> +<li><a href="#bug-fixes-1" id="toc-bug-fixes-1">Bug fixes</a></li> </ul></li> -<li><a href="#h-20210527"><code>1.4h (2021/05/27)</code></a><ul> -<li><a href="#bug-fixes-2">Bug fixes</a></li> +<li><a href="#i-20210611" +id="toc-i-20210611"><code>1.4i (2021/06/11)</code></a> +<ul> +<li><a href="#new-features-1" id="toc-new-features-1">New +features</a></li> +<li><a href="#bug-fixes-2" id="toc-bug-fixes-2">Bug fixes</a></li> </ul></li> -<li><a href="#g-20210525"><code>1.4g (2021/05/25)</code></a><ul> -<li><a href="#breaking-changes">Breaking changes</a></li> -<li><a href="#deprecated">Deprecated</a></li> -<li><a href="#new-features-1">New features</a></li> -<li><a href="#bug-fixes-3">Bug fixes</a></li> +<li><a href="#h-20210527" +id="toc-h-20210527"><code>1.4h (2021/05/27)</code></a> +<ul> +<li><a href="#bug-fixes-3" id="toc-bug-fixes-3">Bug fixes</a></li> </ul></li> -<li><a href="#f-20210510"><code>1.4f (2021/05/10)</code></a><ul> -<li><a href="#breaking-changes-1">Breaking changes</a></li> -<li><a href="#bug-fixes-4">Bug fixes</a></li> +<li><a href="#g-20210525" +id="toc-g-20210525"><code>1.4g (2021/05/25)</code></a> +<ul> +<li><a href="#breaking-changes-1" id="toc-breaking-changes-1">Breaking +changes</a></li> +<li><a href="#deprecated" id="toc-deprecated">Deprecated</a></li> +<li><a href="#new-features-2" id="toc-new-features-2">New +features</a></li> +<li><a href="#bug-fixes-4" id="toc-bug-fixes-4">Bug fixes</a></li> </ul></li> -<li><a href="#e-20210505"><code>1.4e (2021/05/05)</code></a><ul> -<li><a href="#breaking-changes-2">Breaking changes</a></li> -<li><a href="#new-features-2">New features</a></li> -<li><a href="#bug-fixes-5">Bug fixes</a></li> +<li><a href="#f-20210510" +id="toc-f-20210510"><code>1.4f (2021/05/10)</code></a> +<ul> +<li><a href="#breaking-changes-2" id="toc-breaking-changes-2">Breaking +changes</a></li> +<li><a href="#bug-fixes-5" id="toc-bug-fixes-5">Bug fixes</a></li> </ul></li> -<li><a href="#d-20210329"><code>1.4d (2021/03/29)</code></a><ul> -<li><a href="#breaking-changes-3">Breaking changes</a></li> -<li><a href="#bug-fixes-6">Bug fixes</a></li> +<li><a href="#e-20210505" +id="toc-e-20210505"><code>1.4e (2021/05/05)</code></a> +<ul> +<li><a href="#breaking-changes-3" id="toc-breaking-changes-3">Breaking +changes</a></li> +<li><a href="#new-features-3" id="toc-new-features-3">New +features</a></li> +<li><a href="#bug-fixes-6" id="toc-bug-fixes-6">Bug fixes</a></li> </ul></li> -<li><a href="#c-20210220"><code>1.4c (2021/02/20)</code></a><ul> -<li><a href="#bug-fixes-7">Bug fixes</a></li> +<li><a href="#d-20210329" +id="toc-d-20210329"><code>1.4d (2021/03/29)</code></a> +<ul> +<li><a href="#breaking-changes-4" id="toc-breaking-changes-4">Breaking +changes</a></li> +<li><a href="#bug-fixes-7" id="toc-bug-fixes-7">Bug fixes</a></li> </ul></li> -<li><a href="#b-20200225"><code>1.4b (2020/02/25)</code></a><ul> -<li><a href="#future">Future</a></li> -<li><a href="#new-features-3">New features</a></li> -<li><a href="#bug-fixes-8">Bug fixes</a></li> +<li><a href="#c-20210220" +id="toc-c-20210220"><code>1.4c (2021/02/20)</code></a> +<ul> +<li><a href="#bug-fixes-8" id="toc-bug-fixes-8">Bug fixes</a></li> </ul></li> -<li><a href="#a-20200219"><code>1.4a (2020/02/19)</code></a><ul> -<li><a href="#breaking-changes-4">Breaking changes</a></li> -<li><a href="#new-features-4">New features</a></li> -<li><a href="#bug-fixes-9">Bug fixes</a></li> +<li><a href="#b-20200225" +id="toc-b-20200225"><code>1.4b (2020/02/25)</code></a> +<ul> +<li><a href="#future" id="toc-future">Future</a></li> +<li><a href="#new-features-4" id="toc-new-features-4">New +features</a></li> +<li><a href="#bug-fixes-9" id="toc-bug-fixes-9">Bug fixes</a></li> </ul></li> -<li><a href="#section"><code>1.4 (2020/01/31)</code></a><ul> -<li><a href="#breaking-changes-5">Breaking changes</a></li> -<li><a href="#improvements-and-new-features">Improvements and new features</a></li> -<li><a href="#bug-fixes-10">Bug fixes</a></li> -<li><a href="#todo">TODO</a></li> +<li><a href="#a-20200219" +id="toc-a-20200219"><code>1.4a (2020/02/19)</code></a> +<ul> +<li><a href="#breaking-changes-5" id="toc-breaking-changes-5">Breaking +changes</a></li> +<li><a href="#new-features-5" id="toc-new-features-5">New +features</a></li> +<li><a href="#bug-fixes-10" id="toc-bug-fixes-10">Bug fixes</a></li> </ul></li> -<li><a href="#f-20190910"><code>1.3f (2019/09/10)</code></a><ul> -<li><a href="#improvements-and-new-features-1">Improvements and new features</a></li> -<li><a href="#bug-fixes-11">Bug fixes</a></li> +<li><a href="#section" +id="toc-section"><code>1.4 (2020/01/31)</code></a> +<ul> +<li><a href="#breaking-changes-6" id="toc-breaking-changes-6">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features" +id="toc-improvements-and-new-features">Improvements and new +features</a></li> +<li><a href="#bug-fixes-11" id="toc-bug-fixes-11">Bug fixes</a></li> +<li><a href="#todo" id="toc-todo">TODO</a></li> </ul></li> -<li><a href="#e-20190405"><code>1.3e (2019/04/05)</code></a><ul> -<li><a href="#breaking-changes-6">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-2">Improvements and new features</a></li> -<li><a href="#bug-fixes-12">Bug fixes</a></li> +<li><a href="#f-20190910" +id="toc-f-20190910"><code>1.3f (2019/09/10)</code></a> +<ul> +<li><a href="#improvements-and-new-features-1" +id="toc-improvements-and-new-features-1">Improvements and new +features</a></li> +<li><a href="#bug-fixes-12" id="toc-bug-fixes-12">Bug fixes</a></li> </ul></li> -<li><a href="#d-20190106"><code>1.3d (2019/01/06)</code></a><ul> -<li><a href="#breaking-changes-7">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-3">Improvements and new features</a></li> -<li><a href="#bug-fixes-13">Bug fixes</a></li> +<li><a href="#e-20190405" +id="toc-e-20190405"><code>1.3e (2019/04/05)</code></a> +<ul> +<li><a href="#breaking-changes-7" id="toc-breaking-changes-7">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-2" +id="toc-improvements-and-new-features-2">Improvements and new +features</a></li> +<li><a href="#bug-fixes-13" id="toc-bug-fixes-13">Bug fixes</a></li> </ul></li> -<li><a href="#c-20180617"><code>1.3c (2018/06/17)</code></a><ul> -<li><a href="#improvements-and-new-features-4">Improvements and new features</a></li> -<li><a href="#bug-fixes-14">Bug fixes</a></li> +<li><a href="#d-20190106" +id="toc-d-20190106"><code>1.3d (2019/01/06)</code></a> +<ul> +<li><a href="#breaking-changes-8" id="toc-breaking-changes-8">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-3" +id="toc-improvements-and-new-features-3">Improvements and new +features</a></li> +<li><a href="#bug-fixes-14" id="toc-bug-fixes-14">Bug fixes</a></li> </ul></li> -<li><a href="#b-20180518"><code>1.3b (2018/05/18)</code></a><ul> -<li><a href="#improvements-and-new-features-5">Improvements and new features</a></li> +<li><a href="#c-20180617" +id="toc-c-20180617"><code>1.3c (2018/06/17)</code></a> +<ul> +<li><a href="#improvements-and-new-features-4" +id="toc-improvements-and-new-features-4">Improvements and new +features</a></li> +<li><a href="#bug-fixes-15" id="toc-bug-fixes-15">Bug fixes</a></li> </ul></li> -<li><a href="#a-20180307"><code>1.3a (2018/03/07)</code></a><ul> -<li><a href="#removed">Removed</a></li> -<li><a href="#improvements-and-new-features-6">Improvements and new features</a></li> -<li><a href="#bug-fixes-15">Bug fixes</a></li> +<li><a href="#b-20180518" +id="toc-b-20180518"><code>1.3b (2018/05/18)</code></a> +<ul> +<li><a href="#improvements-and-new-features-5" +id="toc-improvements-and-new-features-5">Improvements and new +features</a></li> </ul></li> -<li><a href="#section-1"><code>1.3 (2018/03/01)</code></a><ul> -<li><a href="#breaking-changes-8">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-7">Improvements and new features</a></li> +<li><a href="#a-20180307" +id="toc-a-20180307"><code>1.3a (2018/03/07)</code></a> +<ul> +<li><a href="#removed" id="toc-removed">Removed</a></li> +<li><a href="#improvements-and-new-features-6" +id="toc-improvements-and-new-features-6">Improvements and new +features</a></li> +<li><a href="#bug-fixes-16" id="toc-bug-fixes-16">Bug fixes</a></li> </ul></li> -<li><a href="#q-20180206"><code>1.2q (2018/02/06)</code></a><ul> -<li><a href="#improvements-and-new-features-8">Improvements and new features</a></li> -<li><a href="#bug-fixes-16">Bug fixes</a></li> +<li><a href="#section-1" +id="toc-section-1"><code>1.3 (2018/03/01)</code></a> +<ul> +<li><a href="#breaking-changes-9" id="toc-breaking-changes-9">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-7" +id="toc-improvements-and-new-features-7">Improvements and new +features</a></li> </ul></li> -<li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul> -<li><a href="#breaking-changes-9">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-9">Improvements and new features</a></li> -<li><a href="#bug-fixes-17">Bug fixes</a></li> +<li><a href="#q-20180206" +id="toc-q-20180206"><code>1.2q (2018/02/06)</code></a> +<ul> +<li><a href="#improvements-and-new-features-8" +id="toc-improvements-and-new-features-8">Improvements and new +features</a></li> +<li><a href="#bug-fixes-17" id="toc-bug-fixes-17">Bug fixes</a></li> </ul></li> -<li><a href="#o-20170829"><code>1.2o (2017/08/29)</code></a><ul> -<li><a href="#breaking-changes-10">Breaking changes</a></li> -<li><a href="#deprecated-1">Deprecated</a></li> +<li><a href="#p-20171205" +id="toc-p-20171205"><code>1.2p (2017/12/05)</code></a> +<ul> +<li><a href="#breaking-changes-10" id="toc-breaking-changes-10">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-9" +id="toc-improvements-and-new-features-9">Improvements and new +features</a></li> +<li><a href="#bug-fixes-18" id="toc-bug-fixes-18">Bug fixes</a></li> </ul></li> -<li><a href="#n-20170806"><code>1.2n (2017/08/06)</code></a><ul> -<li><a href="#breaking-changes-11">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-10">Improvements and new features</a></li> +<li><a href="#o-20170829" +id="toc-o-20170829"><code>1.2o (2017/08/29)</code></a> +<ul> +<li><a href="#breaking-changes-11" id="toc-breaking-changes-11">Breaking +changes</a></li> +<li><a href="#deprecated-1" id="toc-deprecated-1">Deprecated</a></li> </ul></li> -<li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul> -<li><a href="#breaking-changes-12">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-11">Improvements and new features</a></li> -<li><a href="#bug-fixes-18">Bug fixes</a></li> +<li><a href="#n-20170806" +id="toc-n-20170806"><code>1.2n (2017/08/06)</code></a> +<ul> +<li><a href="#breaking-changes-12" id="toc-breaking-changes-12">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-10" +id="toc-improvements-and-new-features-10">Improvements and new +features</a></li> </ul></li> -<li><a href="#l-20170726"><code>1.2l (2017/07/26)</code></a><ul> -<li><a href="#removed-1">Removed</a></li> -<li><a href="#improvements-and-new-features-12">Improvements and new features</a></li> -<li><a href="#bug-fixes-19">Bug fixes</a></li> +<li><a href="#m-20170731" +id="toc-m-20170731"><code>1.2m (2017/07/31)</code></a> +<ul> +<li><a href="#breaking-changes-13" id="toc-breaking-changes-13">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-11" +id="toc-improvements-and-new-features-11">Improvements and new +features</a></li> +<li><a href="#bug-fixes-19" id="toc-bug-fixes-19">Bug fixes</a></li> </ul></li> -<li><a href="#k-20170106"><code>1.2k (2017/01/06)</code></a><ul> -<li><a href="#breaking-changes-13">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-13">Improvements and new features</a></li> -<li><a href="#bug-fixes-20">Bug fixes</a></li> +<li><a href="#l-20170726" +id="toc-l-20170726"><code>1.2l (2017/07/26)</code></a> +<ul> +<li><a href="#removed-1" id="toc-removed-1">Removed</a></li> +<li><a href="#improvements-and-new-features-12" +id="toc-improvements-and-new-features-12">Improvements and new +features</a></li> +<li><a href="#bug-fixes-20" id="toc-bug-fixes-20">Bug fixes</a></li> </ul></li> -<li><a href="#j-20161222"><code>1.2j (2016/12/22)</code></a><ul> -<li><a href="#improvements-and-new-features-14">Improvements and new features</a></li> -<li><a href="#bug-fixes-21">Bug fixes</a></li> +<li><a href="#k-20170106" +id="toc-k-20170106"><code>1.2k (2017/01/06)</code></a> +<ul> +<li><a href="#breaking-changes-14" id="toc-breaking-changes-14">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-13" +id="toc-improvements-and-new-features-13">Improvements and new +features</a></li> +<li><a href="#bug-fixes-21" id="toc-bug-fixes-21">Bug fixes</a></li> +</ul></li> +<li><a href="#j-20161222" +id="toc-j-20161222"><code>1.2j (2016/12/22)</code></a> +<ul> +<li><a href="#improvements-and-new-features-14" +id="toc-improvements-and-new-features-14">Improvements and new +features</a></li> +<li><a href="#bug-fixes-22" id="toc-bug-fixes-22">Bug fixes</a></li> </ul></li> -<li><a href="#i-20161213"><code>1.2i (2016/12/13)</code></a><ul> -<li><a href="#breaking-changes-14">Breaking changes</a></li> -<li><a href="#removed-2">Removed</a></li> -<li><a href="#improvements-and-new-features-15">Improvements and new features</a></li> -<li><a href="#bug-fixes-22">Bug fixes</a></li> +<li><a href="#i-20161213" +id="toc-i-20161213"><code>1.2i (2016/12/13)</code></a> +<ul> +<li><a href="#breaking-changes-15" id="toc-breaking-changes-15">Breaking +changes</a></li> +<li><a href="#removed-2" id="toc-removed-2">Removed</a></li> +<li><a href="#improvements-and-new-features-15" +id="toc-improvements-and-new-features-15">Improvements and new +features</a></li> +<li><a href="#bug-fixes-23" id="toc-bug-fixes-23">Bug fixes</a></li> </ul></li> -<li><a href="#h-20161120"><code>1.2h (2016/11/20)</code></a><ul> -<li><a href="#improvements-and-new-features-16">Improvements and new features</a></li> -<li><a href="#bug-fixes-23">Bug fixes</a></li> +<li><a href="#h-20161120" +id="toc-h-20161120"><code>1.2h (2016/11/20)</code></a> +<ul> +<li><a href="#improvements-and-new-features-16" +id="toc-improvements-and-new-features-16">Improvements and new +features</a></li> +<li><a href="#bug-fixes-24" id="toc-bug-fixes-24">Bug fixes</a></li> </ul></li> -<li><a href="#g-20160319"><code>1.2g (2016/03/19)</code></a><ul> -<li><a href="#breaking-changes-15">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-17">Improvements and new features</a></li> +<li><a href="#g-20160319" +id="toc-g-20160319"><code>1.2g (2016/03/19)</code></a> +<ul> +<li><a href="#breaking-changes-16" id="toc-breaking-changes-16">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-17" +id="toc-improvements-and-new-features-17">Improvements and new +features</a></li> </ul></li> -<li><a href="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul> -<li><a href="#breaking-changes-16">Breaking changes</a></li> -<li><a href="#improvements-and-new-features-18">Improvements and new features</a></li> -<li><a href="#bug-fixes-24">Bug fixes</a></li> +<li><a href="#f-20160312" +id="toc-f-20160312"><code>1.2f (2016/03/12)</code></a> +<ul> +<li><a href="#breaking-changes-17" id="toc-breaking-changes-17">Breaking +changes</a></li> +<li><a href="#improvements-and-new-features-18" +id="toc-improvements-and-new-features-18">Improvements and new +features</a></li> +<li><a href="#bug-fixes-25" id="toc-bug-fixes-25">Bug fixes</a></li> </ul></li> -<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul> -<li><a href="#improvements-and-new-features-19">Improvements and new features</a></li> -<li><a href="#bug-fixes-25">Bug fixes</a></li> +<li><a href="#e-20151122" +id="toc-e-20151122"><code>1.2e (2015/11/22)</code></a> +<ul> +<li><a href="#improvements-and-new-features-19" +id="toc-improvements-and-new-features-19">Improvements and new +features</a></li> +<li><a href="#bug-fixes-26" id="toc-bug-fixes-26">Bug fixes</a></li> </ul></li> -<li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul> -<li><a href="#improvements-and-new-features-20">Improvements and new features</a></li> -<li><a href="#bug-fixes-26">Bug fixes</a></li> +<li><a href="#d-20151118" +id="toc-d-20151118"><code>1.2d (2015/11/18)</code></a> +<ul> +<li><a href="#improvements-and-new-features-20" +id="toc-improvements-and-new-features-20">Improvements and new +features</a></li> +<li><a href="#bug-fixes-27" id="toc-bug-fixes-27">Bug fixes</a></li> </ul></li> -<li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul> -<li><a href="#improvements-and-new-features-21">Improvements and new features</a></li> -<li><a href="#bug-fixes-27">Bug fixes</a></li> +<li><a href="#c-20151116" +id="toc-c-20151116"><code>1.2c (2015/11/16)</code></a> +<ul> +<li><a href="#improvements-and-new-features-21" +id="toc-improvements-and-new-features-21">Improvements and new +features</a></li> +<li><a href="#bug-fixes-28" id="toc-bug-fixes-28">Bug fixes</a></li> </ul></li> -<li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul> -<li><a href="#bug-fixes-28">Bug fixes</a></li> +<li><a href="#b-20151029" +id="toc-b-20151029"><code>1.2b (2015/10/29)</code></a> +<ul> +<li><a href="#bug-fixes-29" id="toc-bug-fixes-29">Bug fixes</a></li> </ul></li> -<li><a href="#a-20151019"><code>1.2a (2015/10/19)</code></a><ul> -<li><a href="#improvements-and-new-features-22">Improvements and new features</a></li> -<li><a href="#bug-fixes-29">Bug fixes</a></li> +<li><a href="#a-20151019" +id="toc-a-20151019"><code>1.2a (2015/10/19)</code></a> +<ul> +<li><a href="#improvements-and-new-features-22" +id="toc-improvements-and-new-features-22">Improvements and new +features</a></li> +<li><a href="#bug-fixes-30" id="toc-bug-fixes-30">Bug fixes</a></li> </ul></li> -<li><a href="#section-2"><code>1.2 (2015/10/10)</code></a><ul> -<li><a href="#removed-3">Removed</a></li> -<li><a href="#improvements-and-new-features-23">Improvements and new features</a></li> +<li><a href="#section-2" +id="toc-section-2"><code>1.2 (2015/10/10)</code></a> +<ul> +<li><a href="#removed-3" id="toc-removed-3">Removed</a></li> +<li><a href="#improvements-and-new-features-23" +id="toc-improvements-and-new-features-23">Improvements and new +features</a></li> </ul></li> -<li><a href="#c-20150912"><code>1.1c (2015/09/12)</code></a></li> -<li><a href="#b-20150831"><code>1.1b (2015/08/31)</code></a></li> -<li><a href="#a-20141107"><code>1.1a (2014/11/07)</code></a></li> -<li><a href="#section-3"><code>1.1 (2014/10/28)</code></a><ul> -<li><a href="#breaking-changes-17">Breaking changes</a></li> -<li><a href="#removed-4">Removed</a></li> -<li><a href="#deprecated-2">Deprecated</a></li> -<li><a href="#improvements-and-new-features-24">Improvements and new features</a></li> -<li><a href="#bug-fixes-30">Bug fixes</a></li> +<li><a href="#c-20150912" +id="toc-c-20150912"><code>1.1c (2015/09/12)</code></a></li> +<li><a href="#b-20150831" +id="toc-b-20150831"><code>1.1b (2015/08/31)</code></a></li> +<li><a href="#a-20141107" +id="toc-a-20141107"><code>1.1a (2014/11/07)</code></a></li> +<li><a href="#section-3" +id="toc-section-3"><code>1.1 (2014/10/28)</code></a> +<ul> +<li><a href="#breaking-changes-18" id="toc-breaking-changes-18">Breaking +changes</a></li> +<li><a href="#removed-4" id="toc-removed-4">Removed</a></li> +<li><a href="#deprecated-2" id="toc-deprecated-2">Deprecated</a></li> +<li><a href="#improvements-and-new-features-24" +id="toc-improvements-and-new-features-24">Improvements and new +features</a></li> +<li><a href="#bug-fixes-31" id="toc-bug-fixes-31">Bug fixes</a></li> </ul></li> -<li><a href="#n-20140401"><code>1.09n (2014/04/01)</code></a></li> -<li><a href="#m-20140226"><code>1.09m (2014/02/26)</code></a></li> -<li><a href="#kb-20140213"><code>1.09kb (2014/02/13)</code></a></li> -<li><a href="#k-20140121"><code>1.09k (2014/01/21)</code></a></li> -<li><a href="#j-20140109"><code>1.09j (2014/01/09)</code></a></li> -<li><a href="#i-20131218"><code>1.09i (2013/12/18)</code></a></li> -<li><a href="#h-20131128"><code>1.09h (2013/11/28)</code></a></li> -<li><a href="#g-20131122"><code>1.09g (2013/11/22)</code></a></li> -<li><a href="#f-20131104"><code>1.09f (2013/11/04)</code></a></li> -<li><a href="#e-20131029"><code>1.09e (2013/10/29)</code></a></li> -<li><a href="#d-20131022"><code>1.09d (2013/10/22)</code></a></li> -<li><a href="#c-20131009"><code>1.09c (2013/10/09)</code></a></li> -<li><a href="#b-20131003"><code>1.09b (2013/10/03)</code></a></li> -<li><a href="#a-20130924"><code>1.09a (2013/09/24)</code></a></li> -<li><a href="#b-20130614"><code>1.08b (2013/06/14)</code></a></li> -<li><a href="#a-20130611"><code>1.08a (2013/06/11)</code></a></li> -<li><a href="#section-4"><code>1.08 (2013/06/07)</code></a></li> -<li><a href="#section-5"><code>1.07 (2013/05/25)</code></a></li> -<li><a href="#b-20130514"><code>1.06b (2013/05/14)</code></a></li> -<li><a href="#section-6"><code>1.06 (2013/05/07)</code></a></li> -<li><a href="#section-7"><code>1.05 (2013/05/01)</code></a></li> -<li><a href="#section-8"><code>1.04 (2013/04/25)</code></a></li> -<li><a href="#section-9"><code>1.03 (2013/04/14)</code></a></li> -<li><a href="#section-10"><code>1.0 (2013/03/28)</code></a></li> +<li><a href="#n-20140401" +id="toc-n-20140401"><code>1.09n (2014/04/01)</code></a></li> +<li><a href="#m-20140226" +id="toc-m-20140226"><code>1.09m (2014/02/26)</code></a></li> +<li><a href="#kb-20140213" +id="toc-kb-20140213"><code>1.09kb (2014/02/13)</code></a></li> +<li><a href="#k-20140121" +id="toc-k-20140121"><code>1.09k (2014/01/21)</code></a></li> +<li><a href="#j-20140109" +id="toc-j-20140109"><code>1.09j (2014/01/09)</code></a></li> +<li><a href="#i-20131218" +id="toc-i-20131218"><code>1.09i (2013/12/18)</code></a></li> +<li><a href="#h-20131128" +id="toc-h-20131128"><code>1.09h (2013/11/28)</code></a></li> +<li><a href="#g-20131122" +id="toc-g-20131122"><code>1.09g (2013/11/22)</code></a></li> +<li><a href="#f-20131104" +id="toc-f-20131104"><code>1.09f (2013/11/04)</code></a></li> +<li><a href="#e-20131029" +id="toc-e-20131029"><code>1.09e (2013/10/29)</code></a></li> +<li><a href="#d-20131022" +id="toc-d-20131022"><code>1.09d (2013/10/22)</code></a></li> +<li><a href="#c-20131009" +id="toc-c-20131009"><code>1.09c (2013/10/09)</code></a></li> +<li><a href="#b-20131003" +id="toc-b-20131003"><code>1.09b (2013/10/03)</code></a></li> +<li><a href="#a-20130924" +id="toc-a-20130924"><code>1.09a (2013/09/24)</code></a></li> +<li><a href="#b-20130614" +id="toc-b-20130614"><code>1.08b (2013/06/14)</code></a></li> +<li><a href="#a-20130611" +id="toc-a-20130611"><code>1.08a (2013/06/11)</code></a></li> +<li><a href="#section-4" +id="toc-section-4"><code>1.08 (2013/06/07)</code></a></li> +<li><a href="#section-5" +id="toc-section-5"><code>1.07 (2013/05/25)</code></a></li> +<li><a href="#b-20130514" +id="toc-b-20130514"><code>1.06b (2013/05/14)</code></a></li> +<li><a href="#section-6" +id="toc-section-6"><code>1.06 (2013/05/07)</code></a></li> +<li><a href="#section-7" +id="toc-section-7"><code>1.05 (2013/05/01)</code></a></li> +<li><a href="#section-8" +id="toc-section-8"><code>1.04 (2013/04/25)</code></a></li> +<li><a href="#section-9" +id="toc-section-9"><code>1.03 (2013/04/14)</code></a></li> +<li><a href="#section-10" +id="toc-section-10"><code>1.0 (2013/03/28)</code></a></li> </ul> </nav> -<pre><code>Source: xint.dtx 1.4j 2021/07/13 (doc 2021/07/13) +<pre><code>Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> -<h2 id="j-20210713"><code>1.4j (2021/07/13)</code></h2> +<h2 id="k-20220518"><code>1.4k (2022/05/18)</code></h2> +<h3 id="breaking-changes">Breaking changes</h3> +<ul> +<li><p><strong>xintfrac</strong>: the longstanding (but documented as +undecided and unstable) way of <code>\xintFloat</code> to output the +zero value was <code>0.e0</code> and it has now been modified into +<code>0.0e0</code>. Customizable via +<code>\xintFloatZero</code>.</p></li> +<li><p><strong>xintfrac</strong>/<strong>xintexpr</strong>: the +behaviour of <code>\xintPFloat</code> (hence of +<code>\xintfloateval</code>) has again changed: when the output is an +integer (not using scientific notation) it does not get postfixed by +<code>.0</code>. This applies in particular for the zero value, now +printed <code>0</code>. Similarly, in the case of scientific notation +with a single-digit (trimmed) mantissa, no <code>.0</code> is used.</p> +<p>Customizable via <code>\xintPFloatIntSuffix</code>, +<code>\xintPFloatLengthOneSuffix</code>, and +<code>\xintPFloatZero</code>.</p> +<p>Also, <code>\xintPFloat</code> trims trailing zeros from the full +significand only if there are at least <code>4</code> of them, see +<code>\xintPFloatMinTrimmed</code>.</p></li> +<li><p><strong>xintfrac</strong>/<strong>xintexpr</strong>: definition +of <code>\xintFracToSci</code> migrated from the former to the +latter.</p></li> +<li><p><strong>xintexpr</strong>: +<code>\xintexpr{Safe,Restore}Catcodes</code> pairs now behave like a +“last in first out” stack. Check the <code>pdf</code> documentation for +details.</p></li> +</ul> <h3 id="bug-fixes">Bug fixes</h3> <ul> -<li><strong>xinttools</strong>: a brace removal bug affected the venerable <code>\xintSeq</code> if producing a single number (e.g. <code>\xintSeq{10}{10}</code> expanded to <code>10</code> not <code>{10}</code>). Thanks to Christophe Poulain for report.</li> +<li><p><strong>xintexpr</strong>: the +<code>\xintexpr{Safe,Restore}Catcodes</code> were documented at user +level, but also used by the package <code>\xintdefvar</code> or +<code>\xintdeffunc</code>. This could result in some bad interaction due +to the somewhat strange (but documented) behaviour of nested +<code>\xintexpr{Safe,Restore}Catcodes</code> (which has now been +modified).</p></li> +<li><p><strong>xintexpr</strong>: ever since <code>1.4</code>, +<code>\xintdefufunc</code> (but not <code>\xintdeffunc</code>) forgot to +reset the catcodes to their status prior to the sanitization done by the +macro at the start of its execution.</p></li> </ul> -<h2 id="i-20210611"><code>1.4i (2021/06/11)</code></h2> <h3 id="new-features">New features</h3> <ul> -<li><p><strong>xintexpr</strong>: the concept of simultaneous assignments is extended: in case of more variables than values the extraneous variables do not cause an error message but are simply set to the <code>nil</code> value; in case of more values than variables, the last variable is defined to be the ople concatenating all the extra values.</p></li> -<li><p><strong>xintexpr</strong>: built-in functions usable with arbitrarily many arguments such as <code>max()</code>, <code>gcd()</code>, or <code>len()</code> are now again usable with a single numeric argument: since <code>1.4</code> a lone argument had to be a <code>nutple</code> (which was automatically unpacked). It can now again be a number.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintPFloatZero</code>, +<code>\xintPFloatIntSuffix</code>, +<code>\xintPFloatLengthOneSuffix</code>, +<code>\xintPFloatNoSciEmax</code>, <code>\xintPFloatNoSciEmin</code> and +<code>\xintPFloatMinTrimmed</code> customize the output of +<code>\xintPFloat</code>, hence also of <code>\xintfloateval</code> (and +of <code>\xinteval</code> when scientific notation was used in the +expression). Also added <code>\xintFloatZero</code>.</p></li> +<li><p><strong>xintfrac</strong>: +<code>\xintFloatToDecimal</code>.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintFracToDecimal</code>, an +alternative to <code>\xintFracToSci</code> for the configuration of +<code>\xintexprPrintOne</code>.</p></li> +<li><p><strong>xintexpr</strong>: long awaited syntax +<code>\xintieval[D]{...}</code> and <code>\xintfloateval[Q]{...}</code> +now implemented. The legacy syntax with <code>\xintieval{[D]...}</code> +and <code>\xintfloateval{[Q]...}</code> is kept for backwards +compatibility.</p></li> </ul> +<h2 id="j-20210713"><code>1.4j (2021/07/13)</code></h2> <h3 id="bug-fixes-1">Bug fixes</h3> <ul> -<li><p><strong>xintexpr</strong>: simultaneous assignments via <code>\xintdefvar</code> to 10 or more variables was broken if the right hand side was an ople (of length at least 10, as it had prior to this release to match the number of variables).</p></li> -<li><p><strong>xintexpr</strong>: the mechanism which allows to define variables with names already in use for pre-existing functions was broken for some built-in functions: those handling syntax with dummy variables (currently <code>subs()</code>, <code>subsm()</code>, <code>subsn()</code>, <code>seq()</code>, <code>add()</code>, <code>mul()</code>, <code>ndseq()</code>, <code>ndmap()</code>, <code>ndfillraw()</code>) and the so-called “pseudo” functions (currently <code>bool()</code>, <code>togl()</code>, <code>protect()</code>, <code>qint()</code>, <code>qfrac()</code>, <code>qfloat()</code>, <code>qraw()</code>, <code>random()</code>, <code>qrand()</code>, <code>rbit()</code>). For example the function <code>seq()</code> was broken if the user had defined a variable <code>seq</code>.</p></li> +<li><strong>xinttools</strong>: a brace removal bug affected the +venerable <code>\xintSeq</code> if producing a single number +(e.g. <code>\xintSeq{10}{10}</code> expanded to <code>10</code> not +<code>{10}</code>). Thanks to Christophe Poulain for report.</li> +</ul> +<h2 id="i-20210611"><code>1.4i (2021/06/11)</code></h2> +<h3 id="new-features-1">New features</h3> +<ul> +<li><p><strong>xintexpr</strong>: the concept of simultaneous +assignments is extended: in case of more variables than values the +extraneous variables do not cause an error message but are simply set to +the <code>nil</code> value; in case of more values than variables, the +last variable is defined to be the ople concatenating all the extra +values.</p></li> +<li><p><strong>xintexpr</strong>: built-in functions usable with +arbitrarily many arguments such as <code>max()</code>, +<code>gcd()</code>, or <code>len()</code> are now again usable with a +single numeric argument: since <code>1.4</code> a lone argument had to +be a <code>nutple</code> (which was automatically unpacked). It can now +again be a number.</p></li> </ul> -<h2 id="h-20210527"><code>1.4h (2021/05/27)</code></h2> <h3 id="bug-fixes-2">Bug fixes</h3> <ul> -<li><p><strong>xintexpr</strong>: the recent <code>1.4g</code> introduced a bug breaking input of the type <code><operator><space token><macro></code>.</p></li> -<li><p><strong>xintexpr</strong>: since <code>1.4</code> (<code>2020/01/31</code>) the <code>omit</code> and <code>abort</code> keywords were broken if used inside a substitution, itself nested in a <code>seq()</code> or similar construct.</p></li> -<li><p><strong>xintexpr</strong>: since <code>1.4c</code> the <code>\xintthespaceseparated</code> (added at <code>1.4a</code>) inserted two, not one, spaces at one specific location near the end of its output. A bit cosmetic problem, fixed nevertheless.</p></li> +<li><p><strong>xintexpr</strong>: simultaneous assignments via +<code>\xintdefvar</code> to 10 or more variables was broken if the right +hand side was an ople (of length at least 10, as it had prior to this +release to match the number of variables).</p></li> +<li><p><strong>xintexpr</strong>: the mechanism which allows to define +variables with names already in use for pre-existing functions was +broken for some built-in functions: those handling syntax with dummy +variables (currently <code>subs()</code>, <code>subsm()</code>, +<code>subsn()</code>, <code>seq()</code>, <code>add()</code>, +<code>mul()</code>, <code>ndseq()</code>, <code>ndmap()</code>, +<code>ndfillraw()</code>) and the so-called “pseudo” functions +(currently <code>bool()</code>, <code>togl()</code>, +<code>protect()</code>, <code>qint()</code>, <code>qfrac()</code>, +<code>qfloat()</code>, <code>qraw()</code>, <code>random()</code>, +<code>qrand()</code>, <code>rbit()</code>). For example the function +<code>seq()</code> was broken if the user had defined a variable +<code>seq</code>.</p></li> +</ul> +<h2 id="h-20210527"><code>1.4h (2021/05/27)</code></h2> +<h3 id="bug-fixes-3">Bug fixes</h3> +<ul> +<li><p><strong>xintexpr</strong>: the recent <code>1.4g</code> +introduced a bug breaking input of the type +<code><operator><space token><macro></code>.</p></li> +<li><p><strong>xintexpr</strong>: since <code>1.4</code> +(<code>2020/01/31</code>) the <code>omit</code> and <code>abort</code> +keywords were broken if used inside a substitution, itself nested in a +<code>seq()</code> or similar construct.</p></li> +<li><p><strong>xintexpr</strong>: since <code>1.4c</code> the +<code>\xintthespaceseparated</code> (added at <code>1.4a</code>) +inserted two, not one, spaces at one specific location near the end of +its output. A bit cosmetic problem, fixed nevertheless.</p></li> </ul> <h2 id="g-20210525"><code>1.4g (2021/05/25)</code></h2> -<h3 id="breaking-changes">Breaking changes</h3> +<h3 id="breaking-changes-1">Breaking changes</h3> <ul> -<li><p><strong>xintexpr</strong>: the parsing of power operators <code>**</code> and <code>^</code> now proceeds in a right associative way: <code>2^3^4==2^(3^4)</code>.</p></li> -<li><p><strong>xintexpr</strong>: single-character operators <code>&</code>, <code>|</code>, and <code>=</code> (deprecated since <code>1.1</code>) have been removed. Use <code>&&</code>, <code>||</code> and <code>==</code> respectively.</p></li> +<li><p><strong>xintexpr</strong>: the parsing of power operators +<code>**</code> and <code>^</code> now proceeds in a right associative +way: <code>2^3^4==2^(3^4)</code>.</p></li> +<li><p><strong>xintexpr</strong>: single-character operators +<code>&</code>, <code>|</code>, and <code>=</code> (deprecated since +<code>1.1</code>) have been removed. Use <code>&&</code>, +<code>||</code> and <code>==</code> respectively.</p></li> </ul> <h3 id="deprecated">Deprecated</h3> <ul> -<li><strong>xintfrac</strong>: old typesetting macros dating back to <code>1.03</code> and <code>1.04</code> releases <code>\xintFrac</code>, <code>\xintSignedFrac</code>, <code>\xintFwOver</code>, <code>\xintSignedFwOver</code> are deprecated. Please use the new names <code>\xintTeXFrac</code>, <code>\xintTeXsignedFrac</code>, <code>\xintTeXOver</code>, <code>\xintTeXsignedOver</code>. The old names will emit warnings.</li> +<li><strong>xintfrac</strong>: old typesetting macros dating back to +<code>1.03</code> and <code>1.04</code> releases <code>\xintFrac</code>, +<code>\xintSignedFrac</code>, <code>\xintFwOver</code>, +<code>\xintSignedFwOver</code> are deprecated. Please use the new names +<code>\xintTeXFrac</code>, <code>\xintTeXsignedFrac</code>, +<code>\xintTeXOver</code>, <code>\xintTeXsignedOver</code>. The old +names will emit warnings.</li> </ul> -<h3 id="new-features-1">New features</h3> +<h3 id="new-features-2">New features</h3> <ul> -<li><p>Messages written to the terminal and log file during the handling of recovery from exceptions use a new mechanism; when in interactive mode, the user is prompted only once, not thrice, to enter <code><return></code> for recovery and continued processing.</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintTeXfromSci</code> (added about 7 or 8 years too late) to help typesetting values output by <code>\xintfloateval</code> in a more useful way than <code>\xintTeXFrac</code> (formerly <code>\xintFrac</code>).</p></li> +<li><p>Messages written to the terminal and log file during the handling +of recovery from exceptions use a new mechanism; when in interactive +mode, the user is prompted only once, not thrice, to enter +<code><return></code> for recovery and continued +processing.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintTeXfromSci</code> (added +about 7 or 8 years too late) to help typesetting values output by +<code>\xintfloateval</code> in a more useful way than +<code>\xintTeXFrac</code> (formerly <code>\xintFrac</code>).</p></li> </ul> -<h3 id="bug-fixes-3">Bug fixes</h3> -<ul> -<li><p><strong>xintexpr</strong>: with <strong>xintbinhex</strong> loaded, <code>"</code> is recognized as prefix for hexadecimal input; but a bug (present ever since this support for hexadecimal input was added) caused syntax such as <code>"\macro</code> to break the parser. Also, leading zeros such as in <code>"0000A</code> where not properly trimmed since <code>1.2m</code>.</p></li> -<li><p><strong>xintexpr</strong>: authorize <code>x! == y</code> without parentheses. Formerly the parser mis-interpreted <code>!</code> as first character of the <code>!=</code> not-equal-to comparison operator, subsequently causing breakage when finding the second <code>=</code>.</p></li> -<li><strong>xintexpr</strong>: various error situations were badly handled. +<h3 id="bug-fixes-4">Bug fixes</h3> <ul> -<li><code>\xinteval{1/0}</code> did not recover gracefully due to longstanding bug in <strong>xintfrac</strong>.</li> -<li><code>\xintfloateval{1/0}</code> did not recover gracefully either… due to some other reason.</li> -<li>recovery from encountering an unknown variable name was broken since <code>1.4</code>; also, with an unknown function name if in <code>\xintfloatexpr</code>.</li> -<li><code>\xinteval{_4}</code> caused an infinite loop (with underscore <code>_</code> having its normal catcode). This was unexpected, as the <code>_</code> is documented to be ignored if in-between digits (and is ignored if last after some digits). It will be now ignored also if encountered upfront. A similar problem existed with variable names starting with a <code>_</code> (of normal catcode), which however are clearly not legal. The (normal catcode) <code>_</code> will then be ignored as well if encountered in front of a variable or function name (but not inside of course).</li> -<li><code>\xinteval{\catcode`@}</code> crashed (one had to use an added <code>\the</code> or <code>\number</code>).</li> -<li>illegal <code>\xinteval{/3}</code> was not intercepted and ultimately caused low-level errors (same with <code>^</code>).</li> -</ul> -<p>Surely, further situations remain where bad input will crash parser.</p></li> +<li><p><strong>xintexpr</strong>: with <strong>xintbinhex</strong> +loaded, <code>"</code> is recognized as prefix for hexadecimal input; +but a bug (present ever since this support for hexadecimal input was +added) caused syntax such as <code>"\macro</code> to break the parser. +Also, leading zeros such as in <code>"0000A</code> where not properly +trimmed since <code>1.2m</code>.</p></li> +<li><p><strong>xintexpr</strong>: authorize <code>x! == y</code> without +parentheses. Formerly the parser mis-interpreted <code>!</code> as first +character of the <code>!=</code> not-equal-to comparison operator, +subsequently causing breakage when finding the second +<code>=</code>.</p></li> +<li><p><strong>xintexpr</strong>: various error situations were badly +handled.</p> +<ul> +<li><code>\xinteval{1/0}</code> did not recover gracefully due to +longstanding bug in <strong>xintfrac</strong>.</li> +<li><code>\xintfloateval{1/0}</code> did not recover gracefully either… +due to some other reason.</li> +<li>recovery from encountering an unknown variable name was broken since +<code>1.4</code>; also, with an unknown function name if in +<code>\xintfloatexpr</code>.</li> +<li><code>\xinteval{_4}</code> caused an infinite loop (with underscore +<code>_</code> having its normal catcode). This was unexpected, as the +<code>_</code> is documented to be ignored if in-between digits (and is +ignored if last after some digits). It will be now ignored also if +encountered upfront. A similar problem existed with variable names +starting with a <code>_</code> (of normal catcode), which however are +clearly not legal. The (normal catcode) <code>_</code> will then be +ignored as well if encountered in front of a variable or function name +(but not inside of course).</li> +<li><code>\xinteval{\catcode`@}</code> crashed (one had to use an added +<code>\the</code> or <code>\number</code>).</li> +<li>illegal <code>\xinteval{/3}</code> was not intercepted and +ultimately caused low-level errors (same with <code>^</code>).</li> +</ul> +<p>Surely, further situations remain where bad input will crash +parser.</p></li> </ul> <h2 id="f-20210510"><code>1.4f (2021/05/10)</code></h2> -<h3 id="breaking-changes-1">Breaking changes</h3> +<h3 id="breaking-changes-2">Breaking changes</h3> <ul> -<li><p><strong>xintexpr</strong>: <code>\xintieval{[-D]...}</code>, which rounds to a multiple of <code>1eD</code> for <code>D</code> positive now <em>does not insert the trailing zeros</em> (as done at <code>1.4e</code>) <em>nor a scientific part</em> <code>eD</code> (as prior to <code>1.4e</code>). The use case envisioned is for the quantized value to be used with an appropriate unit, for example <code>k</code> for <code>D=3</code> or <code>M</code> for <code>D=6</code> etc… Sorry for the very long process which was needed to reach this final decision.</p></li> -<li><p><strong>xintexpr</strong>: for Digits beyond the officially supported range for accurate math functions, i.e. for <code>D>62</code>, computations were still done and printed with full number of digits, but the extra digits were meaningless; they now operate on and output mantissas limited to <code>min(D,64)</code> digits.</p></li> -<li><p><strong>xintexpr</strong>: for powers <code>a^b</code> with Digits at most <code>8</code>, the number <code>a</code> is now float-rounded to Digits before computation, as is done for <code>Digits>8</code>; previously <code>9</code> significant digits were kept.</p></li> -<li><p><strong>xintexpr</strong>: further changes in the computation of powers, see the bug fixes below.</p></li> -<li><p><strong>xintexpr</strong>: the <code>float_()</code> function got renamed into <code>float_dgt()</code>.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintieval{[-D]...}</code>, +which rounds to a multiple of <code>1eD</code> for <code>D</code> +positive now <em>does not insert the trailing zeros</em> (as done at +<code>1.4e</code>) <em>nor a scientific part</em> <code>eD</code> (as +prior to <code>1.4e</code>). The use case envisioned is for the +quantized value to be used with an appropriate unit, for example +<code>k</code> for <code>D=3</code> or <code>M</code> for +<code>D=6</code> etc… Sorry for the very long process which was needed +to reach this final decision.</p></li> +<li><p><strong>xintexpr</strong>: for Digits beyond the officially +supported range for accurate math functions, i.e. for +<code>D>62</code>, computations were still done and printed with full +number of digits, but the extra digits were meaningless; they now +operate on and output mantissas limited to <code>min(D,64)</code> +digits.</p></li> +<li><p><strong>xintexpr</strong>: for powers <code>a^b</code> with +Digits at most <code>8</code>, the number <code>a</code> is now +float-rounded to Digits before computation, as is done for +<code>Digits>8</code>; previously <code>9</code> significant digits +were kept.</p></li> +<li><p><strong>xintexpr</strong>: further changes in the computation of +powers, see the bug fixes below.</p></li> +<li><p><strong>xintexpr</strong>: the <code>float_()</code> function got +renamed into <code>float_dgt()</code>.</p></li> </ul> -<h3 id="bug-fixes-4">Bug fixes</h3> +<h3 id="bug-fixes-5">Bug fixes</h3> <ul> -<li><p><strong>xintexpr</strong>: the documentation said <code>float_()</code> function had been renamed <code>float_dgt()</code> but actually that was not yet the case.</p></li> -<li><p><strong>xintexpr</strong>: powers <code>a^b</code> (with exponent <code>b</code> neither integer nor half-integer) stopped being accurate regarding the last digits for <code>|b|</code> about <code>1000</code> and beyond. Except for <code>0.8<a<1.25</code> for which accuracy was maintained up to about <code>|b|=10^7</code>. Fixed via keeping the same suitable number of extra digits for internal computations of logarithms, independently of whether <code>a</code> is close to <code>1</code> or not.</p></li> -<li><p><strong>xintexpr</strong>: powers <code>a^b</code> in <code>\xinteval</code> with <code>|b|</code> an integer at least <code>10000</code> were paradoxically computed with less accuracy than in <code>\xintfloateval</code>… although they were documented to be handled exactly the same in the two parsers.</p></li> -<li><p><strong>xintexpr</strong>: powers <code>a^b</code> for Digits at most <code>8</code> unconditionally used <code>log10()/pow10()</code> approach but due to the limited accuracy of the poorman logarithm (<code>9</code> fractional digits) this was inaccurate already for <code>b</code> about <code>100</code>. So, the handling is now as for Digits at least <code>9</code>, i.e. integer and half-integer exponents are handled via the legacy <code>\xintFloatPower/\xintFloatSqrt</code> allowing arbitrarily big exponents. It is advised to split big powers with non integer non half integer exponents into a product; this is not done internally to avoid costly overhead for possibly rare use cases.</p></li> -<li><p><strong>xintexpr</strong>: the invalid input <code>(-1)^2.5</code> triggered an undefined control sequence error if Digits was at most <code>8</code>.</p></li> +<li><p><strong>xintexpr</strong>: the documentation said +<code>float_()</code> function had been renamed <code>float_dgt()</code> +but actually that was not yet the case.</p></li> +<li><p><strong>xintexpr</strong>: powers <code>a^b</code> (with exponent +<code>b</code> neither integer nor half-integer) stopped being accurate +regarding the last digits for <code>|b|</code> about <code>1000</code> +and beyond. Except for <code>0.8<a<1.25</code> for which accuracy +was maintained up to about <code>|b|=10^7</code>. Fixed via keeping the +same suitable number of extra digits for internal computations of +logarithms, independently of whether <code>a</code> is close to +<code>1</code> or not.</p></li> +<li><p><strong>xintexpr</strong>: powers <code>a^b</code> in +<code>\xinteval</code> with <code>|b|</code> an integer at least +<code>10000</code> were paradoxically computed with less accuracy than +in <code>\xintfloateval</code>… although they were documented to be +handled exactly the same in the two parsers.</p></li> +<li><p><strong>xintexpr</strong>: powers <code>a^b</code> for Digits at +most <code>8</code> unconditionally used <code>log10()/pow10()</code> +approach but due to the limited accuracy of the poorman logarithm +(<code>9</code> fractional digits) this was inaccurate already for +<code>b</code> about <code>100</code>. So, the handling is now as for +Digits at least <code>9</code>, i.e. integer and half-integer exponents +are handled via the legacy <code>\xintFloatPower/\xintFloatSqrt</code> +allowing arbitrarily big exponents. It is advised to split big powers +with non integer non half integer exponents into a product; this is not +done internally to avoid costly overhead for possibly rare use +cases.</p></li> +<li><p><strong>xintexpr</strong>: the invalid input +<code>(-1)^2.5</code> triggered an undefined control sequence error if +Digits was at most <code>8</code>.</p></li> </ul> <h2 id="e-20210505"><code>1.4e (2021/05/05)</code></h2> -<h3 id="breaking-changes-2">Breaking changes</h3> +<h3 id="breaking-changes-3">Breaking changes</h3> <ul> -<li><p><strong>xintlog</strong>: <code>\poormanloghack</code> now a no-op.</p></li> -<li><p><strong>xinttrig</strong>: loading the package does not define left-over variables holding the values of the inverse factorials used in the sine and cosine series.</p></li> -<li><p><strong>xintexpr</strong>: the output format of <code>\xinteval</code>, which uses <code>\xintFracToSci,</code> has changed. In particular, if the number has a power of ten part, it is not output with an integer mantissa, but with a scientific mantissa <code>d.d...</code> with always at least one digit after the decimal mark (possibly <code>0</code>) and trailing zeros are trimmed out. This is the same output format as used for <code>\xintfloateval</code>, apart of course from the fact that the mantissa lengths are not limited.</p></li> -<li><p><strong>xintexpr</strong>: the output format of <code>\xintfloateval</code>, which uses <code>\xintPFloat</code>, changed. The <code>\xintfloatexprPrintOne</code> macro has changed its signature to <code>[#1]{#2}</code> i.e. its first argument will be within brackets not braces.</p></li> -<li><p><strong>xintexpr</strong>: when using <code>\xintieval{[D]...}</code> optional <code>[D]</code> with a negative <code>D</code>, which triggers quantization to a positive power of ten, the output (if not the zero value) will be an integer with <code>N=abs(D)</code> explicit trailing zeros, not an integer mantissa followed by <code>eN</code>.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xinteval</code> will not compute powers <code>a^N</code> exactly if <code>N</code> in absolute value is at least the (rounded) quotient of <code>10000</code> by the number of digits of <code>a</code>; it will then use the logarithm/exponential (in base 10) approach, according to the prevailing Digits setting (at <code>1.4f</code> this got modified again and integer exponents large enough to trigger floating point evaluation are handled exactly as in <code>\xintfloateval</code>, i.e. using the legacy <strong>xintfrac</strong> <code>\xintFloatPower</code>, not the logarithm/exponential approach which loses accuracy for exponents of the order of <code>100000000</code> and beyond).</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintdeffloatvar</code> now always rounds the assigned value to the target precision. Formerly, inputs actually involving no float operations, such as for example a sub-expression <code>\xintexpr1/20!\relax</code> (in contrast to <code>1/20!</code>), or an explicit single number having more digits than the precision, got stored “as is” in the defined variable, without pre-rounding to the Digits precision.</p></li> -<li><p><strong>xintfrac</strong>:<code>\xintPFloat</code> and <code>\xintFracToSci</code> have both been modified. The macro <code>\xintFracToSciE</code> does not exist anymore, as <code>\xintFracToSci</code> in the case of scientific exponents hands over the process to <code>\xintPFloat</code> (without the rounding to Digits, of course).</p></li> +<li><p><strong>xintlog</strong>: <code>\poormanloghack</code> now a +no-op.</p></li> +<li><p><strong>xinttrig</strong>: loading the package does not define +left-over variables holding the values of the inverse factorials used in +the sine and cosine series.</p></li> +<li><p><strong>xintexpr</strong>: the output format of +<code>\xinteval</code>, which uses <code>\xintFracToSci,</code> has +changed. In particular, if the number has a power of ten part, it is not +output with an integer mantissa, but with a scientific mantissa +<code>d.d...</code> with always at least one digit after the decimal +mark (possibly <code>0</code>) and trailing zeros are trimmed out. This +is the same output format as used for <code>\xintfloateval</code>, apart +of course from the fact that the mantissa lengths are not +limited.</p></li> +<li><p><strong>xintexpr</strong>: the output format of +<code>\xintfloateval</code>, which uses <code>\xintPFloat</code>, +changed. The <code>\xintfloatexprPrintOne</code> macro has changed its +signature to <code>[#1]{#2}</code> i.e. its first argument will be +within brackets not braces.</p></li> +<li><p><strong>xintexpr</strong>: when using +<code>\xintieval{[D]...}</code> optional <code>[D]</code> with a +negative <code>D</code>, which triggers quantization to a positive power +of ten, the output (if not the zero value) will be an integer with +<code>N=abs(D)</code> explicit trailing zeros, not an integer mantissa +followed by <code>eN</code>.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xinteval</code> will not +compute powers <code>a^N</code> exactly if <code>N</code> in absolute +value is at least the (rounded) quotient of <code>10000</code> by the +number of digits of <code>a</code>; it will then use the +logarithm/exponential (in base 10) approach, according to the prevailing +Digits setting (at <code>1.4f</code> this got modified again and integer +exponents large enough to trigger floating point evaluation are handled +exactly as in <code>\xintfloateval</code>, i.e. using the legacy +<strong>xintfrac</strong> <code>\xintFloatPower</code>, not the +logarithm/exponential approach which loses accuracy for exponents of the +order of <code>100000000</code> and beyond).</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintdeffloatvar</code> now +always rounds the assigned value to the target precision. Formerly, +inputs actually involving no float operations, such as for example a +sub-expression <code>\xintexpr1/20!\relax</code> (in contrast to +<code>1/20!</code>), or an explicit single number having more digits +than the precision, got stored “as is” in the defined variable, without +pre-rounding to the Digits precision.</p></li> +<li><p><strong>xintfrac</strong>:<code>\xintPFloat</code> and +<code>\xintFracToSci</code> have both been modified. The macro +<code>\xintFracToSciE</code> does not exist anymore, as +<code>\xintFracToSci</code> in the case of scientific exponents hands +over the process to <code>\xintPFloat</code> (without the rounding to +Digits, of course).</p></li> </ul> -<h3 id="new-features-2">New features</h3> +<h3 id="new-features-3">New features</h3> <ul> -<li><p><strong>xintlog</strong>: now working up to <code>62</code> digits. The legacy faster <code>poormanlog</code>-based macros are kept for computations with Digits up to <code>8</code>. Fractional powers are now available both in <code>xinteval</code> and <code>xintfloateval</code>, per default.</p></li> -<li><p><strong>xinttrig</strong>: now working up to <code>62</code> digits and with increased accuracy. Special faster (or not as slow if you prefer) mode at <code>8</code> digits or less.</p></li> -<li><p><strong>xintexpr</strong>: the constraints on the <code>\xintexprPrintOne</code> replacement macro, which defaults to <code>\xintFracToSci</code>, have been much simplified.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintiexprPrintOne</code> (defaults to <code>\xintDecToString</code>)</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintPFloatE</code> may be redefined as a macro which fetches the scientific exponent as a mandatory argument delimited with a dot, and outputs a suitable formatted result (f-expandably), also delimited with a dot which will be removed by internal processing. The default however simply expands to the letter <code>e</code>.</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintDecToStringREZ</code> is like <code>\xintDecToString</code> but starts by removing trailing zeroes.</p></li> +<li><p><strong>xintlog</strong>: now working up to <code>62</code> +digits. The legacy faster <code>poormanlog</code>-based macros are kept +for computations with Digits up to <code>8</code>. Fractional powers are +now available both in <code>xinteval</code> and +<code>xintfloateval</code>, per default.</p></li> +<li><p><strong>xinttrig</strong>: now working up to <code>62</code> +digits and with increased accuracy. Special faster (or not as slow if +you prefer) mode at <code>8</code> digits or less.</p></li> +<li><p><strong>xintexpr</strong>: the constraints on the +<code>\xintexprPrintOne</code> replacement macro, which defaults to +<code>\xintFracToSci</code>, have been much simplified.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintiexprPrintOne</code> +(defaults to <code>\xintDecToString</code>)</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintPFloatE</code> may be +redefined as a macro which fetches the scientific exponent as a +mandatory argument delimited with a dot, and outputs a suitable +formatted result (f-expandably), also delimited with a dot which will be +removed by internal processing. The default however simply expands to +the letter <code>e</code>.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintDecToStringREZ</code> is +like <code>\xintDecToString</code> but starts by removing trailing +zeroes.</p></li> </ul> -<h3 id="bug-fixes-5">Bug fixes</h3> +<h3 id="bug-fixes-6">Bug fixes</h3> <ul> -<li><strong>xintfrac</strong>, <strong>xintexpr</strong>: it was not possible to use <code>\xinttheDigits</code> in the right hand side of an <code>\xintDigits</code> assignment. For example: <code>\xintDigits*:=\numexpr\xinttheDigits+4;</code>. This is now allowed, and the same applies to the macro interface, for example <code>\xintSetDigits*{\xinttheDigits+4}</code>.</li> +<li><strong>xintfrac</strong>, <strong>xintexpr</strong>: it was not +possible to use <code>\xinttheDigits</code> in the right hand side of an +<code>\xintDigits</code> assignment. For example: +<code>\xintDigits*:=\numexpr\xinttheDigits+4;</code>. This is now +allowed, and the same applies to the macro interface, for example +<code>\xintSetDigits*{\xinttheDigits+4}</code>.</li> </ul> <h2 id="d-20210329"><code>1.4d (2021/03/29)</code></h2> -<h3 id="breaking-changes-3">Breaking changes</h3> +<h3 id="breaking-changes-4">Breaking changes</h3> <ul> -<li><p><code>quo()</code> and <code>rem()</code> in <code>\xintiiexpr/\xintiieval</code> renamed to <code>iquo()</code> and <code>irem()</code>.</p></li> -<li><p>The output of <code>gcd()</code> and <code>lcm()</code> as applied to fractions is now always in lowest terms.</p></li> -<li><p>The log message to report a variable creation (if <code>\xintverbosetrue</code>) does not use (double) quotes anymore around the name. By the way, quotes were never used for function names.</p></li> +<li><p><code>quo()</code> and <code>rem()</code> in +<code>\xintiiexpr/\xintiieval</code> renamed to <code>iquo()</code> and +<code>irem()</code>.</p></li> +<li><p>The output of <code>gcd()</code> and <code>lcm()</code> as +applied to fractions is now always in lowest terms.</p></li> +<li><p>The log message to report a variable creation (if +<code>\xintverbosetrue</code>) does not use (double) quotes anymore +around the name. By the way, quotes were never used for function +names.</p></li> </ul> -<h3 id="bug-fixes-6">Bug fixes</h3> +<h3 id="bug-fixes-7">Bug fixes</h3> <ul> -<li><p>Ever since <code>1.3</code> the <code>quo()</code> and <code>rem()</code> functions in <code>\xintexpr</code> (not the ones in <code>\xintiiexpr</code>) were broken as their (officially deprecated) support macros had been removed! They had somewhat useless definitions anyway. They have now been officially removed from the syntax. Their siblings in <code>\xintiieval</code> were renamed to <code>iquo()</code> and <code>irem()</code>.</p></li> -<li><p>Sadly, <code>gcd()</code> was broken in <code>\xintexpr</code> since <code>1.4</code>, if the first argument vanished. And <code>gcd()</code> was broken in <code>\xintiiexpr</code> since <code>1.3d</code> if <em>any</em> argument vanished. I did have a unit test! (which obviously was too limited …)</p> -<p>Further, the <code>\xintGCDof</code> and <code>\xintLCMof</code> <strong>xintfrac</strong> macros were added at <code>1.4</code> but did not behave like other <strong>xintfrac</strong> macros with respect to parsing their arguments: e.g. <code>\xintGCDof{2}{03}</code> gave an unexpected non-numeric result.</p></li> -<li><p>The <code>first()</code> and <code>last()</code> functions, if used as arguments to numerical functions such as <code>sqr()</code> inside an <code>\xintdeffunc</code> caused the defined function to be broken.</p></li> +<li><p>Ever since <code>1.3</code> the <code>quo()</code> and +<code>rem()</code> functions in <code>\xintexpr</code> (not the ones in +<code>\xintiiexpr</code>) were broken as their (officially deprecated) +support macros had been removed! They had somewhat useless definitions +anyway. They have now been officially removed from the syntax. Their +siblings in <code>\xintiieval</code> were renamed to <code>iquo()</code> +and <code>irem()</code>.</p></li> +<li><p>Sadly, <code>gcd()</code> was broken in <code>\xintexpr</code> +since <code>1.4</code>, if the first argument vanished. And +<code>gcd()</code> was broken in <code>\xintiiexpr</code> since +<code>1.3d</code> if <em>any</em> argument vanished. I did have a unit +test! (which obviously was too limited …)</p> +<p>Further, the <code>\xintGCDof</code> and <code>\xintLCMof</code> +<strong>xintfrac</strong> macros were added at <code>1.4</code> but did +not behave like other <strong>xintfrac</strong> macros with respect to +parsing their arguments: e.g. <code>\xintGCDof{2}{03}</code> gave an +unexpected non-numeric result.</p></li> +<li><p>The <code>first()</code> and <code>last()</code> functions, if +used as arguments to numerical functions such as <code>sqr()</code> +inside an <code>\xintdeffunc</code> caused the defined function to be +broken.</p></li> </ul> <h2 id="c-20210220"><code>1.4c (2021/02/20)</code></h2> -<h3 id="bug-fixes-7">Bug fixes</h3> +<h3 id="bug-fixes-8">Bug fixes</h3> <ul> -<li>Fix <code>1.4</code> regression which broke syntax <code>varname(...)</code> which supposedly is allowed and inserts a tacit multiplication.</li> +<li>Fix <code>1.4</code> regression which broke syntax +<code>varname(...)</code> which supposedly is allowed and inserts a +tacit multiplication.</li> </ul> <h2 id="b-20200225"><code>1.4b (2020/02/25)</code></h2> <p>All changes regard the <strong>xintexpr</strong> module.</p> <h3 id="future">Future</h3> <ul> -<li><p><code>&</code>, <code>|</code>, (as Boolean operators) and <code>=</code> (as equality test) have long been deprecated in favour of <code>&&</code>, <code>||</code> and <code>==</code>. They will be removed at next major release.</p></li> -<li><p>At next major release the power operators <code>**</code> and <code>^</code> will turn from left to right associative. I.e. <code>2**2**3</code> will give <code>256</code>, not <code>64</code>. This is to match with Python and l3fp.</p></li> -<li><p><code>\thexintexpr</code> et al. (introduced at <code>1.2h</code> but not documented anymore for some time) will be removed at next major release. The original <code>\xinttheexpr</code> et al. have always been so much better names. Besides, since <code>1.4</code>, <code>\xintexpr</code> can be used directly in typesetting flow.</p></li> +<li><p><code>&</code>, <code>|</code>, (as Boolean operators) and +<code>=</code> (as equality test) have long been deprecated in favour of +<code>&&</code>, <code>||</code> and <code>==</code>. They will +be removed at next major release.</p></li> +<li><p>At next major release the power operators <code>**</code> and +<code>^</code> will turn from left to right associative. I.e. +<code>2**2**3</code> will give <code>256</code>, not <code>64</code>. +This is to match with Python and l3fp.</p></li> +<li><p><code>\thexintexpr</code> et al. (introduced at <code>1.2h</code> +but not documented anymore for some time) will be removed at next major +release. The original <code>\xinttheexpr</code> et al. have always been +so much better names. Besides, since <code>1.4</code>, +<code>\xintexpr</code> can be used directly in typesetting +flow.</p></li> </ul> -<h3 id="new-features-3">New features</h3> +<h3 id="new-features-4">New features</h3> <ul> -<li><p>Function <code>zip()</code> is modeled on Python’s function of the same name.</p></li> -<li><p>Function <code>flat()</code> removes all nesting to produce a “one-dimensional” list having the exact same leaves (some possibly empty) as the original (in the same order).</p></li> -<li><p>Chaining of comparison operators (e.g. <code>x<y<z</code>) as in Python (but all comparisons are done even if one is found false) and l3fp.</p></li> -<li><p>It was possible since <code>1.4</code>’s <code>\xintFracToSciE</code> to configure the separator between mantissas and exponents in the output of <code>\xinteval</code> but strangely there was no way to customize the output of <code>\xintfloateval</code>. The added <code>\xintPFloatE</code> fixes this.</p></li> +<li><p>Function <code>zip()</code> is modeled on Python’s function of +the same name.</p></li> +<li><p>Function <code>flat()</code> removes all nesting to produce a +“one-dimensional” list having the exact same leaves (some possibly +empty) as the original (in the same order).</p></li> +<li><p>Chaining of comparison operators (e.g. <code>x<y<z</code>) +as in Python (but all comparisons are done even if one is found false) +and l3fp.</p></li> +<li><p>It was possible since <code>1.4</code>’s +<code>\xintFracToSciE</code> to configure the separator between +mantissas and exponents in the output of <code>\xinteval</code> but +strangely there was no way to customize the output of +<code>\xintfloateval</code>. The added <code>\xintPFloatE</code> fixes +this.</p></li> </ul> -<h3 id="bug-fixes-8">Bug fixes</h3> +<h3 id="bug-fixes-9">Bug fixes</h3> <ul> -<li><code>\xintieval{[D]...}</code> with a negative <code>D</code> (a feature added at <code>1.4a</code>) used erroneously a catcode 12 <code>e</code> in output, which moreover remained immuned to the <code>\xintFracToSciE</code> setting.</li> +<li><code>\xintieval{[D]...}</code> with a negative <code>D</code> (a +feature added at <code>1.4a</code>) used erroneously a catcode 12 +<code>e</code> in output, which moreover remained immuned to the +<code>\xintFracToSciE</code> setting.</li> </ul> <h2 id="a-20200219"><code>1.4a (2020/02/19)</code></h2> <p>All changes regard the <strong>xintexpr</strong> module.</p> -<h3 id="breaking-changes-4">Breaking changes</h3> +<h3 id="breaking-changes-5">Breaking changes</h3> <ul> -<li>The macros implementing customization of <code>\xintthealign</code> have modified meanings and names.</li> +<li>The macros implementing customization of <code>\xintthealign</code> +have modified meanings and names.</li> </ul> -<h3 id="new-features-4">New features</h3> +<h3 id="new-features-5">New features</h3> <ul> -<li><p><code>\xintthespaceseparated</code> (serves to provide suitable input to PS-Tricks <code>\listplot</code>).</p></li> -<li><p>The optional argument <code>[D]</code> to <code>\xintieval/\xintiexpr</code> can be negative, with the same meaning as the non-negative case, i.e. rounding to an integer multiple of <code>10^(-D)</code>.</p> -<p>The same applies to the functions <code>trunc()</code> and <code>round()</code>. And to the <code>\xintTrunc</code>, <code>\xintRound</code>, <code>\xintiTrunc</code>, and <code>\xintiRound</code> macros of <strong>xintfrac</strong>.</p></li> +<li><p><code>\xintthespaceseparated</code> (serves to provide suitable +input to PS-Tricks <code>\listplot</code>).</p></li> +<li><p>The optional argument <code>[D]</code> to +<code>\xintieval/\xintiexpr</code> can be negative, with the same +meaning as the non-negative case, i.e. rounding to an integer multiple +of <code>10^(-D)</code>.</p> +<p>The same applies to the functions <code>trunc()</code> and +<code>round()</code>. And to the <code>\xintTrunc</code>, +<code>\xintRound</code>, <code>\xintiTrunc</code>, and +<code>\xintiRound</code> macros of <strong>xintfrac</strong>.</p></li> </ul> -<h3 id="bug-fixes-9">Bug fixes</h3> +<h3 id="bug-fixes-10">Bug fixes</h3> <ul> -<li><p>Usage of <code>round()</code> and <code>trunc()</code> within <code>\xintdeffunc</code> got broken at <code>1.4</code>.</p></li> -<li><p><code>add()</code> and <code>mul()</code> were supposedly accepting the <code>omit</code>, <code>abort</code> and <code>break()</code> keywords since <code>1.4</code> but this was broken.</p></li> +<li><p>Usage of <code>round()</code> and <code>trunc()</code> within +<code>\xintdeffunc</code> got broken at <code>1.4</code>.</p></li> +<li><p><code>add()</code> and <code>mul()</code> were supposedly +accepting the <code>omit</code>, <code>abort</code> and +<code>break()</code> keywords since <code>1.4</code> but this was +broken.</p></li> </ul> <h2 id="section"><code>1.4 (2020/01/31)</code></h2> -<h3 id="breaking-changes-5">Breaking changes</h3> -<p>Please note that this list may still be incomplete. If not otherly specified all items regard the <strong>xintexpr</strong> module.</p> -<ul> -<li><p>The <code>\expanded</code> primitive (TeXLive 2019) is <strong>required</strong>. This does not affect the macro layer <strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>, <strong>xinttools</strong> (yet).</p></li> -<li><p>Formerly square brackets <code>[...]</code> were, on their own, not different from parentheses (and thus disappeared from the output), but they are now a genuine constructor of nested lists. For example <code>\xinteval{1, [2, [3, 4]], 5}</code> produces <code>1, [2, [3, 4]], 5</code> (recall this is free bloatware).</p></li> -<li><p>The output of <code>\xinteval</code> has changed (besides containing brackets). It does not use anymore the so-called <em>raw</em> <strong>xintfrac</strong> format, i.e. things such as <code>A/B[N]</code> (which can still be used in input but are discouraged in <strong>xintexpr</strong> context), but scientific notation <code>AeN/B</code>. As formerly, the denominator is printed only if <code>B>1</code> and the scientific part is dropped if the exponent vanishes. In this way the output of <code>\xinteval</code> can be pasted to alternative software.</p></li> -<li><p>The output format of <code>\xinthe\xintboolexpr</code> also has changed. It uses <code>True</code> and <code>False</code> (which are accepted on input), and this can easily be configured otherwise (also <code>true</code> and <code>false</code> are accepted on input).</p></li> -<li><p>The “broadcasting” (as it turned out, à la <code>NumPy</code>) of scalar operations on one-dimensional “lists”, e.g <code>3*[1,3,5,7]+10</code> acting itemwise is <strong>dropped</strong>. It is hoped to implement such operations again in stronger form in future releases. Pre-existing alternative syntax is available, also to produce the bracketed (cf. next item) <code>[13,19,25,31]</code> which will be the output in future.</p></li> -<li><p>The <code>divmod()</code> function now produces on output such a bracketed pair, but simultaneous assignment such as <code>\xintdefvar xq, xr = divmod(a,b);</code> will work transparently.</p></li> -<li><p>The syntax for using conditionals in function declarations has changed. Now, one <em>must</em> use the <code>?</code> and <code>??</code> short-circuit boolean branching operators whereas in the past it was explained that the syntax had to use the <code>if()</code> and <code>ifsgn()</code> functions.</p></li> -<li><p>Macros <code>\xintGCD</code>, <code>\xintLCM</code>, <code>\xintGCDof</code> and <code>\xintLCMof</code> formerly provided by <strong>xintgcd</strong> got moved to <strong>xintfrac</strong> (which is not loaded by <strong>xintgcd</strong>). Moreover, they were extended to handle general fractions on input but this also means that their output is now obiding by the raw <strong>xintfrac</strong> format. The integer only <code>\xintiiGCD</code>, <code>\xintiiLCM</code> also got moved out of <strong>xintgcd</strong>, but to <strong>xint</strong> which is now loaded automatically by <strong>xintgcd</strong>. The few remaining macros of <strong>xintgcd</strong> at least do not need other imports as <strong>xintgcd</strong> now loads also automatically <strong>xinttools</strong> which is a dependency for two of them.</p></li> -</ul> -<h3 id="improvements-and-new-features">Improvements and new features</h3> -<p>Please note that this list is currently incomplete. For more information look at the user manual and the documented source code <code>sourcexint.pdf</code>.</p> -<p>Unless otherwise specified all changes commented upon here regard <strong>xintexpr</strong>. Important: all the new syntax is to be considered experimental. The author may change some names in future release, or even the interface (whether to use semi-colons or colons etc…).</p> -<ul> -<li><p>The <code>\csname</code> encapsulation technique used since <strong>xintexpr</strong> initial release (<code>1.07 2013/05/25</code>) to move around possibly large data during expansion-only operations is replaced with methods based on the <code>\expanded</code> engine primitive. The latter is available in all major engines since TeXLive 2019.</p> -<p>Formerly, and with default memory settings, one would typically saturate the string pool memory after about of the order of 50,000 independent floating point evaluations of expressions of average complexity on 16-digits numbers.</p> -<p>There is thus no string pool memory impact at all but one can now hit TeX’s main memory limit (which typically stands at 5,000,000 words) from defining large variables or generating on the fly large data. TeX distributions have a configuration file allowing to enlarge TeX memory parameters and regenerate the (eTeX based) formats.</p></li> -<li><p>The package supports input and output of arbitrarily <em>nested lists</em>, a.k.a. <em>oples</em> or <em>nlists</em>, with <code>[...]</code> as the constructor of <em>bracketed lists</em>, a.k.a <em>nut-ples</em>. Operations on these objects (as briefly surveyed in later items) are inspired from syntax and functionalities of <code>NumPy</code>’s <em>ndarrays</em>. Our <em>oples</em> (hence also their packaged form <em>nut-ples</em>) may have <em>leaves</em> at varying depths rather than obeying an N-dimensional hyperrectangular shape. But the syntax does provide specific constructors for <em>ndlists</em> (i.e. hyperrectangular <em>oples</em> or <em>nut-ples</em>).</p> -<p>In a (distant?) future, perhaps <strong>xintexpr</strong> itself or a third-party package will provide an interface, say <code>\xintstorearray</code>, <code>\xintgetarray</code>, to store (which can not be expandable) and retrieve (which can be expandable and thus be embedded inside expressions parsed by <code>\xintexpr</code>, <code>\xintiiexpr</code> or <code>\xintfloatexpr</code>) such <em>ndlists</em> from TeX memory. This is why the package does not use the word <em>ndarray</em> and reserves it for such memory stored objects.</p></li> -<li><p>The <code>*</code> serves as <em>unpacking</em> operator on <em>nut-ples</em>, i.e. reversing the <code>[]</code> bracketing of an <em>ople</em>.</p></li> -<li><p><em>oples</em> have no exact equivalent in <code>Python</code>. For example <strong>xintexpr</strong> allows <code>foo(Var1, x)</code> if <code>foo</code> is a function of 4 variables and <code>Var1</code> is a variable producing a length 3 <em>ople</em>, or <code>foo(Var2)</code> if <code>Var2</code> is a variable producing a length 4 <em>ople</em>. Python would require here to use explicitly the <code>*</code>-unpacking notation on some “packed” objects.</p> -<p>Variable and function values may be <em>oples</em> (even <em>nil</em>), but in function declarations variables must stand for <em>one-ples</em>, i.e. either <em>numbers</em> or <em>nut-ples</em> (as there is no non-ambiguous way to split e.g. 5 arguments into two separate <em>oples</em>).</p></li> -<li><p>Simultaneous assignment to at least two variables via <code>\xintdefvar</code> et al. automatically unpacks the assigned value if it is a <em>one-ple</em>. If this value was in fact a <em>number</em>, low-level errors will result shortly afterwards as no check is done if the unpacking was illicit. (update: this last remark does not apply since the <code>1.4i</code> extension to the concept of simultaneous assignments)</p></li> -<li><p>The <code>NumPy</code> concept and syntax for nested slicing and item selection are implemented. Currently <em>stepping</em> and the <em>Ellipsis object</em> are not yet available. Only so-called basic slicing is currently supported. (The author has not yet read the section of <code>NumPy</code> documentation on so-called <em>advanced indexing</em>).</p></li> -<li><p>The <em>broadcasting</em> of scalar operations, such as itemwise addition or multiplication of <em>nut-ples</em> of the same shape is <strong>not yet implemented</strong>.</p></li> -<li><p>Slicing and indexing apply also at top level to the <em>oples</em> with behaviour conforming to intuitive expectations (see user manual); if it turns out the <em>ople</em> is in fact a <em>nut-ple</em>, the top-level slicing/indexing switches to the <code>Python/NumPy</code> conventions, i.e. it operates inside the brackets for slicing and removes brackets if indexing.</p></li> -<li><p>The syntax <code>ndseq(expression in x, y, ..., x = values; y = values; ...)</code> constructs a (bracketed) <em>ndlist</em> by evaluation the expression on all possible Cartesian n-uples, where the first variable indexes the first axis, the second the next, etc…</p></li> -<li><p>The <code>ndmap(foo, values1; values2; ...; valuesN)</code> syntax constructs a (bracketed) <em>ndlist</em> by evaluating the function <code>foo</code> on all elements of the cartesian product of the given (one-dimensional) value lists.</p></li> -<li><p>The two concepts of <code>\xintdeffunc</code> (for recursive definitions) and <code>\xintdefefunc</code> (for functions which expand immediately in other function declarations) have been merged. The <code>\xintdefefunc</code> et al. are deprecated and kept as aliases for <code>\xintdeffunc</code> et al.</p></li> -<li><p><code>\xintdefufunc</code> allows to define so-called <em>universal functions</em>, i.e. functions <code>foo</code> such that <code>foo(myople)</code> will apply itemwise at arbitrary depth in the nested structure. The function <code>foo</code> is allowed to produce from a scalar an <em>ople</em>…</p></li> -<li><p>The variables in function declarations can now be multi-letter words.</p></li> -<li><p>The last positional variable in a function declaration can be prefixed with a <code>*</code> meaning exactly as in Python (<em>variadic</em> function argument) that it stands for a one-dimensional <em>nut-ple</em> receiving all remaining arguments from the function call beyond the first positional ones. It is thus an optional argument, but syntax for named optional arguments with default values is not yet implemented.</p></li> -<li><p>Dummy variables used in constructors can also be multi-letter words, if they have been declared as such.</p></li> -<li><p>In variable and function declarations, if the expression contains inner semi-colons, it is not needed anymore to brace them to avoid mis-interpretation as the final semi-colon which is mandated by the syntax to serve as expression terminator.</p></li> -<li><p><code>subsm(expression, var1 = value1; var2 = value2; ...)</code> provides a leaner syntax for multiple substitutions; they must be independent, though.</p></li> -<li><p><code>subsn(expression, var1 = value1; var2 = value2; ...)</code> provides a leaner syntax for nested substitutions, i.e., each <code>valueJ</code> may be an expression using the dummy variables <code>varK</code> with <code>K>J</code>. And finally of course the evaluated expression can refer to all variables.</p></li> -<li><p><code>\xintthealign\xintexpr...\relax</code> (or with <code>\xintfloatexpr</code> or <code>\xintiiexpr</code> or <code>\xintboolexpr</code>…) will use a TeX alignment to display <em>oples</em>. The output (for regular N-dimensional lists) looks very similar to what <code>Python/NumPy</code> produces in interactive session. This is entirely configurable and can also be set-up to be used for writing into external files.</p> -<p>Attention that <code>\xintthealign</code> only works if followed by <code>\xintexpr</code> et al., not by <code>\xinteval{}</code>.</p></li> -<li><p>It is now possible to use <code>\xintexpr...\relax</code> directly for typesetting. The syntax <code>\xinteval{...}</code> or <code>\xintthe\xintexpr...\relax</code> is needed only if one wants the expansion to give the explicit digits, but <code>\xintexpr...\relax</code> by itself will typeset as would have the other ones. Further it can be used in so-called moving arguments, because when output to an external file it uses only characters with standard catcodes (and produces the same protected and re-tokenizable result it would in an <code>\edef</code>.)</p> -<p>As formerly, <code>\xintexpr...\relax</code> is the preferred way to include an expression into another one. Using <code>\xinteval</code> is a waste because it forces the outer parser to re-digest all the digits (or now also the square brackets).</p></li> -<li><p>The output format of <code>\xintfloateval</code> with scientific notation has not changed (apart from possible presence of bracketed lists), but the author hesitates because the <em>prettifying</em> it does by default is not really adapted to display of arrays (see <code>\xintthealign</code>). Anyway, this is configurable by the user. It is possible to specify whether to use <code>e</code> or <code>E</code>.</p></li> -<li><p>Function declarations are able to parse a much wider part of the syntax, but some severe limitations remain. Refer to the user manual for related information.</p></li> -<li><p>We have made an effort on some error messages, and when working interactively in a shell it may even be sometimes possible to insert for example a correct variable or function name in place of the not recognized one. But don’t expect miracles when trying to intervene in the midst of a purely expandable expansion…</p></li> +<h3 id="breaking-changes-6">Breaking changes</h3> +<p>Please note that this list may still be incomplete. If not otherly +specified all items regard the <strong>xintexpr</strong> module.</p> +<ul> +<li><p>The <code>\expanded</code> primitive (TeXLive 2019) is +<strong>required</strong>. This does not affect the macro layer +<strong>xintcore</strong>, <strong>xint</strong>, +<strong>xintfrac</strong>, <strong>xinttools</strong> (yet).</p></li> +<li><p>Formerly square brackets <code>[...]</code> were, on their own, +not different from parentheses (and thus disappeared from the output), +but they are now a genuine constructor of nested lists. For example +<code>\xinteval{1, [2, [3, 4]], 5}</code> produces +<code>1, [2, [3, 4]], 5</code> (recall this is free bloatware).</p></li> +<li><p>The output of <code>\xinteval</code> has changed (besides +containing brackets). It does not use anymore the so-called <em>raw</em> +<strong>xintfrac</strong> format, i.e. things such as +<code>A/B[N]</code> (which can still be used in input but are +discouraged in <strong>xintexpr</strong> context), but scientific +notation <code>AeN/B</code>. As formerly, the denominator is printed +only if <code>B>1</code> and the scientific part is dropped if the +exponent vanishes. In this way the output of <code>\xinteval</code> can +be pasted to alternative software.</p></li> +<li><p>The output format of <code>\xinthe\xintboolexpr</code> also has +changed. It uses <code>True</code> and <code>False</code> (which are +accepted on input), and this can easily be configured otherwise (also +<code>true</code> and <code>false</code> are accepted on +input).</p></li> +<li><p>The “broadcasting” (as it turned out, à la <code>NumPy</code>) of +scalar operations on one-dimensional “lists”, e.g +<code>3*[1,3,5,7]+10</code> acting itemwise is <strong>dropped</strong>. +It is hoped to implement such operations again in stronger form in +future releases. Pre-existing alternative syntax is available, also to +produce the bracketed (cf. next item) <code>[13,19,25,31]</code> which +will be the output in future.</p></li> +<li><p>The <code>divmod()</code> function now produces on output such a +bracketed pair, but simultaneous assignment such as +<code>\xintdefvar xq, xr = divmod(a,b);</code> will work +transparently.</p></li> +<li><p>The syntax for using conditionals in function declarations has +changed. Now, one <em>must</em> use the <code>?</code> and +<code>??</code> short-circuit boolean branching operators whereas in the +past it was explained that the syntax had to use the <code>if()</code> +and <code>ifsgn()</code> functions.</p></li> +<li><p>Macros <code>\xintGCD</code>, <code>\xintLCM</code>, +<code>\xintGCDof</code> and <code>\xintLCMof</code> formerly provided by +<strong>xintgcd</strong> got moved to <strong>xintfrac</strong> (which +is not loaded by <strong>xintgcd</strong>). Moreover, they were extended +to handle general fractions on input but this also means that their +output is now obiding by the raw <strong>xintfrac</strong> format. The +integer only <code>\xintiiGCD</code>, <code>\xintiiLCM</code> also got +moved out of <strong>xintgcd</strong>, but to <strong>xint</strong> +which is now loaded automatically by <strong>xintgcd</strong>. The few +remaining macros of <strong>xintgcd</strong> at least do not need other +imports as <strong>xintgcd</strong> now loads also automatically +<strong>xinttools</strong> which is a dependency for two of +them.</p></li> +</ul> +<h3 id="improvements-and-new-features">Improvements and new +features</h3> +<p>Please note that this list is currently incomplete. For more +information look at the user manual and the documented source code +<code>sourcexint.pdf</code>.</p> +<p>Unless otherwise specified all changes commented upon here regard +<strong>xintexpr</strong>. Important: all the new syntax is to be +considered experimental. The author may change some names in future +release, or even the interface (whether to use semi-colons or colons +etc…).</p> +<ul> +<li><p>The <code>\csname</code> encapsulation technique used since +<strong>xintexpr</strong> initial release (<code>1.07 2013/05/25</code>) +to move around possibly large data during expansion-only operations is +replaced with methods based on the <code>\expanded</code> engine +primitive. The latter is available in all major engines since TeXLive +2019.</p> +<p>Formerly, and with default memory settings, one would typically +saturate the string pool memory after about of the order of 50,000 +independent floating point evaluations of expressions of average +complexity on 16-digits numbers.</p> +<p>There is thus no string pool memory impact at all but one can now hit +TeX’s main memory limit (which typically stands at 5,000,000 words) from +defining large variables or generating on the fly large data. TeX +distributions have a configuration file allowing to enlarge TeX memory +parameters and regenerate the (eTeX based) formats.</p></li> +<li><p>The package supports input and output of arbitrarily <em>nested +lists</em>, a.k.a. <em>oples</em> or <em>nlists</em>, with +<code>[...]</code> as the constructor of <em>bracketed lists</em>, a.k.a +<em>nut-ples</em>. Operations on these objects (as briefly surveyed in +later items) are inspired from syntax and functionalities of +<code>NumPy</code>’s <em>ndarrays</em>. Our <em>oples</em> (hence also +their packaged form <em>nut-ples</em>) may have <em>leaves</em> at +varying depths rather than obeying an N-dimensional hyperrectangular +shape. But the syntax does provide specific constructors for +<em>ndlists</em> (i.e. hyperrectangular <em>oples</em> or +<em>nut-ples</em>).</p> +<p>In a (distant?) future, perhaps <strong>xintexpr</strong> itself or a +third-party package will provide an interface, say +<code>\xintstorearray</code>, <code>\xintgetarray</code>, to store +(which can not be expandable) and retrieve (which can be expandable and +thus be embedded inside expressions parsed by <code>\xintexpr</code>, +<code>\xintiiexpr</code> or <code>\xintfloatexpr</code>) such +<em>ndlists</em> from TeX memory. This is why the package does not use +the word <em>ndarray</em> and reserves it for such memory stored +objects.</p></li> +<li><p>The <code>*</code> serves as <em>unpacking</em> operator on +<em>nut-ples</em>, i.e. reversing the <code>[]</code> bracketing of an +<em>ople</em>.</p></li> +<li><p><em>oples</em> have no exact equivalent in <code>Python</code>. +For example <strong>xintexpr</strong> allows <code>foo(Var1, x)</code> +if <code>foo</code> is a function of 4 variables and <code>Var1</code> +is a variable producing a length 3 <em>ople</em>, or +<code>foo(Var2)</code> if <code>Var2</code> is a variable producing a +length 4 <em>ople</em>. Python would require here to use explicitly the +<code>*</code>-unpacking notation on some “packed” objects.</p> +<p>Variable and function values may be <em>oples</em> (even +<em>nil</em>), but in function declarations variables must stand for +<em>one-ples</em>, i.e. either <em>numbers</em> or <em>nut-ples</em> (as +there is no non-ambiguous way to split e.g. 5 arguments into two +separate <em>oples</em>).</p></li> +<li><p>Simultaneous assignment to at least two variables via +<code>\xintdefvar</code> et al. automatically unpacks the assigned value +if it is a <em>one-ple</em>. If this value was in fact a +<em>number</em>, low-level errors will result shortly afterwards as no +check is done if the unpacking was illicit. (update: this last remark +does not apply since the <code>1.4i</code> extension to the concept of +simultaneous assignments)</p></li> +<li><p>The <code>NumPy</code> concept and syntax for nested slicing and +item selection are implemented. Currently <em>stepping</em> and the +<em>Ellipsis object</em> are not yet available. Only so-called basic +slicing is currently supported. (The author has not yet read the section +of <code>NumPy</code> documentation on so-called <em>advanced +indexing</em>).</p></li> +<li><p>The <em>broadcasting</em> of scalar operations, such as itemwise +addition or multiplication of <em>nut-ples</em> of the same shape is +<strong>not yet implemented</strong>.</p></li> +<li><p>Slicing and indexing apply also at top level to the +<em>oples</em> with behaviour conforming to intuitive expectations (see +user manual); if it turns out the <em>ople</em> is in fact a +<em>nut-ple</em>, the top-level slicing/indexing switches to the +<code>Python/NumPy</code> conventions, i.e. it operates inside the +brackets for slicing and removes brackets if indexing.</p></li> +<li><p>The syntax +<code>ndseq(expression in x, y, ..., x = values; y = values; ...)</code> +constructs a (bracketed) <em>ndlist</em> by evaluation the expression on +all possible Cartesian n-uples, where the first variable indexes the +first axis, the second the next, etc…</p></li> +<li><p>The <code>ndmap(foo, values1; values2; ...; valuesN)</code> +syntax constructs a (bracketed) <em>ndlist</em> by evaluating the +function <code>foo</code> on all elements of the cartesian product of +the given (one-dimensional) value lists.</p></li> +<li><p>The two concepts of <code>\xintdeffunc</code> (for recursive +definitions) and <code>\xintdefefunc</code> (for functions which expand +immediately in other function declarations) have been merged. The +<code>\xintdefefunc</code> et al. are deprecated and kept as aliases for +<code>\xintdeffunc</code> et al.</p></li> +<li><p><code>\xintdefufunc</code> allows to define so-called +<em>universal functions</em>, i.e. functions <code>foo</code> such that +<code>foo(myople)</code> will apply itemwise at arbitrary depth in the +nested structure. The function <code>foo</code> is allowed to produce +from a scalar an <em>ople</em>…</p></li> +<li><p>The variables in function declarations can now be multi-letter +words.</p></li> +<li><p>The last positional variable in a function declaration can be +prefixed with a <code>*</code> meaning exactly as in Python +(<em>variadic</em> function argument) that it stands for a +one-dimensional <em>nut-ple</em> receiving all remaining arguments from +the function call beyond the first positional ones. It is thus an +optional argument, but syntax for named optional arguments with default +values is not yet implemented.</p></li> +<li><p>Dummy variables used in constructors can also be multi-letter +words, if they have been declared as such.</p></li> +<li><p>In variable and function declarations, if the expression contains +inner semi-colons, it is not needed anymore to brace them to avoid +mis-interpretation as the final semi-colon which is mandated by the +syntax to serve as expression terminator.</p></li> +<li><p><code>subsm(expression, var1 = value1; var2 = value2; ...)</code> +provides a leaner syntax for multiple substitutions; they must be +independent, though.</p></li> +<li><p><code>subsn(expression, var1 = value1; var2 = value2; ...)</code> +provides a leaner syntax for nested substitutions, i.e., each +<code>valueJ</code> may be an expression using the dummy variables +<code>varK</code> with <code>K>J</code>. And finally of course the +evaluated expression can refer to all variables.</p></li> +<li><p><code>\xintthealign\xintexpr...\relax</code> (or with +<code>\xintfloatexpr</code> or <code>\xintiiexpr</code> or +<code>\xintboolexpr</code>…) will use a TeX alignment to display +<em>oples</em>. The output (for regular N-dimensional lists) looks very +similar to what <code>Python/NumPy</code> produces in interactive +session. This is entirely configurable and can also be set-up to be used +for writing into external files.</p> +<p>Attention that <code>\xintthealign</code> only works if followed by +<code>\xintexpr</code> et al., not by <code>\xinteval{}</code>.</p></li> +<li><p>It is now possible to use <code>\xintexpr...\relax</code> +directly for typesetting. The syntax <code>\xinteval{...}</code> or +<code>\xintthe\xintexpr...\relax</code> is needed only if one wants the +expansion to give the explicit digits, but +<code>\xintexpr...\relax</code> by itself will typeset as would have the +other ones. Further it can be used in so-called moving arguments, +because when output to an external file it uses only characters with +standard catcodes (and produces the same protected and re-tokenizable +result it would in an <code>\edef</code>.)</p> +<p>As formerly, <code>\xintexpr...\relax</code> is the preferred way to +include an expression into another one. Using <code>\xinteval</code> is +a waste because it forces the outer parser to re-digest all the digits +(or now also the square brackets).</p></li> +<li><p>The output format of <code>\xintfloateval</code> with scientific +notation has not changed (apart from possible presence of bracketed +lists), but the author hesitates because the <em>prettifying</em> it +does by default is not really adapted to display of arrays (see +<code>\xintthealign</code>). Anyway, this is configurable by the user. +It is possible to specify whether to use <code>e</code> or +<code>E</code>.</p></li> +<li><p>Function declarations are able to parse a much wider part of the +syntax, but some severe limitations remain. Refer to the user manual for +related information.</p></li> +<li><p>We have made an effort on some error messages, and when working +interactively in a shell it may even be sometimes possible to insert for +example a correct variable or function name in place of the not +recognized one. But don’t expect miracles when trying to intervene in +the midst of a purely expandable expansion…</p></li> </ul> -<h3 id="bug-fixes-10">Bug fixes</h3> -<p>Bugs? Those identified in <code>1.3f</code> were almost features. As per <code>1.4</code> the code base of <strong>xintexpr</strong> received multiple successive core refactorings and added numerous new features, and our test suite although significantly enlarged is not yet extensive enough. Please report bugs by mail.</p> +<h3 id="bug-fixes-11">Bug fixes</h3> +<p>Bugs? Those identified in <code>1.3f</code> were almost features. As +per <code>1.4</code> the code base of <strong>xintexpr</strong> received +multiple successive core refactorings and added numerous new features, +and our test suite although significantly enlarged is not yet extensive +enough. Please report bugs by mail.</p> <h3 id="todo">TODO</h3> <ul> -<li><p>The long delayed overhaul of how floating point numbers are handled is delayed again. It has remained basically identical to its initial provisory version from <code>1.07 2013/05/25</code> (which was based upon what was originally only a set of expandable macros for computations with big integers), and suffers from the author lack of knowledge of the notion of “data type” in modern programming. Indeed, he never took a CS class, and disables JavaScript in his browser (or allows only select non-tracking scripts, a rare beast in modern days).</p></li> -<li><p>Prior to integrating all of <code>NumPy</code>, it is envisioned to start with matrix algebra first.</p></li> +<li><p>The long delayed overhaul of how floating point numbers are +handled is delayed again. It has remained basically identical to its +initial provisory version from <code>1.07 2013/05/25</code> (which was +based upon what was originally only a set of expandable macros for +computations with big integers), and suffers from the author lack of +knowledge of the notion of “data type” in modern programming. Indeed, he +never took a CS class, and disables JavaScript in his browser (or allows +only select non-tracking scripts, a rare beast in modern days).</p></li> +<li><p>Prior to integrating all of <code>NumPy</code>, it is envisioned +to start with matrix algebra first.</p></li> </ul> <h2 id="f-20190910"><code>1.3f (2019/09/10)</code></h2> -<h3 id="improvements-and-new-features-1">Improvements and new features</h3> -<ul> -<li><p><strong>xintfrac</strong>: <code>\xintDigits = P;</code> syntax (i.e. without a colon) is now accepted in addition to <code>\xintDigits := P;</code>.</p> -<p>Document that the ending semi-colon can not be an active character and that it has always been allowed to use in its place a non-expanding token e.g. <code>\xintDigits := 32\relax</code>.</p> +<h3 id="improvements-and-new-features-1">Improvements and new +features</h3> +<ul> +<li><p><strong>xintfrac</strong>: <code>\xintDigits = P;</code> syntax +(i.e. without a colon) is now accepted in addition to +<code>\xintDigits := P;</code>.</p> +<p>Document that the ending semi-colon can not be an active character +and that it has always been allowed to use in its place a non-expanding +token e.g. <code>\xintDigits := 32\relax</code>.</p> <p>Add <code>\xintSetDigits</code>.</p></li> -<li><p><strong>xintexpr</strong>: add starred variants <code>\xintDigits*</code> and <code>\xintSetDigits*</code> which execute <code>\xintreloadxinttrig</code>.</p> -<p>Revert 1.3e ban on usage of <code>\xinteval</code> et al. inside expressions by <code>\xintdeffunc</code>. And make them usable also inside macro definitions via <code>\xintNewExpr</code>.</p></li> +<li><p><strong>xintexpr</strong>: add starred variants +<code>\xintDigits*</code> and <code>\xintSetDigits*</code> which execute +<code>\xintreloadxinttrig</code>.</p> +<p>Revert 1.3e ban on usage of <code>\xinteval</code> et al. inside +expressions by <code>\xintdeffunc</code>. And make them usable also +inside macro definitions via <code>\xintNewExpr</code>.</p></li> </ul> -<h3 id="bug-fixes-11">Bug fixes</h3> +<h3 id="bug-fixes-12">Bug fixes</h3> <ul> -<li><p><strong>xintexpr</strong>: fix bug preventing usage of <code>\xintdefefunc</code> to define a function without variables.</p> -<p>Fix some issue with <code>\xintfloatexpr[D]..\relax</code> if used inside an expression parsed by <code>\xintdeffunc</code> et al.</p></li> +<li><p><strong>xintexpr</strong>: fix bug preventing usage of +<code>\xintdefefunc</code> to define a function without variables.</p> +<p>Fix some issue with <code>\xintfloatexpr[D]..\relax</code> if used +inside an expression parsed by <code>\xintdeffunc</code> et al.</p></li> </ul> <h2 id="e-20190405"><code>1.3e (2019/04/05)</code></h2> -<h3 id="breaking-changes-6">Breaking changes</h3> -<ul> -<li>(<em>reverted at 1.3f</em>) When defining functions, sub-expressions can only use the <code>\xint(float)expr...\relax</code> syntax. One can not use there the <code>\xint(float)eval</code> wrappers.</li> -</ul> -<h3 id="improvements-and-new-features-2">Improvements and new features</h3> +<h3 id="breaking-changes-7">Breaking changes</h3> <ul> -<li><p>The <strong>xinttrig</strong> library is automatically loaded by <strong>xintexpr</strong>. It provides direct and inverse trigonometrical functions using either degrees or radians with a precision of up to (a bit less than) 60 digits. It is for the most part implemented using high level user interface, but will probably get some optimizations in future (and perhaps extension to more digits).</p></li> -<li><p>The <strong>xintlog</strong> library is automatically loaded by <strong>xintexpr</strong>. It uses <a href="http://ctan.org/pkg/poormanlog">poormanlog</a> to provide logarithms and exponentials with almost 9 digits of precision. Extended precision is for a future release.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintdefefunc</code>, <code>\xintdeffloatefunc</code>, <code>\xintdefiiefunc</code> define functions which are not protected against expansion in the definition of other functions; refer to <code>xint.pdf</code> for the related explanations.</p> -<p>Notice that whole area of <code>\xintdef(e)func</code>, <code>\xintNewExpr</code>, <code>\xintNewFunction</code> is complex and to be considered still as work in progress as it has a number of shortcomings.</p></li> -<li><p><strong>xintexpr</strong>: <code>inv()</code>, <code>ilog10()</code>, <code>sfloat()</code>, behaviour of <code>qfloat()</code> slightly modified.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintensuredummy</code>, <code>\xintrestorelettervar</code>.</p></li> -<li><p>The optional argument of <code>\xintfloatexpr</code> or <code>\xintfloateval</code> (it must be at start of braced argument) can be negative; it then means to trim (and round) from the output at float precision that many least significant digits.</p></li> +<li>(<em>reverted at 1.3f</em>) When defining functions, sub-expressions +can only use the <code>\xint(float)expr...\relax</code> syntax. One can +not use there the <code>\xint(float)eval</code> wrappers.</li> +</ul> +<h3 id="improvements-and-new-features-2">Improvements and new +features</h3> +<ul> +<li><p>The <strong>xinttrig</strong> library is automatically loaded by +<strong>xintexpr</strong>. It provides direct and inverse +trigonometrical functions using either degrees or radians with a +precision of up to (a bit less than) 60 digits. It is for the most part +implemented using high level user interface, but will probably get some +optimizations in future (and perhaps extension to more digits).</p></li> +<li><p>The <strong>xintlog</strong> library is automatically loaded by +<strong>xintexpr</strong>. It uses <a +href="http://ctan.org/pkg/poormanlog">poormanlog</a> to provide +logarithms and exponentials with almost 9 digits of precision. Extended +precision is for a future release.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintdefefunc</code>, +<code>\xintdeffloatefunc</code>, <code>\xintdefiiefunc</code> define +functions which are not protected against expansion in the definition of +other functions; refer to <code>xint.pdf</code> for the related +explanations.</p> +<p>Notice that whole area of <code>\xintdef(e)func</code>, +<code>\xintNewExpr</code>, <code>\xintNewFunction</code> is complex and +to be considered still as work in progress as it has a number of +shortcomings.</p></li> +<li><p><strong>xintexpr</strong>: <code>inv()</code>, +<code>ilog10()</code>, <code>sfloat()</code>, behaviour of +<code>qfloat()</code> slightly modified.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintensuredummy</code>, +<code>\xintrestorelettervar</code>.</p></li> +<li><p>The optional argument of <code>\xintfloatexpr</code> or +<code>\xintfloateval</code> (it must be at start of braced argument) can +be negative; it then means to trim (and round) from the output at float +precision that many least significant digits.</p></li> </ul> -<h3 id="bug-fixes-12">Bug fixes</h3> +<h3 id="bug-fixes-13">Bug fixes</h3> <ul> -<li>Some bugfixes related to user functions with no variables at all; they were dysfunctional.</li> +<li>Some bugfixes related to user functions with no variables at all; +they were dysfunctional.</li> </ul> <h2 id="d-20190106"><code>1.3d (2019/01/06)</code></h2> -<h3 id="breaking-changes-7">Breaking changes</h3> -<ul> -<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and <code>lcm()</code> functions formerly converted their arguments to integers via <code>\xintNum</code>. They now handle general input with no such modification.</p></li> -<li><p><strong>xintexpr</strong>: former <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> renamed to <code>\xintexpro</code>, <code>\xintiexpro</code>, <code>\xintiiexpro</code>, and <code>\xintfloatexpro</code>.</p></li> -</ul> -<h3 id="improvements-and-new-features-3">Improvements and new features</h3> +<h3 id="breaking-changes-8">Breaking changes</h3> <ul> -<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and <code>lcm()</code> multi-arguments functions have been refactored to handle general fractions. The dependency on <strong>xintgcd</strong> is removed.</p></li> -<li><p><strong>xintexpr</strong>: three-way branching <code>\xintifsgnexpr</code>, <code>\xintifsgnfloatexpr</code>, <code>\xintifsgniiexpr</code> conditional macros.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintunassignexprfunc</code>, <code>\xintunassigniiexprfunc</code>, <code>\xintunassignfloatexprfunc</code> to “undefine” functions.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintunassignvar</code> really makes the (multi-letter) variable unknown (formerly, it only gave it value zero),</p></li> -<li><p><strong>xintexpr</strong>: functions <code>isone()</code> and <code>isint()</code>.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> as synonyms to <code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</p></li> +<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and +<code>lcm()</code> functions formerly converted their arguments to +integers via <code>\xintNum</code>. They now handle general input with +no such modification.</p></li> +<li><p><strong>xintexpr</strong>: former <code>\xinteval</code>, +<code>\xintieval</code>, <code>\xintiieval</code>, and +<code>\xintfloateval</code> renamed to <code>\xintexpro</code>, +<code>\xintiexpro</code>, <code>\xintiiexpro</code>, and +<code>\xintfloatexpro</code>.</p></li> +</ul> +<h3 id="improvements-and-new-features-3">Improvements and new +features</h3> +<ul> +<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and +<code>lcm()</code> multi-arguments functions have been refactored to +handle general fractions. The dependency on <strong>xintgcd</strong> is +removed.</p></li> +<li><p><strong>xintexpr</strong>: three-way branching +<code>\xintifsgnexpr</code>, <code>\xintifsgnfloatexpr</code>, +<code>\xintifsgniiexpr</code> conditional macros.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintunassignexprfunc</code>, +<code>\xintunassigniiexprfunc</code>, +<code>\xintunassignfloatexprfunc</code> to “undefine” +functions.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintunassignvar</code> really +makes the (multi-letter) variable unknown (formerly, it only gave it +value zero),</p></li> +<li><p><strong>xintexpr</strong>: functions <code>isone()</code> and +<code>isint()</code>.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xinteval</code>, +<code>\xintieval</code>, <code>\xintiieval</code>, and +<code>\xintfloateval</code> as synonyms to +<code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) +expression as a usual braced macro argument.</p></li> </ul> -<h3 id="bug-fixes-13">Bug fixes</h3> +<h3 id="bug-fixes-14">Bug fixes</h3> <ul> -<li><strong>xintcore</strong>, <strong>xintexpr</strong> : division in <code>\xintiiexpr</code> was broken for a zero dividend and a one-digit divisor (e.g. <code>0//7</code>) since <code>1.2p</code> due to a bug in <code>\xintiiDivMod</code> for such arguments. The bug was signaled (thanks to Kpym for report) and fixed shortly after <code>1.3c</code> release but I then completely forgot to upload a bugfix release to CTAN at that time, apologies for that.</li> +<li><strong>xintcore</strong>, <strong>xintexpr</strong> : division in +<code>\xintiiexpr</code> was broken for a zero dividend and a one-digit +divisor (e.g. <code>0//7</code>) since <code>1.2p</code> due to a bug in +<code>\xintiiDivMod</code> for such arguments. The bug was signaled +(thanks to Kpym for report) and fixed shortly after <code>1.3c</code> +release but I then completely forgot to upload a bugfix release to CTAN +at that time, apologies for that.</li> </ul> <h2 id="c-20180617"><code>1.3c (2018/06/17)</code></h2> -<h3 id="improvements-and-new-features-4">Improvements and new features</h3> -<ul> -<li><p><strong>xintexpr</strong>: with <code>\xintglobaldefstrue</code>, <code>\xintdefvar</code>, <code>\xintdeffunc</code>, <code>\xintNewExpr</code> et al. make definitions with global scope.</p></li> -<li><p><strong>xintexpr</strong>: <code>qraw()</code> for fast input of (very many) comma separated numbers (in suitable raw format).</p></li> -<li><p><strong>xintexpr</strong>: the colon in the <code>:=</code> part of the syntax for <code>\xintdefvar</code> and variants is now optional; and if present it may be an active character or have any (reasonable) catcode.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>, <code>\xintdeffunc</code> and their variants try to set the catcode of the semi-colon which delimits their arguments; of course this will not work if that catcode is already frozen.</p></li> -<li><p><code>\xintUniformDeviate</code> is better documented and <code>sourcexint.pdf</code> is better hyperlinked and includes indices for the macros defined by each package.</p></li> +<h3 id="improvements-and-new-features-4">Improvements and new +features</h3> +<ul> +<li><p><strong>xintexpr</strong>: with <code>\xintglobaldefstrue</code>, +<code>\xintdefvar</code>, <code>\xintdeffunc</code>, +<code>\xintNewExpr</code> et al. make definitions with global +scope.</p></li> +<li><p><strong>xintexpr</strong>: <code>qraw()</code> for fast input of +(very many) comma separated numbers (in suitable raw format).</p></li> +<li><p><strong>xintexpr</strong>: the colon in the <code>:=</code> part +of the syntax for <code>\xintdefvar</code> and variants is now optional; +and if present it may be an active character or have any (reasonable) +catcode.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>, +<code>\xintdeffunc</code> and their variants try to set the catcode of +the semi-colon which delimits their arguments; of course this will not +work if that catcode is already frozen.</p></li> +<li><p><code>\xintUniformDeviate</code> is better documented and +<code>sourcexint.pdf</code> is better hyperlinked and includes indices +for the macros defined by each package.</p></li> </ul> -<h3 id="bug-fixes-14">Bug fixes</h3> +<h3 id="bug-fixes-15">Bug fixes</h3> <ul> -<li><strong>xintfrac</strong>: since <code>1.3</code> release, it loaded <strong>xintgcd</strong> in contradiction to what the documentation says (hence also <strong>xintexpr</strong> loaded <strong>xintgcd</strong> automatically). There is no actual dependency so the loading is removed for now.</li> +<li><strong>xintfrac</strong>: since <code>1.3</code> release, it loaded +<strong>xintgcd</strong> in contradiction to what the documentation says +(hence also <strong>xintexpr</strong> loaded <strong>xintgcd</strong> +automatically). There is no actual dependency so the loading is removed +for now.</li> </ul> <h2 id="b-20180518"><code>1.3b (2018/05/18)</code></h2> -<h3 id="improvements-and-new-features-5">Improvements and new features</h3> -<p>All additions related to randomness are marked as work-in-progress. They require an engine providing the <code>\(pdf)uniformdeviate</code> primitive.</p> -<ul> -<li><p><strong>xintkernel</strong>: <code>\xintUniformDeviate</code>.</p></li> -<li><p><strong>xint</strong>: <code>\xintRandomDigits</code>, <code>\xintXRandomDigits</code>, <code>\xintiiRandRange</code>, <code>\xintiiRandRangeAtoB</code>.</p></li> -<li><p><strong>xintfrac</strong>: support macros (not public, mainly because internal format for floats is surely not final) for <code>random()</code> and <code>qrand()</code>.</p></li> -<li><p><strong>xintexpr</strong>: <code>random()</code>, <code>qrand()</code>, and <code>randrange(A[, B])</code>.</p></li> -<li><p><strong>xintexpr</strong>: when a function <code>foo()</code> is declared via <code>\xintdeffunc</code> (et al.) to be parameter-less, it can be used as <code>foo()</code>; formerly <code>foo(nil)</code> syntax was required.</p></li> +<h3 id="improvements-and-new-features-5">Improvements and new +features</h3> +<p>All additions related to randomness are marked as work-in-progress. +They require an engine providing the <code>\(pdf)uniformdeviate</code> +primitive.</p> +<ul> +<li><p><strong>xintkernel</strong>: +<code>\xintUniformDeviate</code>.</p></li> +<li><p><strong>xint</strong>: <code>\xintRandomDigits</code>, +<code>\xintXRandomDigits</code>, <code>\xintiiRandRange</code>, +<code>\xintiiRandRangeAtoB</code>.</p></li> +<li><p><strong>xintfrac</strong>: support macros (not public, mainly +because internal format for floats is surely not final) for +<code>random()</code> and <code>qrand()</code>.</p></li> +<li><p><strong>xintexpr</strong>: <code>random()</code>, +<code>qrand()</code>, and <code>randrange(A[, B])</code>.</p></li> +<li><p><strong>xintexpr</strong>: when a function <code>foo()</code> is +declared via <code>\xintdeffunc</code> (et al.) to be parameter-less, it +can be used as <code>foo()</code>; formerly <code>foo(nil)</code> syntax +was required.</p></li> <li><p>The usual provision of user manual “improvements”.</p></li> </ul> <h2 id="a-20180307"><code>1.3a (2018/03/07)</code></h2> <h3 id="removed">Removed</h3> <ul> -<li><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>: removal of the internal macros which were used at <code>1.2o</code> to add a deprecation mechanism; all deprecated macros have been removed at <code>1.3</code> so there was no reason to keep the code used for deprecating them.</li> +<li><strong>xintcore</strong>, <strong>xint</strong>, +<strong>xintfrac</strong>: removal of the internal macros which were +used at <code>1.2o</code> to add a deprecation mechanism; all deprecated +macros have been removed at <code>1.3</code> so there was no reason to +keep the code used for deprecating them.</li> </ul> -<h3 id="improvements-and-new-features-6">Improvements and new features</h3> +<h3 id="improvements-and-new-features-6">Improvements and new +features</h3> <ul> -<li><p><strong>xintexpr</strong>: new conditionals <code>ifone()</code> and <code>ifint()</code>.</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintREZ</code> is faster on inputs having one hundred digits or more.</p></li> -<li><p>Added to the user manual mention of macros such as <code>\xintDivFloor</code>, <code>\xintMod</code>, <code>\xintModTrunc</code>, which had been left out so far.</p></li> +<li><p><strong>xintexpr</strong>: new conditionals <code>ifone()</code> +and <code>ifint()</code>.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintREZ</code> is faster on +inputs having one hundred digits or more.</p></li> +<li><p>Added to the user manual mention of macros such as +<code>\xintDivFloor</code>, <code>\xintMod</code>, +<code>\xintModTrunc</code>, which had been left out so far.</p></li> </ul> -<h3 id="bug-fixes-15">Bug fixes</h3> +<h3 id="bug-fixes-16">Bug fixes</h3> <ul> -<li><strong>xintexpr</strong>: the mechanism for adjunction to the expression parsers of user defined functions was refactored and improved at previous release <code>1.3</code>: in particular recursive definitions became possible. But an oversight made these recursive functions quite inefficient (to remain polite.) This release fixes the problem.</li> +<li><strong>xintexpr</strong>: the mechanism for adjunction to the +expression parsers of user defined functions was refactored and improved +at previous release <code>1.3</code>: in particular recursive +definitions became possible. But an oversight made these recursive +functions quite inefficient (to remain polite.) This release fixes the +problem.</li> </ul> <h2 id="section-1"><code>1.3 (2018/03/01)</code></h2> -<h3 id="breaking-changes-8">Breaking changes</h3> -<ul> -<li><p><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>: all macros deprecated at <code>1.2o</code> got removed.</p></li> -<li><p><strong>xintfrac</strong>: addition and subtraction of <code>a/b</code> and <code>c/d</code> now use the l.c.m. of the denominators. Similarly the macro supporting the modulo operator <code>/:</code> uses a l.c.m. for the denominator of the result.</p></li> -<li><p><strong>xintexpr</strong>: the addition, subtraction, modulo <code>/:</code>, and the <code>mod()</code> and <code>divmod()</code> functions produce generally smaller denominators (see previous item).</p></li> -<li><p><strong>xintexpr</strong>: formerly, the internal macros which are internally associated to user-declared functions were using comma separated parameter texts. They now do not use such commas (their meanings, which may again change in future, are written for information to the log under <code>\xintverbosetrue</code>).</p></li> -</ul> -<h3 id="improvements-and-new-features-7">Improvements and new features</h3> +<h3 id="breaking-changes-9">Breaking changes</h3> <ul> -<li><p><strong>xintexpr</strong>: user-defined functions may now be of a recursive nature. This was made possible by a refactoring of the <code>\xintNewExpr</code> mechanism. It became both leaner and more extensive than formerly.</p></li> -<li><p><strong>xintfrac</strong>: new macros <code>\xintPIrr</code> and <code>\xintDecToString</code>. The latter is a backport of a <code>polexpr 0.4</code> utility, and it is to be considered unstable.</p></li> -<li><p><strong>xintexpr</strong>: new function <code>preduce()</code> associated with <code>\xintPIrr</code>.</p></li> +<li><p><strong>xintcore</strong>, <strong>xint</strong>, +<strong>xintfrac</strong>: all macros deprecated at <code>1.2o</code> +got removed.</p></li> +<li><p><strong>xintfrac</strong>: addition and subtraction of +<code>a/b</code> and <code>c/d</code> now use the l.c.m. of the +denominators. Similarly the macro supporting the modulo operator +<code>/:</code> uses a l.c.m. for the denominator of the +result.</p></li> +<li><p><strong>xintexpr</strong>: the addition, subtraction, modulo +<code>/:</code>, and the <code>mod()</code> and <code>divmod()</code> +functions produce generally smaller denominators (see previous +item).</p></li> +<li><p><strong>xintexpr</strong>: formerly, the internal macros which +are internally associated to user-declared functions were using comma +separated parameter texts. They now do not use such commas (their +meanings, which may again change in future, are written for information +to the log under <code>\xintverbosetrue</code>).</p></li> +</ul> +<h3 id="improvements-and-new-features-7">Improvements and new +features</h3> +<ul> +<li><p><strong>xintexpr</strong>: user-defined functions may now be of a +recursive nature. This was made possible by a refactoring of the +<code>\xintNewExpr</code> mechanism. It became both leaner and more +extensive than formerly.</p></li> +<li><p><strong>xintfrac</strong>: new macros <code>\xintPIrr</code> and +<code>\xintDecToString</code>. The latter is a backport of a +<code>polexpr 0.4</code> utility, and it is to be considered +unstable.</p></li> +<li><p><strong>xintexpr</strong>: new function <code>preduce()</code> +associated with <code>\xintPIrr</code>.</p></li> </ul> <h2 id="q-20180206"><code>1.2q (2018/02/06)</code></h2> -<h3 id="improvements-and-new-features-8">Improvements and new features</h3> +<h3 id="improvements-and-new-features-8">Improvements and new +features</h3> <ul> -<li><strong>xintexpr</strong>: tacit multiplication extended to cases such as <code>3!4!5!</code> or <code>(1+2)3</code>.</li> +<li><strong>xintexpr</strong>: tacit multiplication extended to cases +such as <code>3!4!5!</code> or <code>(1+2)3</code>.</li> </ul> -<h3 id="bug-fixes-16">Bug fixes</h3> +<h3 id="bug-fixes-17">Bug fixes</h3> <ul> -<li><strong>xintcore</strong>: sadly, refactoring at <code>1.2l</code> of subtraction left an extra character in an inner macro causing breakage in some rare circumstances. This should not have escaped our test suite!</li> +<li><strong>xintcore</strong>: sadly, refactoring at <code>1.2l</code> +of subtraction left an extra character in an inner macro causing +breakage in some rare circumstances. This should not have escaped our +test suite!</li> </ul> <h2 id="p-20171205"><code>1.2p (2017/12/05)</code></h2> -<h3 id="breaking-changes-9">Breaking changes</h3> -<ul> -<li><p><strong>xintgcd</strong>: <code>\xintBezout{a}{b}</code>’s output consists of <code>{u}{v}{d}</code> with <code>u*a+v*b==d</code>, with <code>d</code> the GCD. Formerly it was <code>{a}{b}{u}{v}{d}</code>, and with <code>u*a-v*b==d</code>.</p></li> -<li><p><strong>xintgcd</strong>: <code>\xintBezout{0}{0}</code> expands to <code>{0}{0}{0}</code>. Formerly (since <code>1.2l</code>) it raised <code>InvalidOperation</code>.</p></li> -<li><p><strong>xintcore</strong>: <code>\xintiiMod</code> is now associated with floored division. The former meaning (associated with truncated division) is available as <code>\xintiiModTrunc</code>.</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintMod</code> is now associated with floored division. The former meaning is available as <code>\xintModTrunc</code>.</p></li> -<li><p><strong>xintexpr</strong>: the <code>//</code> operator and its associated modulo <code>'mod'</code> (or <code>/:</code>) now correspond to floored division, like the Python language <code>//</code>, <code>%</code>, and <code>divmod(x, y)</code>. Formerly they had been associated to truncated division. This is breaking change for operands of opposite signs.</p></li> -</ul> -<h3 id="improvements-and-new-features-9">Improvements and new features</h3> +<h3 id="breaking-changes-10">Breaking changes</h3> <ul> -<li><p><strong>xinttools</strong>: <code>\xintListWithSep</code>, which had remained unchanged since its introduction at <code>1.04 (2013/04/25)</code>, was rewritten for increased speed.</p></li> -<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>’s syntax is extended to allow simultaneous assignments. Examples: <code>\xintdefvar x1, x2, x3 := 1, 3**10, 3**20;</code> or <code>\xintdefiivar A, B := B, A 'mod' B;</code> for already defined variables <code>A</code> and <code>B</code>.</p></li> -<li><p><strong>xintexpr</strong>: added <code>divmod()</code> to the built-in functions. It is associated with floored division, like the Python language <code>divmod()</code>. Related support macros added to <strong>xintcore</strong>, and <strong>xintfrac</strong>.</p></li> +<li><p><strong>xintgcd</strong>: <code>\xintBezout{a}{b}</code>’s output +consists of <code>{u}{v}{d}</code> with <code>u*a+v*b==d</code>, with +<code>d</code> the GCD. Formerly it was <code>{a}{b}{u}{v}{d}</code>, +and with <code>u*a-v*b==d</code>.</p></li> +<li><p><strong>xintgcd</strong>: <code>\xintBezout{0}{0}</code> expands +to <code>{0}{0}{0}</code>. Formerly (since <code>1.2l</code>) it raised +<code>InvalidOperation</code>.</p></li> +<li><p><strong>xintcore</strong>: <code>\xintiiMod</code> is now +associated with floored division. The former meaning (associated with +truncated division) is available as +<code>\xintiiModTrunc</code>.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintMod</code> is now +associated with floored division. The former meaning is available as +<code>\xintModTrunc</code>.</p></li> +<li><p><strong>xintexpr</strong>: the <code>//</code> operator and its +associated modulo <code>'mod'</code> (or <code>/:</code>) now correspond +to floored division, like the Python language <code>//</code>, +<code>%</code>, and <code>divmod(x, y)</code>. Formerly they had been +associated to truncated division. This is breaking change for operands +of opposite signs.</p></li> +</ul> +<h3 id="improvements-and-new-features-9">Improvements and new +features</h3> +<ul> +<li><p><strong>xinttools</strong>: <code>\xintListWithSep</code>, which +had remained unchanged since its introduction at +<code>1.04 (2013/04/25)</code>, was rewritten for increased +speed.</p></li> +<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>’s syntax is +extended to allow simultaneous assignments. Examples: +<code>\xintdefvar x1, x2, x3 := 1, 3**10, 3**20;</code> or +<code>\xintdefiivar A, B := B, A 'mod' B;</code> for already defined +variables <code>A</code> and <code>B</code>.</p></li> +<li><p><strong>xintexpr</strong>: added <code>divmod()</code> to the +built-in functions. It is associated with floored division, like the +Python language <code>divmod()</code>. Related support macros added to +<strong>xintcore</strong>, and <strong>xintfrac</strong>.</p></li> </ul> -<h3 id="bug-fixes-17">Bug fixes</h3> +<h3 id="bug-fixes-18">Bug fixes</h3> <ul> -<li><p><strong>xintgcd</strong>: <code>\xintBezout{6}{3}</code> (for example) expanded to <code>{6}{3}{-0}{-1}{3}</code>, but the <code>-0</code> should have been <code>0</code>.</p></li> -<li><p><strong>xintgcd</strong>: it still used macro <code>\xintiAbs</code> although the latter had been deprecated from <strong>xintcore</strong>.</p></li> -<li><p><strong>xintexpr</strong>: in float expressions the <code>//</code> and <code>/:</code> (aka <code>'mod'</code>) operators did not round their operands to the float precision prior to computing with them, contrarily to other infix arithmetic operators and to the <code>mod(f,g)</code> function; thus, <code>mod(f,g)</code> and <code>f 'mod' g</code> were not completely equivalent.</p></li> -<li><p>various documentation fixes; in particular, the partial dependency of <strong>xintcfrac</strong> on <strong>xinttools</strong> had not been mentioned.</p></li> +<li><p><strong>xintgcd</strong>: <code>\xintBezout{6}{3}</code> (for +example) expanded to <code>{6}{3}{-0}{-1}{3}</code>, but the +<code>-0</code> should have been <code>0</code>.</p></li> +<li><p><strong>xintgcd</strong>: it still used macro +<code>\xintiAbs</code> although the latter had been deprecated from +<strong>xintcore</strong>.</p></li> +<li><p><strong>xintexpr</strong>: in float expressions the +<code>//</code> and <code>/:</code> (aka <code>'mod'</code>) operators +did not round their operands to the float precision prior to computing +with them, contrarily to other infix arithmetic operators and to the +<code>mod(f,g)</code> function; thus, <code>mod(f,g)</code> and +<code>f 'mod' g</code> were not completely equivalent.</p></li> +<li><p>various documentation fixes; in particular, the partial +dependency of <strong>xintcfrac</strong> on <strong>xinttools</strong> +had not been mentioned.</p></li> </ul> <h2 id="o-20170829"><code>1.2o (2017/08/29)</code></h2> -<h3 id="breaking-changes-10">Breaking changes</h3> +<h3 id="breaking-changes-11">Breaking changes</h3> <ul> -<li><strong>xint</strong>: <code>\xintAND</code>, <code>\xintOR</code>, … and similar Boolean logic macros do not apply anymore <code>\xintNum</code> (or <code>\xintRaw</code> if <strong>xintfrac</strong> is loaded), to their arguments (often, from internal usage of <code>\xintSgn</code>), but only f-expand them (using e.g. <code>\xintiiSgn</code>). This is kept un-modified even if loading <strong>xintfrac</strong>.</li> +<li><strong>xint</strong>: <code>\xintAND</code>, <code>\xintOR</code>, +… and similar Boolean logic macros do not apply anymore +<code>\xintNum</code> (or <code>\xintRaw</code> if +<strong>xintfrac</strong> is loaded), to their arguments (often, from +internal usage of <code>\xintSgn</code>), but only f-expand them (using +e.g. <code>\xintiiSgn</code>). This is kept un-modified even if loading +<strong>xintfrac</strong>.</li> </ul> <h3 id="deprecated-1">Deprecated</h3> -<p>Deprecated macros raise an error but, generally, then expand as in former releases. They will all get removed at some future release.</p> -<ul> -<li><p><strong>xintcore</strong>: <code>\xintiOpp</code>, <code>\xintiAbs</code>, <code>\xintiAdd</code>, <code>\xintiSub</code>, <code>\xintiMul</code>, <code>\xintiDivision</code>, <code>\xintiQuo</code>, <code>\xintiRem</code>, <code>\xintiDivRound</code>, <code>\xintiDivTrunc</code>, <code>\xintiMod</code>, <code>\xintiSqr</code>, <code>\xintiPow</code>, and <code>\xintiFac</code> are deprecated. Only the <code>ii</code>-named variants get defined.</p></li> -<li><p><strong>xintcore</strong>: <code>\xintCmp</code> and <code>\xintSgn</code> are deprecated from <strong>xintcore</strong> (which only defines <code>\xintiiCmp</code> and <code>\xintiiSgn</code>) as they actually belong to <strong>xintfrac</strong>.</p></li> -<li><p><strong>xintcore</strong>: <code>\xintiiFDg</code>, resp. <code>\xintiiLDg</code>, are renamed <code>\xintFDg</code>, resp. <code>\xintLDg</code>. Former denominations are deprecated.</p></li> -<li><p><strong>xint</strong>: <code>\xintMON</code>, <code>\xintMMON</code>, <code>\xintiMax</code>, <code>\xintiMin</code>, <code>\xintiMaxof</code>, <code>\xintiMinof</code>, <code>\xintiSquareRoot</code>, <code>\xintiSqrt</code>, <code>\xintiSqrtR</code>, <code>\xintiBinomial</code>, and <code>\xintiPFactorial</code> are deprecated. Only <code>ii</code>-named variants get defined.</p></li> -<li><p><strong>xint</strong>: <code>\xintEq</code>, <code>\xintGeq</code>, <code>\xintGt</code>, <code>\xintLt</code>, <code>\xintGtorEq</code>, <code>\xintLtorEq</code>, <code>\xintIsZero</code>, <code>\xintIsNotZero</code>, <code>\xintIsOne</code>, <code>\xintOdd</code>, <code>\xintEven</code>, <code>\xintifSgn</code>, <code>\xintifCmp</code>, <code>\xintifEq</code>, <code>\xintifGt</code>, <code>\xintifLt</code>, <code>\xintifZero</code>, <code>\xintifNotZero</code>, <code>\xintifOne</code>, <code>\xintifOdd</code>, are deprecated. These macros belong to <strong>xintfrac</strong>. Package <strong>xint</strong> defines only the <code>ii</code>-named variants.</p></li> -<li><p><strong>xint</strong>: <code>\xintNeq</code> was renamed to <code>\xintNotEq</code> which however is only provided by <strong>xintfrac</strong>. Package <strong>xint</strong> defines <code>\xintiiNotEq</code>, and <code>\xintNeq</code> is deprecated.</p></li> -<li><p><strong>xint</strong>: <code>\xintNot</code> was renamed to <code>\xintNOT</code>, former denomination is deprecated. See also item about Boolean logic macros in the <em>Incompatible Changes</em> section.</p></li> +<p>Deprecated macros raise an error but, generally, then expand as in +former releases. They will all get removed at some future release.</p> +<ul> +<li><p><strong>xintcore</strong>: <code>\xintiOpp</code>, +<code>\xintiAbs</code>, <code>\xintiAdd</code>, <code>\xintiSub</code>, +<code>\xintiMul</code>, <code>\xintiDivision</code>, +<code>\xintiQuo</code>, <code>\xintiRem</code>, +<code>\xintiDivRound</code>, <code>\xintiDivTrunc</code>, +<code>\xintiMod</code>, <code>\xintiSqr</code>, <code>\xintiPow</code>, +and <code>\xintiFac</code> are deprecated. Only the +<code>ii</code>-named variants get defined.</p></li> +<li><p><strong>xintcore</strong>: <code>\xintCmp</code> and +<code>\xintSgn</code> are deprecated from <strong>xintcore</strong> +(which only defines <code>\xintiiCmp</code> and <code>\xintiiSgn</code>) +as they actually belong to <strong>xintfrac</strong>.</p></li> +<li><p><strong>xintcore</strong>: <code>\xintiiFDg</code>, resp. +<code>\xintiiLDg</code>, are renamed <code>\xintFDg</code>, resp. +<code>\xintLDg</code>. Former denominations are deprecated.</p></li> +<li><p><strong>xint</strong>: <code>\xintMON</code>, +<code>\xintMMON</code>, <code>\xintiMax</code>, <code>\xintiMin</code>, +<code>\xintiMaxof</code>, <code>\xintiMinof</code>, +<code>\xintiSquareRoot</code>, <code>\xintiSqrt</code>, +<code>\xintiSqrtR</code>, <code>\xintiBinomial</code>, and +<code>\xintiPFactorial</code> are deprecated. Only <code>ii</code>-named +variants get defined.</p></li> +<li><p><strong>xint</strong>: <code>\xintEq</code>, +<code>\xintGeq</code>, <code>\xintGt</code>, <code>\xintLt</code>, +<code>\xintGtorEq</code>, <code>\xintLtorEq</code>, +<code>\xintIsZero</code>, <code>\xintIsNotZero</code>, +<code>\xintIsOne</code>, <code>\xintOdd</code>, <code>\xintEven</code>, +<code>\xintifSgn</code>, <code>\xintifCmp</code>, +<code>\xintifEq</code>, <code>\xintifGt</code>, <code>\xintifLt</code>, +<code>\xintifZero</code>, <code>\xintifNotZero</code>, +<code>\xintifOne</code>, <code>\xintifOdd</code>, are deprecated. These +macros belong to <strong>xintfrac</strong>. Package +<strong>xint</strong> defines only the <code>ii</code>-named +variants.</p></li> +<li><p><strong>xint</strong>: <code>\xintNeq</code> was renamed to +<code>\xintNotEq</code> which however is only provided by +<strong>xintfrac</strong>. Package <strong>xint</strong> defines +<code>\xintiiNotEq</code>, and <code>\xintNeq</code> is +deprecated.</p></li> +<li><p><strong>xint</strong>: <code>\xintNot</code> was renamed to +<code>\xintNOT</code>, former denomination is deprecated. See also item +about Boolean logic macros in the <em>Incompatible Changes</em> +section.</p></li> </ul> <h2 id="n-20170806"><code>1.2n (2017/08/06)</code></h2> -<h3 id="breaking-changes-11">Breaking changes</h3> +<h3 id="breaking-changes-12">Breaking changes</h3> <ul> -<li><strong>xintbinhex</strong> does not load package <strong>xintcore</strong> anymore, but only <strong>xintkernel</strong>.</li> +<li><strong>xintbinhex</strong> does not load package +<strong>xintcore</strong> anymore, but only +<strong>xintkernel</strong>.</li> </ul> -<h3 id="improvements-and-new-features-10">Improvements and new features</h3> +<h3 id="improvements-and-new-features-10">Improvements and new +features</h3> <ul> -<li><p><strong>xintbinhex</strong> has only <strong>xintkernel</strong> as dependency.</p></li> -<li><p>Macros of <strong>xintbinhex</strong> have been improved for speed and increased maximal sizes of allowable inputs.</p></li> +<li><p><strong>xintbinhex</strong> has only <strong>xintkernel</strong> +as dependency.</p></li> +<li><p>Macros of <strong>xintbinhex</strong> have been improved for +speed and increased maximal sizes of allowable inputs.</p></li> </ul> <h2 id="m-20170731"><code>1.2m (2017/07/31)</code></h2> -<h3 id="breaking-changes-12">Breaking changes</h3> +<h3 id="breaking-changes-13">Breaking changes</h3> <ul> -<li><p><strong>xintbinhex</strong>: the length of the input is now limited. The maximum size depends on the macro and ranges from about <code>4000</code> to about <code>19900</code> digits.</p></li> -<li><p><strong>xintbinhex</strong>: <code>\xintCHexToBin</code> is now the variant of <code>\xintHexToBin</code> which does not remove leading binary zeroes: <code>N</code> hex-digits give on output exactly <code>4N</code> binary digits.</p></li> +<li><p><strong>xintbinhex</strong>: the length of the input is now +limited. The maximum size depends on the macro and ranges from about +<code>4000</code> to about <code>19900</code> digits.</p></li> +<li><p><strong>xintbinhex</strong>: <code>\xintCHexToBin</code> is now +the variant of <code>\xintHexToBin</code> which does not remove leading +binary zeroes: <code>N</code> hex-digits give on output exactly +<code>4N</code> binary digits.</p></li> </ul> -<h3 id="improvements-and-new-features-11">Improvements and new features</h3> +<h3 id="improvements-and-new-features-11">Improvements and new +features</h3> <ul> -<li><strong>xintbinhex</strong>: all macros have been rewritten using techniques from the 1.2 release (they had remained unmodified since <code>1.08</code> of <code>2013/06/07</code>.) The new macros are faster but limited to a few thousand digits. The <code>1.08</code> routines could handle tens of thousands of digits, but not in a reasonable time.</li> +<li><strong>xintbinhex</strong>: all macros have been rewritten using +techniques from the 1.2 release (they had remained unmodified since +<code>1.08</code> of <code>2013/06/07</code>.) The new macros are faster +but limited to a few thousand digits. The <code>1.08</code> routines +could handle tens of thousands of digits, but not in a reasonable +time.</li> </ul> -<h3 id="bug-fixes-18">Bug fixes</h3> +<h3 id="bug-fixes-19">Bug fixes</h3> <ul> -<li><p>user manual: the <code>Changes</code> section wrongly stated at <code>1.2l</code> that the macros of <strong>xintbinhex</strong> had been made robust against non terminated input such as <code>\number\mathcode`\-</code>. Unfortunately the author fell into the trap of believing his own documentation and he forgot to actually implement the change. Now done.</p></li> +<li><p>user manual: the <code>Changes</code> section wrongly stated at +<code>1.2l</code> that the macros of <strong>xintbinhex</strong> had +been made robust against non terminated input such as +<code>\number\mathcode`\-</code>. Unfortunately the author fell into the +trap of believing his own documentation and he forgot to actually +implement the change. Now done.</p></li> <li><p>user manual: the PDF bookmarks were messed up.</p></li> -<li><p><strong>xint</strong>, <strong>xintfrac</strong>: <code>\xintGeq</code>, <code>\xintMax</code>, <code>\xintMin</code>, suffered from some extra overhead. This was caused by use of some auxiliaries from the very early days which got redefined at some stage. This is fixed here with some additional efficiency improvements and pruning of old code.</p></li> +<li><p><strong>xint</strong>, <strong>xintfrac</strong>: +<code>\xintGeq</code>, <code>\xintMax</code>, <code>\xintMin</code>, +suffered from some extra overhead. This was caused by use of some +auxiliaries from the very early days which got redefined at some stage. +This is fixed here with some additional efficiency improvements and +pruning of old code.</p></li> </ul> <h2 id="l-20170726"><code>1.2l (2017/07/26)</code></h2> <h3 id="removed-1">Removed</h3> <ul> -<li><p><code>\xintiiSumExpr</code>, <code>\xintiiPrdExpr</code> (<strong>xint</strong>) and <code>\xintSumExpr</code>, <code>\xintPrdExpr</code> (<strong>xintfrac</strong>). They had not been formally deprecated, but had been left un-documented since <code>1.09d (2013/10/22)</code>.</p></li> -<li><p>internal macro <code>\xint_gob_til_xint_relax</code> removed.</p></li> +<li><p><code>\xintiiSumExpr</code>, <code>\xintiiPrdExpr</code> +(<strong>xint</strong>) and <code>\xintSumExpr</code>, +<code>\xintPrdExpr</code> (<strong>xintfrac</strong>). They had not been +formally deprecated, but had been left un-documented since +<code>1.09d (2013/10/22)</code>.</p></li> +<li><p>internal macro <code>\xint_gob_til_xint_relax</code> +removed.</p></li> +</ul> +<h3 id="improvements-and-new-features-12">Improvements and new +features</h3> +<ul> +<li><p>the underscore character <code>_</code> is accepted by the +<strong>xintexpr</strong> parsers as a digit separator (the space +character already could be used for improved readability of big +numbers). It is not allowed as <em>first</em> character of a number, as +it would then be mis-interpreted as the start of a possible variable +name.</p></li> +<li><p>some refactoring in <strong>xintcore</strong> auxiliary routines +and in <code>\xintiiSub</code> and <code>\xintiiCmp</code> for some +small efficiency gains.</p></li> +<li><p>code comments in <strong>xintcore</strong> are better formatted, +but remain sparse.</p></li> +<li><p><strong>xintcore</strong>, <strong>xint</strong>, +<strong>xintfrac</strong>, … : some macros were not robust against +arguments whose expansion looks forward for some termination +(e.g. <code>\number\mathcode`\-</code>), and particularly, most were +fragile against inputs using non-terminated <code>\numexpr</code> (such +as <code>\xintiiAdd{\the\numexpr1}{2}</code> or +<code>\xintRaw{\numexpr1}</code>). This was not a bug per se, as the +user manual did not claim such inputs were legal, but it was slightly +inconvenient. Most macros (particularly those of +<strong>xintfrac</strong>) have now been made robust against such +inputs. Some macros from <strong>xintcore</strong> primarily destined to +internal usage still accept only properly terminated arguments such as +<code>\the\mathcode`\-<space></code> or +<code>\the\numexpr1\relax</code>.</p> +<p>The situation with expressions is unchanged: syntax such as +<code>\xintexpr \numexpr1+2\relax</code> is illegal as the ending +<code>\relax</code> token will get swallowed by the +<code>\numexpr</code>; but it is needed by the +<code>xintexpr</code>-ession parser, hence the parser will expand +forward and presumably end with in an “illegal token” error, or provoke +some low-level TeX error (N.B.: a closing brace <code>}</code> for +example can not terminate an <code>xintexpr</code>-ession, the parser +must find a <code>\relax</code> token at some point). Thus there must be +in this example a second <code>\relax</code>.</p></li> +<li><p>experimental code for error conditions; there is no complete user +interface yet, it is done in preparation for next major release and is +completely unstable and undocumented.</p></li> </ul> -<h3 id="improvements-and-new-features-12">Improvements and new features</h3> -<ul> -<li><p>the underscore character <code>_</code> is accepted by the <strong>xintexpr</strong> parsers as a digit separator (the space character already could be used for improved readability of big numbers). It is not allowed as <em>first</em> character of a number, as it would then be mis-interpreted as the start of a possible variable name.</p></li> -<li><p>some refactoring in <strong>xintcore</strong> auxiliary routines and in <code>\xintiiSub</code> and <code>\xintiiCmp</code> for some small efficiency gains.</p></li> -<li><p>code comments in <strong>xintcore</strong> are better formatted, but remain sparse.</p></li> -<li><p><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>, … : some macros were not robust against arguments whose expansion looks forward for some termination (e.g. <code>\number\mathcode`\-</code>), and particularly, most were fragile against inputs using non-terminated <code>\numexpr</code> (such as <code>\xintiiAdd{\the\numexpr1}{2}</code> or <code>\xintRaw{\numexpr1}</code>). This was not a bug per se, as the user manual did not claim such inputs were legal, but it was slightly inconvenient. Most macros (particularly those of <strong>xintfrac</strong>) have now been made robust against such inputs. Some macros from <strong>xintcore</strong> primarily destined to internal usage still accept only properly terminated arguments such as <code>\the\mathcode`\-<space></code> or <code>\the\numexpr1\relax</code>.</p> -<p>The situation with expressions is unchanged: syntax such as <code>\xintexpr \numexpr1+2\relax</code> is illegal as the ending <code>\relax</code> token will get swallowed by the <code>\numexpr</code>; but it is needed by the <code>xintexpr</code>-ession parser, hence the parser will expand forward and presumably end with in an “illegal token” error, or provoke some low-level TeX error (N.B.: a closing brace <code>}</code> for example can not terminate an <code>xintexpr</code>-ession, the parser must find a <code>\relax</code> token at some point). Thus there must be in this example a second <code>\relax</code>.</p></li> -<li><p>experimental code for error conditions; there is no complete user interface yet, it is done in preparation for next major release and is completely unstable and undocumented.</p></li> -</ul> -<h3 id="bug-fixes-19">Bug fixes</h3> +<h3 id="bug-fixes-20">Bug fixes</h3> <ul> -<li><p><strong>xintbinhex</strong>: since <code>1.2 (2015/10/10)</code>, <code>\xintHexToDec</code> was broken due to an undefined macro (it was in <code>xint.sty</code>, but the module by itself is supposedly dependent only upon <code>xintcore.sty</code>).</p></li> -<li><p><strong>xintgcd</strong>: macro <code>\xintBezout</code> produced partially wrong output if one of its two arguments was zero.</p></li> -<li><p><strong>xintfrac</strong>: the manual said one could use directly <code>\numexpr</code> compatible expressions in arithmetic macros (without even a <code>\numexpr</code> encapsulation) if they were expressed with up to 8 tokens. There was a bug if these 8 tokens evaluated to zero. The bug has been fixed, and up to 9 tokens are now accepted. But it is simpler to use <code>\the\numexpr</code> prefix and not to worry about the token count… The ending <code>\relax</code> is now un-needed.</p></li> +<li><p><strong>xintbinhex</strong>: since <code>1.2 (2015/10/10)</code>, +<code>\xintHexToDec</code> was broken due to an undefined macro (it was +in <code>xint.sty</code>, but the module by itself is supposedly +dependent only upon <code>xintcore.sty</code>).</p></li> +<li><p><strong>xintgcd</strong>: macro <code>\xintBezout</code> produced +partially wrong output if one of its two arguments was zero.</p></li> +<li><p><strong>xintfrac</strong>: the manual said one could use directly +<code>\numexpr</code> compatible expressions in arithmetic macros +(without even a <code>\numexpr</code> encapsulation) if they were +expressed with up to 8 tokens. There was a bug if these 8 tokens +evaluated to zero. The bug has been fixed, and up to 9 tokens are now +accepted. But it is simpler to use <code>\the\numexpr</code> prefix and +not to worry about the token count… The ending <code>\relax</code> is +now un-needed.</p></li> </ul> <h2 id="k-20170106"><code>1.2k (2017/01/06)</code></h2> -<h3 id="breaking-changes-13">Breaking changes</h3> -<ul> -<li><p>macro <code>\xintFloat</code> which rounds its input to a floating point number does <em>not</em> print anymore <code>10.0...0eN</code> to signal an upwards rounding to the next power of ten. The mantissa has in all cases except the zero input exactly one digit before the decimal mark.</p></li> -<li><p>some floating point computations may differ in the least significant digits, due to a change in the rounding algorithm applied to macro arguments expressed as fractions and to an improvement in precision regarding half-integer powers in expressions. See next.</p></li> -</ul> -<h3 id="improvements-and-new-features-13">Improvements and new features</h3> +<h3 id="breaking-changes-14">Breaking changes</h3> <ul> -<li><p>the initial rounding to the target precision <code>P</code> which is applied by the floating point macros from <strong>xintfrac</strong> to their arguments achieves the <em>exact (aka correct) rounding</em> even for inputs which are fractions with more than <code>P+2</code> digits in their numerators and denominators (<code>>1</code>.) Hence the computed values depend only on the arguments as rational numbers and not upon their representatives. This is not relevant to <em>expressions</em> (<strong>xintexpr</strong>), because the <code>\xintfloatexpr</code> parser sees there <code>/</code> as an operator and does not (apart from special constructs) get to manipulate fractions as such.</p></li> -<li><p><code>\xintnewdummy</code> is public interface to a <code>1.2e</code> macro which serves to declare any given catcode 11 character as a dummy variable for expressions (<strong>xintexpr</strong>). This is useful for Unicode engines (the Latin letters being already all pre-declared as dummy variables.)</p></li> -<li><p>added <code>\xintiSqrtR</code>, there was only <code>\xintiiSqrtR</code> alongside <code>\xintiSqrt</code> and <code>\xintiiSqrt</code> (<strong>xint</strong>).</p></li> -<li><p>added non public <code>\xintLastItem:f:csv</code> to <strong>xinttools</strong> for faster <code>last()</code> function, and improved <code>\xintNewExpr</code> compatibility. Also <code>\xintFirstItem:f:csv</code>.</p></li> +<li><p>macro <code>\xintFloat</code> which rounds its input to a +floating point number does <em>not</em> print anymore +<code>10.0...0eN</code> to signal an upwards rounding to the next power +of ten. The mantissa has in all cases except the zero input exactly one +digit before the decimal mark.</p></li> +<li><p>some floating point computations may differ in the least +significant digits, due to a change in the rounding algorithm applied to +macro arguments expressed as fractions and to an improvement in +precision regarding half-integer powers in expressions. See +next.</p></li> +</ul> +<h3 id="improvements-and-new-features-13">Improvements and new +features</h3> +<ul> +<li><p>the initial rounding to the target precision <code>P</code> which +is applied by the floating point macros from <strong>xintfrac</strong> +to their arguments achieves the <em>exact (aka correct) rounding</em> +even for inputs which are fractions with more than <code>P+2</code> +digits in their numerators and denominators (<code>>1</code>.) Hence +the computed values depend only on the arguments as rational numbers and +not upon their representatives. This is not relevant to +<em>expressions</em> (<strong>xintexpr</strong>), because the +<code>\xintfloatexpr</code> parser sees there <code>/</code> as an +operator and does not (apart from special constructs) get to manipulate +fractions as such.</p></li> +<li><p><code>\xintnewdummy</code> is public interface to a +<code>1.2e</code> macro which serves to declare any given catcode 11 +character as a dummy variable for expressions +(<strong>xintexpr</strong>). This is useful for Unicode engines (the +Latin letters being already all pre-declared as dummy +variables.)</p></li> +<li><p>added <code>\xintiSqrtR</code>, there was only +<code>\xintiiSqrtR</code> alongside <code>\xintiSqrt</code> and +<code>\xintiiSqrt</code> (<strong>xint</strong>).</p></li> +<li><p>added non public <code>\xintLastItem:f:csv</code> to +<strong>xinttools</strong> for faster <code>last()</code> function, and +improved <code>\xintNewExpr</code> compatibility. Also +<code>\xintFirstItem:f:csv</code>.</p></li> </ul> -<h3 id="bug-fixes-20">Bug fixes</h3> +<h3 id="bug-fixes-21">Bug fixes</h3> <ul> -<li><p>the <code>1.2f</code> half-integer powers computed within <code>\xintfloatexpr</code> had a silly rounding to the target precision just <em>before</em> the final square-root extraction, thus possibly losing some precision. The <code>1.2k</code> implementation keeps guard digits for this final square root extraction. As for integer exponents, it is guaranteed that the computed value differs from the exact one by less than <code>0.52 ulp</code> (for inputs having at most <code>\xinttheDigits</code> digits.)</p></li> -<li><p>more regressions from <code>1.2i</code> were fixed: <code>\xintLen</code> (<strong>xint</strong>, <strong>xintfrac</strong>) and <code>\xintDouble</code> (<strong>xintcore</strong>) had forgotten that their argument was allowed to be negative. A regression test suite is now in place and is being slowly expanded to cover more macros.</p></li> -<li><p><code>\xintiiSquareRoot{0}</code> now produces <code>{1}{1}</code>, which fits better the general documented behaviour of this macro than <code>11</code>.</p></li> +<li><p>the <code>1.2f</code> half-integer powers computed within +<code>\xintfloatexpr</code> had a silly rounding to the target precision +just <em>before</em> the final square-root extraction, thus possibly +losing some precision. The <code>1.2k</code> implementation keeps guard +digits for this final square root extraction. As for integer exponents, +it is guaranteed that the computed value differs from the exact one by +less than <code>0.52 ulp</code> (for inputs having at most +<code>\xinttheDigits</code> digits.)</p></li> +<li><p>more regressions from <code>1.2i</code> were fixed: +<code>\xintLen</code> (<strong>xint</strong>, <strong>xintfrac</strong>) +and <code>\xintDouble</code> (<strong>xintcore</strong>) had forgotten +that their argument was allowed to be negative. A regression test suite +is now in place and is being slowly expanded to cover more +macros.</p></li> +<li><p><code>\xintiiSquareRoot{0}</code> now produces +<code>{1}{1}</code>, which fits better the general documented behaviour +of this macro than <code>11</code>.</p></li> </ul> <h2 id="j-20161222"><code>1.2j (2016/12/22)</code></h2> -<h3 id="improvements-and-new-features-14">Improvements and new features</h3> +<h3 id="improvements-and-new-features-14">Improvements and new +features</h3> <ul> <li><p><strong>xinttools</strong> and <strong>xintexpr</strong>:</p> <ol type="1"> <li><p>slightly improves the speed of <code>\xintTrim</code>.</p></li> -<li><p>speed gains for the handlers of comma separated lists implementing Python-like slicing and item extraction. Relevant non (user) documented macros better documented in <code>sourcexint.pdf</code>.</p></li> +<li><p>speed gains for the handlers of comma separated lists +implementing Python-like slicing and item extraction. Relevant non +(user) documented macros better documented in +<code>sourcexint.pdf</code>.</p></li> </ol></li> -<li><p>significant documentations tweaks (inclusive of suppressing things!), and among them two beautiful hyperlinked tables with both horizontal and vertical rules which bring the documentation of the <strong>xintexpr</strong> syntax to a kind of awe-inspiring perfection… except that implementation of some math functions is still lacking.</p></li> +<li><p>significant documentations tweaks (inclusive of suppressing +things!), and among them two beautiful hyperlinked tables with both +horizontal and vertical rules which bring the documentation of the +<strong>xintexpr</strong> syntax to a kind of awe-inspiring perfection… +except that implementation of some math functions is still +lacking.</p></li> </ul> -<h3 id="bug-fixes-21">Bug fixes</h3> +<h3 id="bug-fixes-22">Bug fixes</h3> <ul> -<li>fix two <code>1.2i</code> regressions caused by undefined macros (<code>\xintNthElt</code> in certain branches and <code>[list][N]</code> item extraction in certain cases.) The test files existed but were not executed prior to release. Automation in progress.</li> +<li>fix two <code>1.2i</code> regressions caused by undefined macros +(<code>\xintNthElt</code> in certain branches and <code>[list][N]</code> +item extraction in certain cases.) The test files existed but were not +executed prior to release. Automation in progress.</li> </ul> <h2 id="i-20161213"><code>1.2i (2016/12/13)</code></h2> -<h3 id="breaking-changes-14">Breaking changes</h3> +<h3 id="breaking-changes-15">Breaking changes</h3> <ul> -<li><code>\xintDecSplit</code> second argument must have no sign (former code replaced it with its absolute value, a sign now may cause an error.)</li> +<li><code>\xintDecSplit</code> second argument must have no sign (former +code replaced it with its absolute value, a sign now may cause an +error.)</li> </ul> <h3 id="removed-2">Removed</h3> <ul> -<li>deprecated macros <code>\xintifTrue</code>, <code>\xintifTrueFalse</code>, <code>\xintQuo</code>, <code>\xintRem</code>, <code>\xintquo</code>, <code>\xintrem</code>.</li> +<li>deprecated macros <code>\xintifTrue</code>, +<code>\xintifTrueFalse</code>, <code>\xintQuo</code>, +<code>\xintRem</code>, <code>\xintquo</code>, +<code>\xintrem</code>.</li> </ul> -<h3 id="improvements-and-new-features-15">Improvements and new features</h3> +<h3 id="improvements-and-new-features-15">Improvements and new +features</h3> <ul> -<li><p><strong>xintkernel</strong>: <code>\xintLength</code> is faster. New macros:</p> +<li><p><strong>xintkernel</strong>: <code>\xintLength</code> is faster. +New macros:</p> <ul> -<li><p><code>\xintLastItem</code> to fetch the last item from its argument,</p></li> -<li><p><code>\romannumeral\xintgobble</code> for gobbling many (up to 531440) upstream braced items or tokens.</p></li> -<li><p><code>\romannumeral\xintreplicate</code> which is copied over from the expl3 <code>\prg_replicate:nn</code> with some minor changes.</p></li> +<li><p><code>\xintLastItem</code> to fetch the last item from its +argument,</p></li> +<li><p><code>\romannumeral\xintgobble</code> for gobbling many (up to +531440) upstream braced items or tokens.</p></li> +<li><p><code>\romannumeral\xintreplicate</code> which is copied over +from the expl3 <code>\prg_replicate:nn</code> with some minor +changes.</p></li> </ul></li> -<li><p><strong>xinttools</strong>: general token list handling routines <code>\xintKeep</code>, <code>\xintTrim</code> and <code>\xintNthElt</code> are faster; but the novel <code>\xintTrim</code> can only remove up to a maximum of 531440 items.</p> -<p>Also, <code>\xintFor</code> partially improves on some issues which are reported upon in the documentation.</p></li> -<li><p>some old macros have been rewritten entirely or partially using techniques which <strong>xint</strong> started using in release <code>1.2</code>:</p> -<ul> -<li><p><strong>xintcore</strong>: <code>\xintDouble</code>, <code>\xintHalf</code>, <code>\xintInc</code>, <code>\xintDec</code>, <code>\xintiiLDg</code>, <code>\xintDSR</code> (originally from <strong>xint</strong>), a novel <code>\xintDSRr</code>.</p></li> -<li><p><strong>xint</strong>: <code>\xintDSH</code>, <code>\xintDSx</code>, <code>\xintDecSplit</code>, <code>\xintiiE</code>.</p></li> -<li><p><strong>xintfrac</strong>: as a result of the above <code>\xintTrunc</code>, <code>\xintRound</code> and <code>\xintXTrunc</code> got faster. But the main improvement for them is with decimal inputs which formerly had not been treated separately from the general fraction case. Also, <code>\xintXTrunc</code> does not anymore create a dependency of <strong>xintfrac</strong> on <strong>xinttools</strong>.</p></li> +<li><p><strong>xinttools</strong>: general token list handling routines +<code>\xintKeep</code>, <code>\xintTrim</code> and +<code>\xintNthElt</code> are faster; but the novel +<code>\xintTrim</code> can only remove up to a maximum of 531440 +items.</p> +<p>Also, <code>\xintFor</code> partially improves on some issues which +are reported upon in the documentation.</p></li> +<li><p>some old macros have been rewritten entirely or partially using +techniques which <strong>xint</strong> started using in release +<code>1.2</code>:</p> +<ul> +<li><p><strong>xintcore</strong>: <code>\xintDouble</code>, +<code>\xintHalf</code>, <code>\xintInc</code>, <code>\xintDec</code>, +<code>\xintiiLDg</code>, <code>\xintDSR</code> (originally from +<strong>xint</strong>), a novel <code>\xintDSRr</code>.</p></li> +<li><p><strong>xint</strong>: <code>\xintDSH</code>, +<code>\xintDSx</code>, <code>\xintDecSplit</code>, +<code>\xintiiE</code>.</p></li> +<li><p><strong>xintfrac</strong>: as a result of the above +<code>\xintTrunc</code>, <code>\xintRound</code> and +<code>\xintXTrunc</code> got faster. But the main improvement for them +is with decimal inputs which formerly had not been treated separately +from the general fraction case. Also, <code>\xintXTrunc</code> does not +anymore create a dependency of <strong>xintfrac</strong> on +<strong>xinttools</strong>.</p></li> </ul></li> -<li><p>the documentation has again been (slightly) re-organized; it has a new sub-section on the Miller-Rabin primality test, to illustrate some use of <code>\xintNewFunction</code> for recursive definitions.</p></li> -<li><p>the documentation has dropped the LaTeX “command” terminology (which had been used initially in 2013 for some forgotten reasons and should have been removed long ago) and uses only the more apt “macro”, as after all, all of <strong>xint</strong> is about expansion of macros (plus the use of <code>\numexpr</code>).</p></li> +<li><p>the documentation has again been (slightly) re-organized; it has +a new sub-section on the Miller-Rabin primality test, to illustrate some +use of <code>\xintNewFunction</code> for recursive definitions.</p></li> +<li><p>the documentation has dropped the LaTeX “command” terminology +(which had been used initially in 2013 for some forgotten reasons and +should have been removed long ago) and uses only the more apt “macro”, +as after all, all of <strong>xint</strong> is about expansion of macros +(plus the use of <code>\numexpr</code>).</p></li> </ul> -<h3 id="bug-fixes-22">Bug fixes</h3> +<h3 id="bug-fixes-23">Bug fixes</h3> <ul> -<li><code>\xintDecSplitL</code> and <code>\xintDecSplitR</code> from <strong>xint</strong> produced their output in a spurious brace pair (bug introduced in <code>1.2f</code>).</li> +<li><code>\xintDecSplitL</code> and <code>\xintDecSplitR</code> from +<strong>xint</strong> produced their output in a spurious brace pair +(bug introduced in <code>1.2f</code>).</li> </ul> <h2 id="h-20161120"><code>1.2h (2016/11/20)</code></h2> -<h3 id="improvements-and-new-features-16">Improvements and new features</h3> -<ul> -<li><p>new macro <code>\xintNewFunction</code> in <strong>xintexpr</strong> which allows to extend the parser syntax with functions in situations where <code>\xintdeffunc</code> is not usable (typically, because dummy variables are used over a not yet determined range of values because it depends on the variables).</p></li> -<li><p>after three years of strict obedience to <code>xint</code> prefix, now <code>\thexintexpr</code>, <code>\thexintiexpr</code>, <code>\thexintfloatexpr</code>, and <code>\thexintiiexpr</code> are provided as synonyms to <code>\xinttheexpr</code>, etc…</p></li> +<h3 id="improvements-and-new-features-16">Improvements and new +features</h3> +<ul> +<li><p>new macro <code>\xintNewFunction</code> in +<strong>xintexpr</strong> which allows to extend the parser syntax with +functions in situations where <code>\xintdeffunc</code> is not usable +(typically, because dummy variables are used over a not yet determined +range of values because it depends on the variables).</p></li> +<li><p>after three years of strict obedience to <code>xint</code> +prefix, now <code>\thexintexpr</code>, <code>\thexintiexpr</code>, +<code>\thexintfloatexpr</code>, and <code>\thexintiiexpr</code> are +provided as synonyms to <code>\xinttheexpr</code>, etc…</p></li> </ul> -<h3 id="bug-fixes-23">Bug fixes</h3> +<h3 id="bug-fixes-24">Bug fixes</h3> <ul> -<li><p>the <code>(cond)?{foo}{bar}</code> operator from <strong>xintexpr</strong> mis-behaved in certain circumstances (such as an empty <code>foo</code>).</p></li> -<li><p>the <strong>xintexpr</strong> <code>1.2f</code> <code>binomial</code> function (which uses <code>\xintiiBinomial</code> from <strong>xint.sty</strong> or <code>\xintFloatBinomial</code> from <strong>xintfrac.sty</strong>) deliberately raised an error for <code>binomial(x,y)</code> with <code>y<0</code> or <code>x<y</code>. This was unfortunate, and it now simply evaluates to zero in such cases.</p></li> -<li><p>similarly the <code>pfactorial</code> function was very strict and <code>pfactorial(x,y)</code> deliberately raised an out-of-range error if not used with non-negative integers with <code>x</code> less than <code>y</code>. It now avoids doing that and allows negative arguments.</p></li> -<li><p>the <code>add</code> and <code>mul</code> from <strong>xintexpr</strong>, which work with dummy variables since <code>1.1</code>, raised an error since <code>1.2c 2015/11/16</code> when the dummy variable was given an empty range (or list) of values, rather than producing respectively <code>0</code> and <code>1</code> as formerly.</p></li> +<li><p>the <code>(cond)?{foo}{bar}</code> operator from +<strong>xintexpr</strong> mis-behaved in certain circumstances (such as +an empty <code>foo</code>).</p></li> +<li><p>the <strong>xintexpr</strong> <code>1.2f</code> +<code>binomial</code> function (which uses <code>\xintiiBinomial</code> +from <strong>xint.sty</strong> or <code>\xintFloatBinomial</code> from +<strong>xintfrac.sty</strong>) deliberately raised an error for +<code>binomial(x,y)</code> with <code>y<0</code> or +<code>x<y</code>. This was unfortunate, and it now simply evaluates +to zero in such cases.</p></li> +<li><p>similarly the <code>pfactorial</code> function was very strict +and <code>pfactorial(x,y)</code> deliberately raised an out-of-range +error if not used with non-negative integers with <code>x</code> less +than <code>y</code>. It now avoids doing that and allows negative +arguments.</p></li> +<li><p>the <code>add</code> and <code>mul</code> from +<strong>xintexpr</strong>, which work with dummy variables since +<code>1.1</code>, raised an error since <code>1.2c 2015/11/16</code> +when the dummy variable was given an empty range (or list) of values, +rather than producing respectively <code>0</code> and <code>1</code> as +formerly.</p></li> </ul> <h2 id="g-20160319"><code>1.2g (2016/03/19)</code></h2> -<h3 id="breaking-changes-15">Breaking changes</h3> -<ul> -<li><p>inside expressions, list item selector <code>[L][n]</code> counts starting at zero, not at one. This is more coherent with <code>[L][a:b]</code> which was already exactly like in Python since its introduction. A function len(L) replaces earlier <code>[L][0]</code>.</p></li> -<li><p>former <code>iter</code> keyword now called <code>iterr</code>. Indeed it matched with <code>rrseq</code>, the new <code>iter</code> (which was somehow missing from <code>1.1</code>) is the one matching <code>rseq</code>. Allows to iterate more easily with a “list” variable.</p></li> -</ul> -<h3 id="improvements-and-new-features-17">Improvements and new features</h3> -<ul> -<li><p>in <strong>xintexpr.sty</strong>: list selectors <code>[L][n]</code> and <code>[L][a:b]</code> are more efficient: the earlier <code>1.1</code> routines did back and forth conversions from comma separated values to braced tokens, the <code>1.2g</code> routines use macros from <strong>xinttools.sty</strong> handling directly the encountered lists of comma separated values.</p></li> -<li><p>in <strong>xinttools.sty</strong>: slight improvements in the efficiency of the <code>\xintNthElt</code>, <code>\xintKeep</code>, <code>\xintTrim</code> routines and new routines handling directly comma separated values. The latter are not included in the user manual (they are not <code>\long</code>, they don’t make efforts to preserve some braces, do not worry about spaces, all those worries being irrelevant to the use in expressions for list selectors).</p></li> -<li><p>a slight speed improvement to <code>\xintFloatSqrt</code> in its quest of correct rounding.</p></li> -<li><p>float multiplication and division handle more swiftly operands (non-fractional) with few digits, when the float precision is large.</p></li> -<li><p>the syntax of expressions is described in a devoted chapter of the documentation; an example shows how to implement (expandably) the Brent-Salamin algorithm for computation of Pi using <code>iter</code> in a float expression.</p></li> -</ul> -<h2 id="f-20160312"><code>1.2f (2016/03/12)</code></h2> <h3 id="breaking-changes-16">Breaking changes</h3> <ul> -<li>no more <code>\xintFac</code> macro but <code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li> +<li><p>inside expressions, list item selector <code>[L][n]</code> counts +starting at zero, not at one. This is more coherent with +<code>[L][a:b]</code> which was already exactly like in Python since its +introduction. A function len(L) replaces earlier +<code>[L][0]</code>.</p></li> +<li><p>former <code>iter</code> keyword now called <code>iterr</code>. +Indeed it matched with <code>rrseq</code>, the new <code>iter</code> +(which was somehow missing from <code>1.1</code>) is the one matching +<code>rseq</code>. Allows to iterate more easily with a “list” +variable.</p></li> +</ul> +<h3 id="improvements-and-new-features-17">Improvements and new +features</h3> +<ul> +<li><p>in <strong>xintexpr.sty</strong>: list selectors +<code>[L][n]</code> and <code>[L][a:b]</code> are more efficient: the +earlier <code>1.1</code> routines did back and forth conversions from +comma separated values to braced tokens, the <code>1.2g</code> routines +use macros from <strong>xinttools.sty</strong> handling directly the +encountered lists of comma separated values.</p></li> +<li><p>in <strong>xinttools.sty</strong>: slight improvements in the +efficiency of the <code>\xintNthElt</code>, <code>\xintKeep</code>, +<code>\xintTrim</code> routines and new routines handling directly comma +separated values. The latter are not included in the user manual (they +are not <code>\long</code>, they don’t make efforts to preserve some +braces, do not worry about spaces, all those worries being irrelevant to +the use in expressions for list selectors).</p></li> +<li><p>a slight speed improvement to <code>\xintFloatSqrt</code> in its +quest of correct rounding.</p></li> +<li><p>float multiplication and division handle more swiftly operands +(non-fractional) with few digits, when the float precision is +large.</p></li> +<li><p>the syntax of expressions is described in a devoted chapter of +the documentation; an example shows how to implement (expandably) the +Brent-Salamin algorithm for computation of Pi using <code>iter</code> in +a float expression.</p></li> </ul> -<h3 id="improvements-and-new-features-18">Improvements and new features</h3> +<h2 id="f-20160312"><code>1.2f (2016/03/12)</code></h2> +<h3 id="breaking-changes-17">Breaking changes</h3> <ul> -<li><p>functions <code>binomial</code>, <code>pfactorial</code> and <code>factorial</code> in both integer and float versions.</p></li> -<li><p>macros <code>\xintiiBinomial</code>, <code>\xintiiPFactorial</code> (<strong>xint.sty</strong>) and <code>\xintFloatBinomial</code>, <code>\xintFloatPFactorial</code> (<strong>xintfrac.sty</strong>). Improvements to <code>\xintFloatFac</code>.</p></li> -<li><p>faster implementation and increased accuracy of float power macros. Half-integer exponents are now accepted inside float expressions.</p></li> -<li><p>faster implementation of both integral and float square root macros.</p></li> -<li><p>the float square root achieves <em>correct</em> (aka <em>exact</em>) rounding in arbitrary precision.</p></li> -<li><p>modified behaviour for the <code>\xintPFloat</code> macro, used by <code>\xintthefloatexpr</code> to prettify its output. It now opts for decimal notation if and only if scientific notation would use an exponent between <code>-5</code> and <code>5</code> inclusive. The zero value is printed <code>0.</code> with a dot.</p></li> -<li><p>the float macros for addition, subtraction, multiplication, division now first round their two operands to P, not P+2, significant places before doing the actual computation (P being the target precision). The same applies to the power macros and to the square root macro.</p></li> -<li><p>the documentation offers a more precise (and accurate) discussion of floating point issues.</p></li> -<li><p>various under-the-hood code improvements; the floatexpr operations are chained in a faster way, from skipping some unneeded parsing on results of earlier computations. The absence of a real inner data structure for floats (incorporating their precisions, for one) is however still a bit hair raising: currently the lengths of the mantissas of the operands are computed again by each float macro or expression operation.</p></li> -<li><p>(TeXperts only) the macros defined (internally) from <code>\xintdeffunc</code> et al. constructs do not incorporate an initial <code>\romannumeral</code> anymore.</p></li> -<li><p>renewed desperate efforts at improving the documentation by random shuffling of sections and well thought additions; cuts were considered and even performed.</p></li> +<li>no more <code>\xintFac</code> macro but +<code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li> +</ul> +<h3 id="improvements-and-new-features-18">Improvements and new +features</h3> +<ul> +<li><p>functions <code>binomial</code>, <code>pfactorial</code> and +<code>factorial</code> in both integer and float versions.</p></li> +<li><p>macros <code>\xintiiBinomial</code>, +<code>\xintiiPFactorial</code> (<strong>xint.sty</strong>) and +<code>\xintFloatBinomial</code>, <code>\xintFloatPFactorial</code> +(<strong>xintfrac.sty</strong>). Improvements to +<code>\xintFloatFac</code>.</p></li> +<li><p>faster implementation and increased accuracy of float power +macros. Half-integer exponents are now accepted inside float +expressions.</p></li> +<li><p>faster implementation of both integral and float square root +macros.</p></li> +<li><p>the float square root achieves <em>correct</em> (aka +<em>exact</em>) rounding in arbitrary precision.</p></li> +<li><p>modified behaviour for the <code>\xintPFloat</code> macro, used +by <code>\xintthefloatexpr</code> to prettify its output. It now opts +for decimal notation if and only if scientific notation would use an +exponent between <code>-5</code> and <code>5</code> inclusive. The zero +value is printed <code>0.</code> with a dot.</p></li> +<li><p>the float macros for addition, subtraction, multiplication, +division now first round their two operands to P, not P+2, significant +places before doing the actual computation (P being the target +precision). The same applies to the power macros and to the square root +macro.</p></li> +<li><p>the documentation offers a more precise (and accurate) discussion +of floating point issues.</p></li> +<li><p>various under-the-hood code improvements; the floatexpr +operations are chained in a faster way, from skipping some unneeded +parsing on results of earlier computations. The absence of a real inner +data structure for floats (incorporating their precisions, for one) is +however still a bit hair raising: currently the lengths of the mantissas +of the operands are computed again by each float macro or expression +operation.</p></li> +<li><p>(TeXperts only) the macros defined (internally) from +<code>\xintdeffunc</code> et al. constructs do not incorporate an +initial <code>\romannumeral</code> anymore.</p></li> +<li><p>renewed desperate efforts at improving the documentation by +random shuffling of sections and well thought additions; cuts were +considered and even performed.</p></li> </ul> -<h3 id="bug-fixes-24">Bug fixes</h3> +<h3 id="bug-fixes-25">Bug fixes</h3> <ul> -<li><p>squaring macro <code>\xintSqr</code> from <strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro name. Dates back to <code>1.1</code> release of <code>2014/10/28</code> <code>:-((</code>.</p></li> -<li><p><code>1.2c</code>’s fix to the subtraction bug from <code>1.2</code> introduced another bug, which in some cases could create leading zeroes in the output, or even worse. This could invalidate other routines using subtractions, like <code>\xintiiSquareRoot</code>.</p></li> -<li><p>the comparison operators were not recognized by <code>\xintNewIIExpr</code> and <code>\xintdefiifunc</code> constructs.</p></li> +<li><p>squaring macro <code>\xintSqr</code> from +<strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro +name. Dates back to <code>1.1</code> release of <code>2014/10/28</code> +<code>:-((</code>.</p></li> +<li><p><code>1.2c</code>’s fix to the subtraction bug from +<code>1.2</code> introduced another bug, which in some cases could +create leading zeroes in the output, or even worse. This could +invalidate other routines using subtractions, like +<code>\xintiiSquareRoot</code>.</p></li> +<li><p>the comparison operators were not recognized by +<code>\xintNewIIExpr</code> and <code>\xintdefiifunc</code> +constructs.</p></li> </ul> <h2 id="e-20151122"><code>1.2e (2015/11/22)</code></h2> -<h3 id="improvements-and-new-features-19">Improvements and new features</h3> +<h3 id="improvements-and-new-features-19">Improvements and new +features</h3> <ul> <li><p>macro <code>\xintunassignvar</code>.</p></li> -<li><p>slight modifications of the logged messages in case of <code>\xintverbosetrue</code>.</p></li> -<li><p>a space in <code>\xintdeffunc f(x)<space>:= expression ;</code> is now accepted.</p></li> -<li><p>documentation enhancements: the <em>Quick Sort</em> section with its included code samples has been entirely re-written; the <em>Commands of the xintexpr package</em> section has been extended and reviewed entirely.</p></li> +<li><p>slight modifications of the logged messages in case of +<code>\xintverbosetrue</code>.</p></li> +<li><p>a space in +<code>\xintdeffunc f(x)<space>:= expression ;</code> is now +accepted.</p></li> +<li><p>documentation enhancements: the <em>Quick Sort</em> section with +its included code samples has been entirely re-written; the <em>Commands +of the xintexpr package</em> section has been extended and reviewed +entirely.</p></li> </ul> -<h3 id="bug-fixes-25">Bug fixes</h3> +<h3 id="bug-fixes-26">Bug fixes</h3> <ul> -<li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from release <code>1.2</code> parsed its argument only through <code>\numexpr</code> but it should have used <code>\xintNum</code>.</p></li> -<li><p>in <strong>xintexpr</strong>: release <code>1.2d</code> had broken the recognition of sub-expressions immediately after variable names (with tacit multiplication).</p></li> -<li><p>in <strong>xintexpr</strong>: contrarily to what <code>1.2d</code> documentation said, tacit multiplication was not yet always done with enhanced precedence. Now yes.</p></li> +<li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from +release <code>1.2</code> parsed its argument only through +<code>\numexpr</code> but it should have used +<code>\xintNum</code>.</p></li> +<li><p>in <strong>xintexpr</strong>: release <code>1.2d</code> had +broken the recognition of sub-expressions immediately after variable +names (with tacit multiplication).</p></li> +<li><p>in <strong>xintexpr</strong>: contrarily to what +<code>1.2d</code> documentation said, tacit multiplication was not yet +always done with enhanced precedence. Now yes.</p></li> </ul> <h2 id="d-20151118"><code>1.2d (2015/11/18)</code></h2> -<h3 id="improvements-and-new-features-20">Improvements and new features</h3> -<ul> -<li><p>the function definitions done by <code>\xintdeffunc</code> et al., as well as the macro declarations by <code>\xintNewExpr</code> et al. now have only local scope.</p></li> -<li><p>tacit multiplication applies to more cases, for example (x+y)z, and always ties more than standard * infix operator, e.g. x/2y is like x/(2*y).</p></li> -<li><p>some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments.</p></li> +<h3 id="improvements-and-new-features-20">Improvements and new +features</h3> +<ul> +<li><p>the function definitions done by <code>\xintdeffunc</code> et +al., as well as the macro declarations by <code>\xintNewExpr</code> et +al. now have only local scope.</p></li> +<li><p>tacit multiplication applies to more cases, for example (x+y)z, +and always ties more than standard * infix operator, e.g. x/2y is like +x/(2*y).</p></li> +<li><p>some documentation enhancements, particularly in the chapter on +xintexpr.sty, and also in the code source comments.</p></li> </ul> -<h3 id="bug-fixes-26">Bug fixes</h3> +<h3 id="bug-fixes-27">Bug fixes</h3> <ul> -<li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li> +<li>in <strong>xintcore</strong>: release <code>1.2c</code> had +inadvertently broken the <code>\xintiiDivRound</code> macro.</li> </ul> <h2 id="c-20151116"><code>1.2c (2015/11/16)</code></h2> -<h3 id="improvements-and-new-features-21">Improvements and new features</h3> +<h3 id="improvements-and-new-features-21">Improvements and new +features</h3> <ul> -<li><p>macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, <code>\xintdeffloatfunc</code> and boolean <code>\ifxintverbose</code>.</p></li> -<li><p>on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release.</p></li> +<li><p>macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, +<code>\xintdeffloatfunc</code> and boolean +<code>\ifxintverbose</code>.</p></li> +<li><p>on-going code improvements and documentation enhancements, but +stopped in order to issue this bugfix release.</p></li> </ul> -<h3 id="bug-fixes-27">Bug fixes</h3> +<h3 id="bug-fixes-28">Bug fixes</h3> <ul> -<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations).</li> +<li>in <strong>xintcore</strong>: recent release <code>1.2</code> +introduced a bug in the subtraction (happened when 00000001 was found +under certain circumstances at certain mod 8 locations).</li> </ul> <h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2> -<h3 id="bug-fixes-28">Bug fixes</h3> +<h3 id="bug-fixes-29">Bug fixes</h3> <ul> -<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the division macros, causing a crash when the divisor started with 99999999 (it was attempted to use with 1+99999999 a subroutine expecting only 8-digits numbers).</li> +<li>in <strong>xintcore</strong>: recent release <code>1.2</code> +introduced a bug in the division macros, causing a crash when the +divisor started with 99999999 (it was attempted to use with 1+99999999 a +subroutine expecting only 8-digits numbers).</li> </ul> <h2 id="a-20151019"><code>1.2a (2015/10/19)</code></h2> -<h3 id="improvements-and-new-features-22">Improvements and new features</h3> -<ul> -<li><p>added <code>\xintKeepUnbraced</code>, <code>\xintTrimUnbraced</code> (<strong>xinttools</strong>) and fixed documentation of <code>\xintKeep</code> and <code>\xintTrim</code> regarding brace stripping.</p></li> -<li><p>added <code>\xintiiMaxof/\xintiiMinof</code> (<strong>xint</strong>).</p></li> -<li><p>TeX hackers only: replaced all code uses of <code>\romannumeral-`0</code> by the quicker <code>\romannumeral`&&@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li> +<h3 id="improvements-and-new-features-22">Improvements and new +features</h3> +<ul> +<li><p>added <code>\xintKeepUnbraced</code>, +<code>\xintTrimUnbraced</code> (<strong>xinttools</strong>) and fixed +documentation of <code>\xintKeep</code> and <code>\xintTrim</code> +regarding brace stripping.</p></li> +<li><p>added <code>\xintiiMaxof/\xintiiMinof</code> +(<strong>xint</strong>).</p></li> +<li><p>TeX hackers only: replaced all code uses of +<code>\romannumeral-`0</code> by the quicker +<code>\romannumeral`&&@</code> (<code>^</code> being used as +letter, had to find another character usable with catcode 7).</p></li> </ul> -<h3 id="bug-fixes-29">Bug fixes</h3> +<h3 id="bug-fixes-30">Bug fixes</h3> <ul> -<li>in <strong>xintexpr</strong>: recent release <code>1.2</code> introduced a bad bug in the parsing of decimal numbers and as a result <code>\xinttheexpr 0.01\relax</code> expanded to <code>0</code> ! (sigh…)</li> +<li>in <strong>xintexpr</strong>: recent release <code>1.2</code> +introduced a bad bug in the parsing of decimal numbers and as a result +<code>\xinttheexpr 0.01\relax</code> expanded to <code>0</code> ! +(sigh…)</li> </ul> <h2 id="section-2"><code>1.2 (2015/10/10)</code></h2> <h3 id="removed-3">Removed</h3> <ul> -<li>the macros <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code>, <code>\xintMax</code>, <code>\xintMin</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> are removed from package <strong>xint</strong>, and only exist in the versions from <strong>xintfrac</strong>. With only <strong>xintcore</strong> or <strong>xint</strong> loaded, one <em>must</em> use <code>\xintiiAdd</code>, <code>\xintiiSub</code>, …, or <code>\xintiAdd</code>, <code>\xintiSub</code>, etc…</li> -</ul> -<h3 id="improvements-and-new-features-23">Improvements and new features</h3> -<ul> -<li><p>the basic arithmetic implemented in <strong>xintcore</strong> has been entirely rewritten. The mathematics remains the elementary school one, but the <code>TeX</code> implementation achieves higher speed (except, regarding addition/subtraction, for numbers up to about thirty digits), the gains becoming quite significant for numbers with hundreds of digits.</p></li> -<li><p>the inputs must have less than 19959 digits. But computations with thousands of digits take time.</p></li> -<li><p>a previously standing limitation of <code>\xintexpr</code>, <code>\xintiiexpr</code>, and of <code>\xintfloatexpr</code> to numbers of less than 5000 digits has been lifted.</p></li> -<li><p>a <em>qint</em> function is provided to help the parser gather huge integers in one-go, as an exception to its normal mode of operation which expands token by token.</p></li> -<li><p><code>\xintFloatFac</code> macro for computing the factorials of integers as floating point numbers to a given precision. The <code>!</code> postfix operator inside <code>\xintfloatexpr</code> maps to this new macro rather than to the exact factorial as used by <code>\xintexpr</code> and <code>\xintiiexpr</code>.</p></li> -<li><p>there is more flexibility in the parsing done by the macros from <strong>xintfrac</strong> on fractional input: the decimal parts of both the numerator and the denominator may arise from a separate expansion via <code>\romannumeral-`0</code>. Also the strict <code>A/B[N]</code> format is a bit relaxed: <code>N</code> may be anything understood by <code>\numexpr</code> (it could even be empty but that possibility has been removed by later <code>1.2f</code> release.)</p></li> -<li><p>on the other hand an isolated dot <code>.</code> is not legal syntax anymore inside the expression parsers: there must be digits either before or after. It remains legal input for the macros of <strong>xintfrac</strong>.</p></li> -<li><p>added <code>\ht</code>, <code>\dp</code>, <code>\wd</code>, <code>\fontcharht</code>, etc… to the tokens recognized by the parsers and expanded by <code>\number</code>.</p></li> -<li><p>an obscure bug in package <strong>xintkernel</strong> has been fixed, regarding the sanitization of catcodes: under certain circumstances (which could not occur in a normal <code>LaTeX</code> context), unusual catcodes could end up being propagated to the external world.</p></li> -<li><p>an effort at randomly shuffling around various pieces of the documentation has been done.</p></li> +<li>the macros <code>\xintAdd</code>, <code>\xintSub</code>, +<code>\xintMul</code>, <code>\xintMax</code>, <code>\xintMin</code>, +<code>\xintMaxof</code>, <code>\xintMinof</code> are removed from +package <strong>xint</strong>, and only exist in the versions from +<strong>xintfrac</strong>. With only <strong>xintcore</strong> or +<strong>xint</strong> loaded, one <em>must</em> use +<code>\xintiiAdd</code>, <code>\xintiiSub</code>, …, or +<code>\xintiAdd</code>, <code>\xintiSub</code>, etc…</li> +</ul> +<h3 id="improvements-and-new-features-23">Improvements and new +features</h3> +<ul> +<li><p>the basic arithmetic implemented in <strong>xintcore</strong> has +been entirely rewritten. The mathematics remains the elementary school +one, but the <code>TeX</code> implementation achieves higher speed +(except, regarding addition/subtraction, for numbers up to about thirty +digits), the gains becoming quite significant for numbers with hundreds +of digits.</p></li> +<li><p>the inputs must have less than 19959 digits. But computations +with thousands of digits take time.</p></li> +<li><p>a previously standing limitation of <code>\xintexpr</code>, +<code>\xintiiexpr</code>, and of <code>\xintfloatexpr</code> to numbers +of less than 5000 digits has been lifted.</p></li> +<li><p>a <em>qint</em> function is provided to help the parser gather +huge integers in one-go, as an exception to its normal mode of operation +which expands token by token.</p></li> +<li><p><code>\xintFloatFac</code> macro for computing the factorials of +integers as floating point numbers to a given precision. The +<code>!</code> postfix operator inside <code>\xintfloatexpr</code> maps +to this new macro rather than to the exact factorial as used by +<code>\xintexpr</code> and <code>\xintiiexpr</code>.</p></li> +<li><p>there is more flexibility in the parsing done by the macros from +<strong>xintfrac</strong> on fractional input: the decimal parts of both +the numerator and the denominator may arise from a separate expansion +via <code>\romannumeral-`0</code>. Also the strict <code>A/B[N]</code> +format is a bit relaxed: <code>N</code> may be anything understood by +<code>\numexpr</code> (it could even be empty but that possibility has +been removed by later <code>1.2f</code> release.)</p></li> +<li><p>on the other hand an isolated dot <code>.</code> is not legal +syntax anymore inside the expression parsers: there must be digits +either before or after. It remains legal input for the macros of +<strong>xintfrac</strong>.</p></li> +<li><p>added <code>\ht</code>, <code>\dp</code>, <code>\wd</code>, +<code>\fontcharht</code>, etc… to the tokens recognized by the parsers +and expanded by <code>\number</code>.</p></li> +<li><p>an obscure bug in package <strong>xintkernel</strong> has been +fixed, regarding the sanitization of catcodes: under certain +circumstances (which could not occur in a normal <code>LaTeX</code> +context), unusual catcodes could end up being propagated to the external +world.</p></li> +<li><p>an effort at randomly shuffling around various pieces of the +documentation has been done.</p></li> </ul> <h2 id="c-20150912"><code>1.1c (2015/09/12)</code></h2> <ul> -<li><p>bugfix regarding macro <code>\xintAssign</code> from <strong>xinttools</strong> which did not behave correctly in some circumstances (if there was a space before <code>\to</code>, in particular).</p></li> -<li><p>very minor code improvements, and correction of some issues regarding the source code formatting in <code>sourcexint.pdf</code>, and minor issues in <code>Makefile.mk</code>.</p></li> +<li><p>bugfix regarding macro <code>\xintAssign</code> from +<strong>xinttools</strong> which did not behave correctly in some +circumstances (if there was a space before <code>\to</code>, in +particular).</p></li> +<li><p>very minor code improvements, and correction of some issues +regarding the source code formatting in <code>sourcexint.pdf</code>, and +minor issues in <code>Makefile.mk</code>.</p></li> </ul> <h2 id="b-20150831"><code>1.1b (2015/08/31)</code></h2> <ul> -<li><p>bugfix: some macros needed by the integer division routine from <strong>xintcore</strong> had been left in <strong>xint.sty</strong> since release <code>1.1</code>. This for example broke the <code>\xintGCD</code> from <strong>xintgcd</strong> if package <strong>xint</strong> was not loaded.</p></li> -<li><p>Slight enhancements to the documentation, particularly in the <code>Read this first</code> section.</p></li> +<li><p>bugfix: some macros needed by the integer division routine from +<strong>xintcore</strong> had been left in <strong>xint.sty</strong> +since release <code>1.1</code>. This for example broke the +<code>\xintGCD</code> from <strong>xintgcd</strong> if package +<strong>xint</strong> was not loaded.</p></li> +<li><p>Slight enhancements to the documentation, particularly in the +<code>Read this first</code> section.</p></li> </ul> <h2 id="a-20141107"><code>1.1a (2014/11/07)</code></h2> <ul> -<li><p>fixed a bug which prevented <code>\xintNewExpr</code> from producing correctly working macros from a comma separated replacement text.</p></li> -<li><p><code>\xintiiSqrtR</code> for rounded integer square root; former <code>\xintiiSqrt</code> already produced truncated integer square root; corresponding function <code>sqrtr</code> added to <code>\xintiiexpr..\relax</code> syntax.</p></li> -<li><p>use of straight quotes in the documentation for better legibility.</p></li> -<li><p>added <code>\xintiiIsOne</code>, <code>\xintiiifOne</code>, <code>\xintiiifCmp</code>, <code>\xintiiifEq</code>, <code>\xintiiifGt</code>, <code>\xintiiifLt</code>, <code>\xintiiifOdd</code>, <code>\xintiiCmp</code>, <code>\xintiiEq</code>, <code>\xintiiGt</code>, <code>\xintiiLt</code>, <code>\xintiiLtorEq</code>, <code>\xintiiGtorEq</code>, <code>\xintiiNeq</code>, mainly for efficiency of <code>\xintiiexpr</code>.</p></li> -<li><p>for the same reason, added <code>\xintiiGCD</code> and <code>\xintiiLCM</code>.</p></li> -<li><p>added the previously mentioned <code>ii</code> macros, and some others from <code>1.1</code>, to the user manual. But their main usage is internal to <code>\xintiiexpr</code>, to skip unnecessary overheads.</p></li> -<li><p>various typographical fixes throughout the documentation, and a bit of clean up of the code comments. Improved <code>\Factors</code> example of nested <code>subs</code>, <code>rseq</code>, <code>iter</code> in <code>\xintiiexpr</code>.</p></li> +<li><p>fixed a bug which prevented <code>\xintNewExpr</code> from +producing correctly working macros from a comma separated replacement +text.</p></li> +<li><p><code>\xintiiSqrtR</code> for rounded integer square root; former +<code>\xintiiSqrt</code> already produced truncated integer square root; +corresponding function <code>sqrtr</code> added to +<code>\xintiiexpr..\relax</code> syntax.</p></li> +<li><p>use of straight quotes in the documentation for better +legibility.</p></li> +<li><p>added <code>\xintiiIsOne</code>, <code>\xintiiifOne</code>, +<code>\xintiiifCmp</code>, <code>\xintiiifEq</code>, +<code>\xintiiifGt</code>, <code>\xintiiifLt</code>, +<code>\xintiiifOdd</code>, <code>\xintiiCmp</code>, +<code>\xintiiEq</code>, <code>\xintiiGt</code>, <code>\xintiiLt</code>, +<code>\xintiiLtorEq</code>, <code>\xintiiGtorEq</code>, +<code>\xintiiNeq</code>, mainly for efficiency of +<code>\xintiiexpr</code>.</p></li> +<li><p>for the same reason, added <code>\xintiiGCD</code> and +<code>\xintiiLCM</code>.</p></li> +<li><p>added the previously mentioned <code>ii</code> macros, and some +others from <code>1.1</code>, to the user manual. But their main usage +is internal to <code>\xintiiexpr</code>, to skip unnecessary +overheads.</p></li> +<li><p>various typographical fixes throughout the documentation, and a +bit of clean up of the code comments. Improved <code>\Factors</code> +example of nested <code>subs</code>, <code>rseq</code>, +<code>iter</code> in <code>\xintiiexpr</code>.</p></li> </ul> <h2 id="section-3"><code>1.1 (2014/10/28)</code></h2> -<h3 id="breaking-changes-17">Breaking changes</h3> -<ul> -<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> division, rather than the Euclidean division (for positive arguments, this is truncated division). The <code>//</code> operator does truncated division,</p></li> -<li><p>the <code>:</code> operator for three-way branching is gone, replaced with <code>??</code>,</p></li> -<li><p><code>1e(3+5)</code> is now illegal. The number parser identifies <code>e</code> and <code>E</code> in the same way it does for the decimal mark, earlier versions treated <code>e</code> as <code>E</code> rather as infix operators of highest precedence,</p></li> -<li><p>the <code>add</code> and <code>mul</code> have a new syntax, old syntax is with <code>`+`</code> and <code>`*`</code> (left quotes mandatory), <code>sum</code> and <code>prd</code> are gone,</p></li> -<li><p>no more special treatment for encountered brace pairs <code>{..}</code> by the number scanner, <code>a/b[N]</code> notation can be used without use of braces (the <code>N</code> will end up as is in a <code>\numexpr</code>, it is not parsed by the <code>\xintexpr</code>-ession scanner),</p></li> -<li><p>in earlier releases, place holders for <code>\xintNewExpr</code> could either be denoted <code>#1</code>, <code>#2</code>, … or also <code>$1</code>, <code>$2</code>, … Only the usual <code>#</code> form is now accepted and the special cases previously treated via the second form are now managed via a <code>protect(...)</code> function.</p></li> -<li><p><strong>xintfrac</strong>: <code>\xintFloor</code> and <code>\xintCeil</code> add a trailing <code>/1[0]</code> to their (integer) output. New <code>\xintiFloor</code> and <code>\xintiCeil</code> do not.</p></li> +<h3 id="breaking-changes-18">Breaking changes</h3> +<ul> +<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> +division, rather than the Euclidean division (for positive arguments, +this is truncated division). The <code>//</code> operator does truncated +division,</p></li> +<li><p>the <code>:</code> operator for three-way branching is gone, +replaced with <code>??</code>,</p></li> +<li><p><code>1e(3+5)</code> is now illegal. The number parser identifies +<code>e</code> and <code>E</code> in the same way it does for the +decimal mark, earlier versions treated <code>e</code> as <code>E</code> +rather as infix operators of highest precedence,</p></li> +<li><p>the <code>add</code> and <code>mul</code> have a new syntax, old +syntax is with <code>`+`</code> and <code>`*`</code> (left quotes +mandatory), <code>sum</code> and <code>prd</code> are gone,</p></li> +<li><p>no more special treatment for encountered brace pairs +<code>{..}</code> by the number scanner, <code>a/b[N]</code> notation +can be used without use of braces (the <code>N</code> will end up as is +in a <code>\numexpr</code>, it is not parsed by the +<code>\xintexpr</code>-ession scanner),</p></li> +<li><p>in earlier releases, place holders for <code>\xintNewExpr</code> +could either be denoted <code>#1</code>, <code>#2</code>, … or also +<code>$1</code>, <code>$2</code>, … Only the usual <code>#</code> form +is now accepted and the special cases previously treated via the second +form are now managed via a <code>protect(...)</code> function.</p></li> +<li><p><strong>xintfrac</strong>: <code>\xintFloor</code> and +<code>\xintCeil</code> add a trailing <code>/1[0]</code> to their +(integer) output. New <code>\xintiFloor</code> and +<code>\xintiCeil</code> do not.</p></li> </ul> <h3 id="removed-4">Removed</h3> <ul> -<li><code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code>: use <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>.</li> +<li><code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, +<code>\xintNewNumExpr</code>: use <code>\xintiexpr</code>, +<code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>.</li> </ul> <h3 id="deprecated-2">Deprecated</h3> <ul> -<li><p><code>\xintDivision</code>, <code>\xintQuo</code>, <code>\xintRem</code>: use <code>\xintiDivision</code>, <code>\xintiQuo</code>, <code>\xintiRem</code>.</p></li> -<li><p><code>\xintMax</code>, <code>\xintMin</code>, <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code> (<strong>xint</strong>): their usage without <strong>xintfrac</strong> is deprecated; use <code>\xintiMax</code>, <code>\xintiMin</code>, <code>\xintiAdd</code>, <code>\xintiSub</code>, <code>\xintiMul</code>.</p></li> -<li><p>the <code>&</code> and <code>|</code> as Boolean operators in <code>xintexpr</code>-essions are deprecated in favour of <code>&&</code> and <code>||</code>. The single letter operators might be assigned some other meaning in some later release (bitwise operations, perhaps). Do not use them.</p></li> -</ul> -<h3 id="improvements-and-new-features-24">Improvements and new features</h3> -<ul> -<li><p>new package <strong>xintcore</strong> has been split off <strong>xint</strong>. It contains the core arithmetic macros (it is loaded by LaTeX package <strong>bnumexpr</strong>),</p></li> -<li><p>neither <strong>xint</strong> nor <strong>xintfrac</strong> load <strong>xinttools</strong>. Only <strong>xintexpr</strong> does,</p></li> -<li><p>whenever some portion of code has been revised, often use has been made of the <code>\xint_dothis</code> and <code>\xint_orthat</code> pair of macros for expandably branching,</p></li> -<li><p>these tiny helpful macros, and a few others are in package <strong>xintkernel</strong> which contains also the catcode and loading order management code, initially inspired by code found in Heiko Oberdiek’s packages,</p></li> -<li><p>the source code, which was suppressed from <code>xint.pdf</code> in release <code>1.09n</code>, is now compiled into a separate file <code>sourcexint.pdf</code>,</p></li> -<li><p>faster handling by <code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code>, … of the case where one of the arguments is zero,</p></li> -<li><p>the <code>\xintAdd</code> and <code>\xintSub</code> macros from package <strong>xintfrac</strong> check if one of the denominators is a multiple of the other, and only if this is not the case do they multiply the denominators. But systematic reduction would be too costly,</p></li> -<li><p>this naturally will be also the case for the <code>+</code> and <code>-</code> operations in <code>\xintexpr</code>,</p></li> -<li><p><strong>xint</strong> added <code>\xintiiDivRound</code>, <code>\xintiiDivTrunc</code>, <code>\xintiiMod</code> for rounded and truncated division of big integers (next to <code>\xintiiQuo</code> and <code>\xintiiRem</code>),</p></li> -<li><p>with <strong>xintfrac</strong> loaded, the <code>\xintNum</code> macro does <code>\xintTTrunc</code> (which is truncation to an integer, same as <code>\xintiTrunc {0}</code>),</p></li> -<li><p>added <code>\xintMod</code> to <strong>xintfrac</strong> for modulo operation with fractional numbers,</p></li> -<li><p>added <code>\xintiFloor</code> and <code>\xintiCeil</code> to <strong>xintfrac</strong>,</p></li> -<li><p><code>\xintiexpr</code>, <code>\xinttheiexpr</code> admit an optional argument within brackets <code>[d]</code>, they round the computation result (or results, if comma separated) to <code>d</code> digits after decimal mark, (the whole computation is done exactly, as in <code>xintexpr</code>),</p></li> -<li><p><code>\xintfloatexpr</code>, <code>\xintthefloatexpr</code> similarly admit an optional argument which serves to keep only <code>d</code> digits of precision, getting rid of cumulated uncertainties in the last digits (the whole computation is done according to the precision set via <code>\xintDigits</code>),</p></li> -<li><p><code>\xinttheexpr</code> and <code>\xintthefloatexpr</code> <em>pretty-print</em> if possible, the former removing unit denominator or <code>[0]</code> brackets, the latter avoiding scientific notation if decimal notation is practical,</p></li> -<li><p>the <code>//</code> does truncated division and <code>/:</code> is the associated modulo,</p></li> -<li><p>multi-character operators <code>&&</code>, <code>||</code>, <code>==</code>, <code><=</code>, <code>>=</code>, <code>!=</code>, <code>**</code>,</p></li> -<li><p>multi-letter infix binary words <code>'and'</code>, <code>'or'</code>, <code>'xor'</code>, <code>'mod'</code> (straight quotes mandatory),</p></li> +<li><p><code>\xintDivision</code>, <code>\xintQuo</code>, +<code>\xintRem</code>: use <code>\xintiDivision</code>, +<code>\xintiQuo</code>, <code>\xintiRem</code>.</p></li> +<li><p><code>\xintMax</code>, <code>\xintMin</code>, +<code>\xintAdd</code>, <code>\xintSub</code>, <code>\xintMul</code> +(<strong>xint</strong>): their usage without <strong>xintfrac</strong> +is deprecated; use <code>\xintiMax</code>, <code>\xintiMin</code>, +<code>\xintiAdd</code>, <code>\xintiSub</code>, +<code>\xintiMul</code>.</p></li> +<li><p>the <code>&</code> and <code>|</code> as Boolean operators in +<code>xintexpr</code>-essions are deprecated in favour of +<code>&&</code> and <code>||</code>. The single letter operators +might be assigned some other meaning in some later release (bitwise +operations, perhaps). Do not use them.</p></li> +</ul> +<h3 id="improvements-and-new-features-24">Improvements and new +features</h3> +<ul> +<li><p>new package <strong>xintcore</strong> has been split off +<strong>xint</strong>. It contains the core arithmetic macros (it is +loaded by LaTeX package <strong>bnumexpr</strong>),</p></li> +<li><p>neither <strong>xint</strong> nor <strong>xintfrac</strong> load +<strong>xinttools</strong>. Only <strong>xintexpr</strong> +does,</p></li> +<li><p>whenever some portion of code has been revised, often use has +been made of the <code>\xint_dothis</code> and <code>\xint_orthat</code> +pair of macros for expandably branching,</p></li> +<li><p>these tiny helpful macros, and a few others are in package +<strong>xintkernel</strong> which contains also the catcode and loading +order management code, initially inspired by code found in Heiko +Oberdiek’s packages,</p></li> +<li><p>the source code, which was suppressed from <code>xint.pdf</code> +in release <code>1.09n</code>, is now compiled into a separate file +<code>sourcexint.pdf</code>,</p></li> +<li><p>faster handling by <code>\xintAdd</code>, <code>\xintSub</code>, +<code>\xintMul</code>, … of the case where one of the arguments is +zero,</p></li> +<li><p>the <code>\xintAdd</code> and <code>\xintSub</code> macros from +package <strong>xintfrac</strong> check if one of the denominators is a +multiple of the other, and only if this is not the case do they multiply +the denominators. But systematic reduction would be too costly,</p></li> +<li><p>this naturally will be also the case for the <code>+</code> and +<code>-</code> operations in <code>\xintexpr</code>,</p></li> +<li><p><strong>xint</strong> added <code>\xintiiDivRound</code>, +<code>\xintiiDivTrunc</code>, <code>\xintiiMod</code> for rounded and +truncated division of big integers (next to <code>\xintiiQuo</code> and +<code>\xintiiRem</code>),</p></li> +<li><p>with <strong>xintfrac</strong> loaded, the <code>\xintNum</code> +macro does <code>\xintTTrunc</code> (which is truncation to an integer, +same as <code>\xintiTrunc {0}</code>),</p></li> +<li><p>added <code>\xintMod</code> to <strong>xintfrac</strong> for +modulo operation with fractional numbers,</p></li> +<li><p>added <code>\xintiFloor</code> and <code>\xintiCeil</code> to +<strong>xintfrac</strong>,</p></li> +<li><p><code>\xintiexpr</code>, <code>\xinttheiexpr</code> admit an +optional argument within brackets <code>[d]</code>, they round the +computation result (or results, if comma separated) to <code>d</code> +digits after decimal mark, (the whole computation is done exactly, as in +<code>xintexpr</code>),</p></li> +<li><p><code>\xintfloatexpr</code>, <code>\xintthefloatexpr</code> +similarly admit an optional argument which serves to keep only +<code>d</code> digits of precision, getting rid of cumulated +uncertainties in the last digits (the whole computation is done +according to the precision set via <code>\xintDigits</code>),</p></li> +<li><p><code>\xinttheexpr</code> and <code>\xintthefloatexpr</code> +<em>pretty-print</em> if possible, the former removing unit denominator +or <code>[0]</code> brackets, the latter avoiding scientific notation if +decimal notation is practical,</p></li> +<li><p>the <code>//</code> does truncated division and <code>/:</code> +is the associated modulo,</p></li> +<li><p>multi-character operators <code>&&</code>, +<code>||</code>, <code>==</code>, <code><=</code>, +<code>>=</code>, <code>!=</code>, <code>**</code>,</p></li> +<li><p>multi-letter infix binary words <code>'and'</code>, +<code>'or'</code>, <code>'xor'</code>, <code>'mod'</code> (straight +quotes mandatory),</p></li> <li><p>functions <code>even</code>, <code>odd</code>,</p></li> -<li><p><code>\xintdefvar A3:=3.1415;</code> for variable definitions (non expandable, naturally), usable in subsequent expressions; variable names may contain letters, digits, underscores. They should not start with a digit, the <code>@</code> is reserved, and single lowercase and uppercase Latin letters are predefined to work as dummy variables (see next),</p></li> -<li><p>generation of comma separated lists <code>a..b</code>, <code>a..[d]..b</code>,</p></li> -<li><p>Python syntax-like list extractors <code>[list][n:]</code>, <code>[list][:n]</code>, <code>[list][a:b]</code> allowing negative indices, but no optional step argument, and <code>[list][n]</code> (<code>n=0</code> for the number of items in the list),</p></li> -<li><p>functions <code>first</code>, <code>last</code>, <code>reversed</code>,</p></li> -<li><p>itemwise operations on comma separated lists <code>a*[list]</code>, etc.., possible on both sides <code>a*[list]^b</code>, and obeying the same precedence rules as with numbers,</p></li> -<li><p><code>add</code> and <code>mul</code> must use a dummy variable: <code>add(x(x+1)(x-1), x=-10..10)</code>,</p></li> -<li><p>variable substitutions with <code>subs</code>: <code>subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)</code>,</p></li> -<li><p>sequence generation using <code>seq</code> with a dummy variable: <code>seq(x^3, x=-10..10)</code>,</p></li> -<li><p>simple recursive lists with <code>rseq</code>, with <code>@</code> given the last value, <code>rseq(1;2@+1,i=1..10)</code>,</p></li> -<li><p>higher recursion with <code>rrseq</code>, <code>@1</code>, <code>@2</code>, <code>@3</code>, <code>@4</code>, and <code>@@(n)</code> for earlier values, up to <code>n=K</code> where <code>K</code> is the number of terms of the initial stretch <code>rrseq(0,1;@1+@2,i=2..100)</code>,</p></li> -<li><p>iteration with <code>iter</code> which is like <code>rrseq</code> but outputs only the last <code>K</code> terms, where <code>K</code> was the number of initial terms,</p></li> -<li><p>inside <code>seq</code>, <code>rseq</code>, <code>rrseq</code>, <code>iter</code>, possibility to use <code>omit</code>, <code>abort</code> and <code>break</code> to control termination,</p></li> -<li><p><code>n++</code> potentially infinite index generation for <code>seq</code>, <code>rseq</code>, <code>rrseq</code>, and <code>iter</code>, it is advised to use <code>abort</code> or <code>break(..)</code> at some point,</p></li> -<li><p>the <code>add</code>, <code>mul</code>, <code>seq</code>, … are nestable,</p></li> -<li><p><code>\xintthecoords</code> converts a comma separated list of an even number of items to the format expected by the <code>TikZ</code> <code>coordinates</code> syntax,</p></li> -<li><p>completely new version <code>\xintNewExpr</code>, <code>protect</code> function to handle external macros. The dollar sign <code>$</code> for place holders is not accepted anymore, only the standard macro parameter <code>#</code>. Not all constructs are compatible with <code>\xintNewExpr</code>.</p></li> -</ul> -<h3 id="bug-fixes-30">Bug fixes</h3> -<ul> -<li><p><code>\xintZapFirstSpaces</code> hence also <code>\xintZapSpaces</code> from package <strong>xinttools</strong> were buggy when used with an argument either empty or containing only space tokens.</p></li> -<li><p><code>\xintiiexpr</code> did not strip leading zeroes, hence <code>\xinttheiiexpr 001+1\relax</code> did not obtain the expected result …</p></li> -<li><p><code>\xinttheexpr \xintiexpr 1.23\relax\relax</code> should have produced <code>1</code>, but it produced <code>1.23</code></p></li> -<li><p>the catcode of <code>;</code> was not set at package launching time.</p></li> -<li><p>the <code>\XINTinFloatPrd:csv</code> macro name had a typo, hence <code>prd</code> was non-functional in <code>\xintfloatexpr</code>.</p></li> +<li><p><code>\xintdefvar A3:=3.1415;</code> for variable definitions +(non expandable, naturally), usable in subsequent expressions; variable +names may contain letters, digits, underscores. They should not start +with a digit, the <code>@</code> is reserved, and single lowercase and +uppercase Latin letters are predefined to work as dummy variables (see +next),</p></li> +<li><p>generation of comma separated lists <code>a..b</code>, +<code>a..[d]..b</code>,</p></li> +<li><p>Python syntax-like list extractors <code>[list][n:]</code>, +<code>[list][:n]</code>, <code>[list][a:b]</code> allowing negative +indices, but no optional step argument, and <code>[list][n]</code> +(<code>n=0</code> for the number of items in the list),</p></li> +<li><p>functions <code>first</code>, <code>last</code>, +<code>reversed</code>,</p></li> +<li><p>itemwise operations on comma separated lists +<code>a*[list]</code>, etc.., possible on both sides +<code>a*[list]^b</code>, and obeying the same precedence rules as with +numbers,</p></li> +<li><p><code>add</code> and <code>mul</code> must use a dummy variable: +<code>add(x(x+1)(x-1), x=-10..10)</code>,</p></li> +<li><p>variable substitutions with <code>subs</code>: +<code>subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)</code>,</p></li> +<li><p>sequence generation using <code>seq</code> with a dummy variable: +<code>seq(x^3, x=-10..10)</code>,</p></li> +<li><p>simple recursive lists with <code>rseq</code>, with +<code>@</code> given the last value, +<code>rseq(1;2@+1,i=1..10)</code>,</p></li> +<li><p>higher recursion with <code>rrseq</code>, <code>@1</code>, +<code>@2</code>, <code>@3</code>, <code>@4</code>, and +<code>@@(n)</code> for earlier values, up to <code>n=K</code> where +<code>K</code> is the number of terms of the initial stretch +<code>rrseq(0,1;@1+@2,i=2..100)</code>,</p></li> +<li><p>iteration with <code>iter</code> which is like <code>rrseq</code> +but outputs only the last <code>K</code> terms, where <code>K</code> was +the number of initial terms,</p></li> +<li><p>inside <code>seq</code>, <code>rseq</code>, <code>rrseq</code>, +<code>iter</code>, possibility to use <code>omit</code>, +<code>abort</code> and <code>break</code> to control +termination,</p></li> +<li><p><code>n++</code> potentially infinite index generation for +<code>seq</code>, <code>rseq</code>, <code>rrseq</code>, and +<code>iter</code>, it is advised to use <code>abort</code> or +<code>break(..)</code> at some point,</p></li> +<li><p>the <code>add</code>, <code>mul</code>, <code>seq</code>, … are +nestable,</p></li> +<li><p><code>\xintthecoords</code> converts a comma separated list of an +even number of items to the format expected by the <code>TikZ</code> +<code>coordinates</code> syntax,</p></li> +<li><p>completely new version <code>\xintNewExpr</code>, +<code>protect</code> function to handle external macros. The dollar sign +<code>$</code> for place holders is not accepted anymore, only the +standard macro parameter <code>#</code>. Not all constructs are +compatible with <code>\xintNewExpr</code>.</p></li> +</ul> +<h3 id="bug-fixes-31">Bug fixes</h3> +<ul> +<li><p><code>\xintZapFirstSpaces</code> hence also +<code>\xintZapSpaces</code> from package <strong>xinttools</strong> were +buggy when used with an argument either empty or containing only space +tokens.</p></li> +<li><p><code>\xintiiexpr</code> did not strip leading zeroes, hence +<code>\xinttheiiexpr 001+1\relax</code> did not obtain the expected +result …</p></li> +<li><p><code>\xinttheexpr \xintiexpr 1.23\relax\relax</code> should have +produced <code>1</code>, but it produced <code>1.23</code></p></li> +<li><p>the catcode of <code>;</code> was not set at package launching +time.</p></li> +<li><p>the <code>\XINTinFloatPrd:csv</code> macro name had a typo, hence +<code>prd</code> was non-functional in +<code>\xintfloatexpr</code>.</p></li> </ul> <h2 id="n-20140401"><code>1.09n (2014/04/01)</code></h2> <ul> -<li><p>the user manual does not include by default the source code anymore: the <code>\NoSourceCode</code> toggle in file <code>xint.tex</code> has to be set to 0 before compilation to get source code inclusion (later release <code>1.1</code> made source code available as <code>sourcexint.pdf</code>).</p></li> -<li><p>bug fix (<strong>xinttools</strong>) in <code>\XINT_nthelt_finish</code> (this bug was introduced in <code>1.09i</code> of <code>2013/12/18</code> and showed up when the index <code>N</code> was larger than the number of elements of the list).</p></li> +<li><p>the user manual does not include by default the source code +anymore: the <code>\NoSourceCode</code> toggle in file +<code>xint.tex</code> has to be set to 0 before compilation to get +source code inclusion (later release <code>1.1</code> made source code +available as <code>sourcexint.pdf</code>).</p></li> +<li><p>bug fix (<strong>xinttools</strong>) in +<code>\XINT_nthelt_finish</code> (this bug was introduced in +<code>1.09i</code> of <code>2013/12/18</code> and showed up when the +index <code>N</code> was larger than the number of elements of the +list).</p></li> </ul> <h2 id="m-20140226"><code>1.09m (2014/02/26)</code></h2> <ul> -<li><p>new in <strong>xinttools</strong>: <code>\xintKeep</code> keeps the first <code>N</code> or last <code>N</code> elements of a list (sequence of braced items); <code>\xintTrim</code> cuts out either the first <code>N</code> or the last <code>N</code> elements from a list.</p></li> -<li><p>new in <strong>xintcfrac</strong>: <code>\xintFGtoC</code> finds the initial partial quotients common to two numbers or fractions <code>f</code> and <code>g</code>; <code>\xintGGCFrac</code> is a clone of <code>\xintGCFrac</code> which however does not assume that the coefficients of the generalized continued fraction are numeric quantities. Some other minor changes.</p></li> +<li><p>new in <strong>xinttools</strong>: <code>\xintKeep</code> keeps +the first <code>N</code> or last <code>N</code> elements of a list +(sequence of braced items); <code>\xintTrim</code> cuts out either the +first <code>N</code> or the last <code>N</code> elements from a +list.</p></li> +<li><p>new in <strong>xintcfrac</strong>: <code>\xintFGtoC</code> finds +the initial partial quotients common to two numbers or fractions +<code>f</code> and <code>g</code>; <code>\xintGGCFrac</code> is a clone +of <code>\xintGCFrac</code> which however does not assume that the +coefficients of the generalized continued fraction are numeric +quantities. Some other minor changes.</p></li> </ul> <h2 id="kb-20140213"><code>1.09kb (2014/02/13)</code></h2> <ul> -<li><p>bug fix (<strong>xintexpr</strong>): an aloof modification done by <code>1.09i</code> to <code>\xintNewExpr</code> had resulted in a spurious trailing space present in the outputs of all macros created by <code>\xintNewExpr</code>, making nesting of such macros impossible.</p></li> -<li><p>bug fix (<strong>xinttools</strong>): <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code> were buggy when used in the last iteration of an <code>\xintFor</code> loop.</p></li> -<li><p>bug fix (<strong>xinttools</strong>): <code>\xintSeq</code> from <code>1.09k</code> needed a <code>\chardef</code> which was missing from <code>xinttools.sty</code>, it was in <code>xint.sty</code>.</p></li> +<li><p>bug fix (<strong>xintexpr</strong>): an aloof modification done +by <code>1.09i</code> to <code>\xintNewExpr</code> had resulted in a +spurious trailing space present in the outputs of all macros created by +<code>\xintNewExpr</code>, making nesting of such macros +impossible.</p></li> +<li><p>bug fix (<strong>xinttools</strong>): <code>\xintBreakFor</code> +and <code>\xintBreakForAndDo</code> were buggy when used in the last +iteration of an <code>\xintFor</code> loop.</p></li> +<li><p>bug fix (<strong>xinttools</strong>): <code>\xintSeq</code> from +<code>1.09k</code> needed a <code>\chardef</code> which was missing from +<code>xinttools.sty</code>, it was in <code>xint.sty</code>.</p></li> </ul> <h2 id="k-20140121"><code>1.09k (2014/01/21)</code></h2> <ul> -<li><p>inside <code>\xintexpr..\relax</code> (and its variants) tacit multiplication is implied when a number or operand is followed directly with an opening parenthesis,</p></li> -<li><p>the <code>"</code> for denoting (arbitrarily big) hexadecimal numbers is recognized by <code>\xintexpr</code> and its variants (package <strong>xintbinhex</strong> is required); a fractional hexadecimal part introduced by a dot <code>.</code> is allowed.</p></li> -<li><p>re-organization of the first sections of the user manual.</p></li> -<li><p>bug fix (<strong>xinttools</strong>, <strong>xint</strong>, …): forgotten catcode check of <code>"</code> at loading time has been added.</p></li> +<li><p>inside <code>\xintexpr..\relax</code> (and its variants) tacit +multiplication is implied when a number or operand is followed directly +with an opening parenthesis,</p></li> +<li><p>the <code>"</code> for denoting (arbitrarily big) hexadecimal +numbers is recognized by <code>\xintexpr</code> and its variants +(package <strong>xintbinhex</strong> is required); a fractional +hexadecimal part introduced by a dot <code>.</code> is allowed.</p></li> +<li><p>re-organization of the first sections of the user +manual.</p></li> +<li><p>bug fix (<strong>xinttools</strong>, <strong>xint</strong>, …): +forgotten catcode check of <code>"</code> at loading time has been +added.</p></li> </ul> <h2 id="j-20140109"><code>1.09j (2014/01/09)</code></h2> <ul> -<li><p>(<strong>xint</strong>) the core division routines have been re-written for some (limited) efficiency gain, more pronounced for small divisors. As a result the <em>computation of one thousand digits of <span class="math inline"><em>π</em></span></em> is close to three times faster than with earlier releases.</p></li> -<li><p>some various other small improvements, particularly in the power routines.</p></li> -<li><p>(<strong>xintfrac</strong>) a macro <code>\xintXTrunc</code> is designed to produce thousands or even tens of thousands of digits of the decimal expansion of a fraction. Although completely expandable it has its use limited to inside an <code>\edef</code>, <code>\write</code>, <code>\message</code>, . It can thus not be nested as argument to another package macro.</p></li> -<li><p>(<strong>xintexpr</strong>) the tacit multiplication done in <code>\xintexpr..\relax</code> on encountering a count register or variable, or a <code>\numexpr</code>, while scanning a (decimal) number, is extended to the case of a sub <code>\xintexpr</code>-ession.</p></li> -<li><p><code>\xintexpr</code> can now be used in an <code>\edef</code> with no <code>\xintthe</code> prefix; it will execute completely the computation, and the error message about a missing <code>\xintthe</code> will be inhibited. Previously, in the absence of <code>\xintthe</code>, expansion could only be a full one (with <code>\romannumeral-`0</code>), not a complete one (with <code>\edef</code>). Note that this differs from the behavior of the non-expandable <code>\numexpr</code>: <code>\the</code> or <code>\number</code> (or <code>\romannumeral</code>) are needed not only to print but also to trigger the computation, whereas <code>\xintthe</code> is mandatory only for the printing step.</p></li> -<li><p>the default behavior of <code>\xintAssign</code> is changed, it now does not do any further expansion beyond the initial full-expansion which provided the list of items to be assigned to macros.</p></li> -<li><p>bug fix (<strong>xintfrac</strong>): <code>1.09i</code> did an unexplainable change to <code>\XINT_infloat_zero</code> which broke the floating point routines for vanishing operands =:(((</p></li> -<li><p>bug fix: the <code>1.09i</code> <code>xint.ins</code> file produced a buggy <code>xint.tex</code> file.</p></li> +<li><p>(<strong>xint</strong>) the core division routines have been +re-written for some (limited) efficiency gain, more pronounced for small +divisors. As a result the <em>computation of one thousand digits of +<span class="math inline"><em>π</em></span></em> is close to three times +faster than with earlier releases.</p></li> +<li><p>some various other small improvements, particularly in the power +routines.</p></li> +<li><p>(<strong>xintfrac</strong>) a macro <code>\xintXTrunc</code> is +designed to produce thousands or even tens of thousands of digits of the +decimal expansion of a fraction. Although completely expandable it has +its use limited to inside an <code>\edef</code>, <code>\write</code>, +<code>\message</code>, . It can thus not be nested as argument to +another package macro.</p></li> +<li><p>(<strong>xintexpr</strong>) the tacit multiplication done in +<code>\xintexpr..\relax</code> on encountering a count register or +variable, or a <code>\numexpr</code>, while scanning a (decimal) number, +is extended to the case of a sub <code>\xintexpr</code>-ession.</p></li> +<li><p><code>\xintexpr</code> can now be used in an <code>\edef</code> +with no <code>\xintthe</code> prefix; it will execute completely the +computation, and the error message about a missing <code>\xintthe</code> +will be inhibited. Previously, in the absence of <code>\xintthe</code>, +expansion could only be a full one (with <code>\romannumeral-`0</code>), +not a complete one (with <code>\edef</code>). Note that this differs +from the behavior of the non-expandable <code>\numexpr</code>: +<code>\the</code> or <code>\number</code> (or +<code>\romannumeral</code>) are needed not only to print but also to +trigger the computation, whereas <code>\xintthe</code> is mandatory only +for the printing step.</p></li> +<li><p>the default behavior of <code>\xintAssign</code> is changed, it +now does not do any further expansion beyond the initial full-expansion +which provided the list of items to be assigned to macros.</p></li> +<li><p>bug fix (<strong>xintfrac</strong>): <code>1.09i</code> did an +unexplainable change to <code>\XINT_infloat_zero</code> which broke the +floating point routines for vanishing operands =:(((</p></li> +<li><p>bug fix: the <code>1.09i</code> <code>xint.ins</code> file +produced a buggy <code>xint.tex</code> file.</p></li> </ul> <h2 id="i-20131218"><code>1.09i (2013/12/18)</code></h2> <ul> -<li><p>(<strong>xintexpr</strong>) <code>\xintiiexpr</code> is a variant of <code>\xintexpr</code> which is optimized to deal only with (long) integers, <code>/</code> does a euclidean quotient.</p></li> -<li><p><em>deprecated</em>: <code>\xintnumexpr</code>, <code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code> are renamed, respectively, <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, <code>\xintNewIExpr</code>. The earlier denominations are kept but are to be removed at some point.</p></li> -<li><p>it is now possible within <code>\xintexpr...\relax</code> and its variants to use count, dimen, and skip registers or variables without explicit <code>\the/\number</code>: the parser inserts automatically <code>\number</code> and a tacit multiplication is implied when a register or variable immediately follows a number or fraction. Regarding dimensions and <code>\number</code>, see the further discussion in <em>Dimensions</em>.</p></li> -<li><p>(<strong>xintfrac</strong>) conditional <code>\xintifOne</code>; <code>\xintifTrueFalse</code> renamed to <code>\xintifTrueAelseB</code>; macros <code>\xintTFrac</code> (<code>fractional part</code>, mapped to function <code>frac</code> in <code>\xintexpr</code>-essions), <code>\xintFloatE</code>.</p></li> -<li><p>(<strong>xinttools</strong>) <code>\xintAssign</code> admits an optional argument to specify the expansion type to be used: <code>[]</code> (none, default), <code>[o]</code> (once), <code>[oo]</code> (twice), <code>[f]</code> (full), <code>[e]</code> (<code>\edef</code>),… to define the macros</p></li> -<li><p><strong>xinttools</strong> defines <code>\odef</code>, <code>\oodef</code>, <code>\fdef</code> (if the names have already been assigned, it uses <code>\xintoodef</code> etc…). These tools are provided for the case one uses the package macros in a non-expandable context. <code>\oodef</code> expands twice the macro replacement text, and <code>\fdef</code> applies full expansion. They are useful in situations where one does not want a full <code>\edef</code>. <code>\fdef</code> appears to be faster than <code>\oodef</code> in almost all cases (with less than thousand digits in the result), and even faster than <code>\edef</code> for expanding the package macros when the result has a few dozens of digits. <code>\oodef</code> needs that expansion ends up in thousands of digits to become competitive with the other two.</p></li> -<li><p>some across the board slight efficiency improvement as a result of modifications of various types to <em>fork macros</em> and <em>branching conditionals</em> which are used internally.</p></li> -<li><p>bug fix (<strong>xint</strong>): <code>\xintAND</code> and <code>\xintOR</code> inserted a space token in some cases and did not expand as promised in two steps <code>:-((</code> (bug dating back to <code>1.09a</code> I think; this bug was without consequences when using <code>&</code> and <code>|</code> in <code>\xintexpr-essions</code>, it affected only the macro form).</p></li> -<li><p>bug fix (<strong>xintcfrac</strong>): <code>\xintFtoCCv</code> still ended fractions with the <code>[0]</code>’s which were supposed to have been removed since release <code>1.09b</code>.</p></li> -<li><p><em>deprecated</em>: <code>\xintifTrueFalse</code>, <code>\xintifTrue</code>; use <code>\xintifTrueAelseB</code>.</p></li> +<li><p>(<strong>xintexpr</strong>) <code>\xintiiexpr</code> is a variant +of <code>\xintexpr</code> which is optimized to deal only with (long) +integers, <code>/</code> does a euclidean quotient.</p></li> +<li><p><em>deprecated</em>: <code>\xintnumexpr</code>, +<code>\xintthenumexpr</code>, <code>\xintNewNumExpr</code> are renamed, +respectively, <code>\xintiexpr</code>, <code>\xinttheiexpr</code>, +<code>\xintNewIExpr</code>. The earlier denominations are kept but are +to be removed at some point.</p></li> +<li><p>it is now possible within <code>\xintexpr...\relax</code> and its +variants to use count, dimen, and skip registers or variables without +explicit <code>\the/\number</code>: the parser inserts automatically +<code>\number</code> and a tacit multiplication is implied when a +register or variable immediately follows a number or fraction. Regarding +dimensions and <code>\number</code>, see the further discussion in +<em>Dimensions</em>.</p></li> +<li><p>(<strong>xintfrac</strong>) conditional <code>\xintifOne</code>; +<code>\xintifTrueFalse</code> renamed to <code>\xintifTrueAelseB</code>; +macros <code>\xintTFrac</code> (<code>fractional part</code>, mapped to +function <code>frac</code> in <code>\xintexpr</code>-essions), +<code>\xintFloatE</code>.</p></li> +<li><p>(<strong>xinttools</strong>) <code>\xintAssign</code> admits an +optional argument to specify the expansion type to be used: +<code>[]</code> (none, default), <code>[o]</code> (once), +<code>[oo]</code> (twice), <code>[f]</code> (full), <code>[e]</code> +(<code>\edef</code>),… to define the macros</p></li> +<li><p><strong>xinttools</strong> defines <code>\odef</code>, +<code>\oodef</code>, <code>\fdef</code> (if the names have already been +assigned, it uses <code>\xintoodef</code> etc…). These tools are +provided for the case one uses the package macros in a non-expandable +context. <code>\oodef</code> expands twice the macro replacement text, +and <code>\fdef</code> applies full expansion. They are useful in +situations where one does not want a full <code>\edef</code>. +<code>\fdef</code> appears to be faster than <code>\oodef</code> in +almost all cases (with less than thousand digits in the result), and +even faster than <code>\edef</code> for expanding the package macros +when the result has a few dozens of digits. <code>\oodef</code> needs +that expansion ends up in thousands of digits to become competitive with +the other two.</p></li> +<li><p>some across the board slight efficiency improvement as a result +of modifications of various types to <em>fork macros</em> and +<em>branching conditionals</em> which are used internally.</p></li> +<li><p>bug fix (<strong>xint</strong>): <code>\xintAND</code> and +<code>\xintOR</code> inserted a space token in some cases and did not +expand as promised in two steps <code>:-((</code> (bug dating back to +<code>1.09a</code> I think; this bug was without consequences when using +<code>&</code> and <code>|</code> in <code>\xintexpr-essions</code>, +it affected only the macro form).</p></li> +<li><p>bug fix (<strong>xintcfrac</strong>): <code>\xintFtoCCv</code> +still ended fractions with the <code>[0]</code>’s which were supposed to +have been removed since release <code>1.09b</code>.</p></li> +<li><p><em>deprecated</em>: <code>\xintifTrueFalse</code>, +<code>\xintifTrue</code>; use <code>\xintifTrueAelseB</code>.</p></li> </ul> <h2 id="h-20131128"><code>1.09h (2013/11/28)</code></h2> <ul> -<li><p>parts of the documentation have been re-written or re-organized, particularly the discussion of expansion issues and of input and output formats.</p></li> -<li><p>the expansion types of macro arguments are documented in the margin of the macro descriptions, with conventions mainly taken over from those in the <code>LaTeX3</code> documentation.</p></li> -<li><p>a dependency of <strong>xinttools</strong> on <strong>xint</strong> (inside <code>\xintSeq</code>) has been removed.</p></li> -<li><p>(<strong>xintgcd</strong>) <code>\xintTypesetEuclideAlgorithm</code> and <code>\xintTypesetBezoutAlgorithm</code> have been slightly modified (regarding indentation).</p></li> -<li><p>(<strong>xint</strong>) macros <code>xintiSum</code> and <code>xintiPrd</code> are renamed to <code>\xintiiSum</code> and <code>\xintiiPrd</code>.</p></li> -<li><p>(<strong>xinttools</strong>) a count register used in <code>1.09g</code> in the <code>\xintFor</code> loops for parsing purposes has been removed and replaced by use of a <code>\numexpr</code>.</p></li> -<li><p>the few uses of <code>\loop</code> have been replaced by <code>\xintloop/\xintiloop</code>.</p></li> -<li><p>all macros of <strong>xinttools</strong> for which it makes sense are now declared <code>\long</code>.</p></li> +<li><p>parts of the documentation have been re-written or re-organized, +particularly the discussion of expansion issues and of input and output +formats.</p></li> +<li><p>the expansion types of macro arguments are documented in the +margin of the macro descriptions, with conventions mainly taken over +from those in the <code>LaTeX3</code> documentation.</p></li> +<li><p>a dependency of <strong>xinttools</strong> on +<strong>xint</strong> (inside <code>\xintSeq</code>) has been +removed.</p></li> +<li><p>(<strong>xintgcd</strong>) +<code>\xintTypesetEuclideAlgorithm</code> and +<code>\xintTypesetBezoutAlgorithm</code> have been slightly modified +(regarding indentation).</p></li> +<li><p>(<strong>xint</strong>) macros <code>xintiSum</code> and +<code>xintiPrd</code> are renamed to <code>\xintiiSum</code> and +<code>\xintiiPrd</code>.</p></li> +<li><p>(<strong>xinttools</strong>) a count register used in +<code>1.09g</code> in the <code>\xintFor</code> loops for parsing +purposes has been removed and replaced by use of a +<code>\numexpr</code>.</p></li> +<li><p>the few uses of <code>\loop</code> have been replaced by +<code>\xintloop/\xintiloop</code>.</p></li> +<li><p>all macros of <strong>xinttools</strong> for which it makes sense +are now declared <code>\long</code>.</p></li> </ul> <h2 id="g-20131122"><code>1.09g (2013/11/22)</code></h2> <ul> -<li><p>a package <strong>xinttools</strong> is detached from <strong>xint</strong>, to make tools such as <code>\xintFor</code>, <code>\xintApplyUnbraced</code>, and <code>\xintiloop</code> available without the <strong>xint</strong> overhead.</p></li> -<li><p>expandable nestable loops <code>\xintloop</code> and <code>\xintiloop</code>.</p></li> -<li><p>bugfix: <code>\xintFor</code> and <code>\xintFor*</code> do not modify anymore the value of <code>\count 255</code>.</p></li> +<li><p>a package <strong>xinttools</strong> is detached from +<strong>xint</strong>, to make tools such as <code>\xintFor</code>, +<code>\xintApplyUnbraced</code>, and <code>\xintiloop</code> available +without the <strong>xint</strong> overhead.</p></li> +<li><p>expandable nestable loops <code>\xintloop</code> and +<code>\xintiloop</code>.</p></li> +<li><p>bugfix: <code>\xintFor</code> and <code>\xintFor*</code> do not +modify anymore the value of <code>\count 255</code>.</p></li> </ul> <h2 id="f-20131104"><code>1.09f (2013/11/04)</code></h2> <ul> -<li><p>(<strong>xint</strong>) <code>\xintZapFirstSpaces</code>, <code>\xintZapLastSpaces</code>, <code>\xintZapSpaces</code>, <code>\xintZapSpacesB</code>, for expandably stripping away leading and/or ending spaces.</p></li> -<li><p><code>\xintCSVtoList</code> by default uses <code>\xintZapSpacesB</code> to strip away spaces around commas (or at the start and end of the comma separated list).</p></li> -<li><p>also the <code>\xintFor</code> loop will strip out all spaces around commas and at the start and the end of its list argument; and similarly for <code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code>.</p></li> -<li><p><code>\xintFor</code> <em>et al.</em> accept all macro parameters from <code>#1</code> to <code>#9</code>.</p></li> -<li><p>for reasons of inner coherence some macros previously with one extra <code>i</code> in their names (e.g. <code>\xintiMON</code>) now have a doubled <code>ii</code> (<code>\xintiiMON</code>) to indicate that they skip the overhead of parsing their inputs via <code>\xintNum</code>. Macros with a <em>single</em> <code>i</code> such as <code>\xintiAdd</code> are those which maintain the non-<strong>xintfrac</strong> output format for big integers, but do parse their inputs via <code>\xintNum</code> (since release <code>1.09a</code>). They too may have doubled-<code>i</code> variants for matters of programming optimization when working only with (big) integers and not fractions or decimal numbers.</p></li> +<li><p>(<strong>xint</strong>) <code>\xintZapFirstSpaces</code>, +<code>\xintZapLastSpaces</code>, <code>\xintZapSpaces</code>, +<code>\xintZapSpacesB</code>, for expandably stripping away leading +and/or ending spaces.</p></li> +<li><p><code>\xintCSVtoList</code> by default uses +<code>\xintZapSpacesB</code> to strip away spaces around commas (or at +the start and end of the comma separated list).</p></li> +<li><p>also the <code>\xintFor</code> loop will strip out all spaces +around commas and at the start and the end of its list argument; and +similarly for <code>\xintForpair</code>, <code>\xintForthree</code>, +<code>\xintForfour</code>.</p></li> +<li><p><code>\xintFor</code> <em>et al.</em> accept all macro parameters +from <code>#1</code> to <code>#9</code>.</p></li> +<li><p>for reasons of inner coherence some macros previously with one +extra <code>i</code> in their names (e.g. <code>\xintiMON</code>) now +have a doubled <code>ii</code> (<code>\xintiiMON</code>) to indicate +that they skip the overhead of parsing their inputs via +<code>\xintNum</code>. Macros with a <em>single</em> <code>i</code> such +as <code>\xintiAdd</code> are those which maintain the +non-<strong>xintfrac</strong> output format for big integers, but do +parse their inputs via <code>\xintNum</code> (since release +<code>1.09a</code>). They too may have doubled-<code>i</code> variants +for matters of programming optimization when working only with (big) +integers and not fractions or decimal numbers.</p></li> </ul> <h2 id="e-20131029"><code>1.09e (2013/10/29)</code></h2> <ul> -<li><p>(<strong>xint</strong>) <code>\xintintegers</code>, <code>\xintdimensions</code>, <code>\xintrationals</code> for infinite <code>\xintFor</code> loops, interrupted with <code>\xintBreakFor</code> and <code>\xintBreakForAndDo</code>.</p></li> -<li><p><code>\xintifForFirst</code>, <code>\xintifForLast</code> for the <code>\xintFor</code> and <code>\xintFor*</code> loops,</p></li> -<li><p>the <code>\xintFor</code> and <code>xintFor*</code> loops are now <code>\long</code>, the replacement text and the items may contain explicit <code>\par</code>’s.</p></li> -<li><p>conditionals <code>\xintifCmp</code>, <code>\xintifInt</code>, <code>\xintifOdd</code>.</p></li> -<li><p>bug fix (<strong>xint</strong>): the <code>\xintFor</code> loop (not <code>\xintFor*</code>) did not correctly detect an empty list.</p></li> -<li><p>bug fix (<strong>xint</strong>): <code>\xintiSqrt {0}</code> crashed. <code>:-((</code></p></li> -<li><p>the documentation has been enriched with various additional examples, such as the <em>the quick sort algorithm illustrated</em> or the various ways of <em>computing prime numbers</em>.</p></li> -<li><p>the documentation explains with more details various expansion related issues, particularly in relation to conditionals.</p></li> +<li><p>(<strong>xint</strong>) <code>\xintintegers</code>, +<code>\xintdimensions</code>, <code>\xintrationals</code> for infinite +<code>\xintFor</code> loops, interrupted with <code>\xintBreakFor</code> +and <code>\xintBreakForAndDo</code>.</p></li> +<li><p><code>\xintifForFirst</code>, <code>\xintifForLast</code> for the +<code>\xintFor</code> and <code>\xintFor*</code> loops,</p></li> +<li><p>the <code>\xintFor</code> and <code>xintFor*</code> loops are now +<code>\long</code>, the replacement text and the items may contain +explicit <code>\par</code>’s.</p></li> +<li><p>conditionals <code>\xintifCmp</code>, <code>\xintifInt</code>, +<code>\xintifOdd</code>.</p></li> +<li><p>bug fix (<strong>xint</strong>): the <code>\xintFor</code> loop +(not <code>\xintFor*</code>) did not correctly detect an empty +list.</p></li> +<li><p>bug fix (<strong>xint</strong>): <code>\xintiSqrt {0}</code> +crashed. <code>:-((</code></p></li> +<li><p>the documentation has been enriched with various additional +examples, such as the <em>the quick sort algorithm illustrated</em> or +the various ways of <em>computing prime numbers</em>.</p></li> +<li><p>the documentation explains with more details various expansion +related issues, particularly in relation to conditionals.</p></li> </ul> <h2 id="d-20131022"><code>1.09d (2013/10/22)</code></h2> <ul> -<li><p>bug fix (<strong>xint</strong>): <code>\xintFor*</code> is modified to gracefully handle a space token (or more than one) located at the very end of its list argument (as the space before <code>\do</code> in <code>\xintFor* #1 in {{a}{b}{c}<space>} \do {stuff}</code>; spaces at other locations were already harmless). Furthermore this new version <em>f-expands</em> the un-braced list items. After <code>\def\x{{1}{2}}</code> and <code>\def\y{{a}\x {b}{c}\x }</code>, <code>\y</code> will appear to <code>\xintFor*</code> exactly as if it had been defined as <code>\def\y{{a}{1}{2}{b}{c}{1}{2}}</code>.</p></li> +<li><p>bug fix (<strong>xint</strong>): <code>\xintFor*</code> is +modified to gracefully handle a space token (or more than one) located +at the very end of its list argument (as the space before +<code>\do</code> in +<code>\xintFor* #1 in {{a}{b}{c}<space>} \do {stuff}</code>; +spaces at other locations were already harmless). Furthermore this new +version <em>f-expands</em> the un-braced list items. After +<code>\def\x{{1}{2}}</code> and +<code>\def\y{{a}\x {b}{c}\x }</code>, <code>\y</code> will appear to +<code>\xintFor*</code> exactly as if it had been defined as +<code>\def\y{{a}{1}{2}{b}{c}{1}{2}}</code>.</p></li> <li><p>same bug fix for <code>\xintApplyInline</code>.</p></li> </ul> <h2 id="c-20131009"><code>1.09c (2013/10/09)</code></h2> <ul> -<li><p>(<strong>xintexpr</strong>) added <code>bool</code> and <code>togl</code> to the <code>\xintexpr</code> syntax; also added <code>\xintboolexpr</code> and <code>\xintifboolexpr</code>.</p></li> +<li><p>(<strong>xintexpr</strong>) added <code>bool</code> and +<code>togl</code> to the <code>\xintexpr</code> syntax; also added +<code>\xintboolexpr</code> and <code>\xintifboolexpr</code>.</p></li> <li><p>added <code>\xintNewNumExpr</code>.</p></li> -<li><p>the factorial <code>!</code> and branching <code>?</code>, <code>:</code>, operators (in <code>\xintexpr...\relax</code>) have now less precedence than a function name located just before,</p></li> -<li><p>(<strong>xint</strong>) <code>\xintFor</code> is a new type of loop, whose replacement text inserts the comma separated values or list items via macro parameters, rather than encapsulated in macros; the loops are nestable up to four levels (nine levels since <code>1.09f</code>) and their replacement texts are allowed to close groups as happens with the tabulation in alignments,</p></li> -<li><p><code>\xintForpair</code>, <code>\xintForthree</code>, <code>\xintForfour</code> are experimental variants of <code>\xintFor</code>,</p></li> -<li><p><code>\xintApplyInline</code> has been enhanced in order to be usable for generating rows (partially or completely) in an alignment,</p></li> -<li><p>command <code>\xintSeq</code> to generate (expandably) arithmetic sequences of (short) integers,</p></li> -<li><p>again various improvements and changes in the documentation.</p></li> +<li><p>the factorial <code>!</code> and branching <code>?</code>, +<code>:</code>, operators (in <code>\xintexpr...\relax</code>) have now +less precedence than a function name located just before,</p></li> +<li><p>(<strong>xint</strong>) <code>\xintFor</code> is a new type of +loop, whose replacement text inserts the comma separated values or list +items via macro parameters, rather than encapsulated in macros; the +loops are nestable up to four levels (nine levels since +<code>1.09f</code>) and their replacement texts are allowed to close +groups as happens with the tabulation in alignments,</p></li> +<li><p><code>\xintForpair</code>, <code>\xintForthree</code>, +<code>\xintForfour</code> are experimental variants of +<code>\xintFor</code>,</p></li> +<li><p><code>\xintApplyInline</code> has been enhanced in order to be +usable for generating rows (partially or completely) in an +alignment,</p></li> +<li><p>command <code>\xintSeq</code> to generate (expandably) arithmetic +sequences of (short) integers,</p></li> +<li><p>again various improvements and changes in the +documentation.</p></li> </ul> <h2 id="b-20131003"><code>1.09b (2013/10/03)</code></h2> <ul> <li><p>various improvements in the documentation,</p></li> -<li><p>more economical catcode management and re-loading handling,</p></li> -<li><p>removal of all those <code>[0]</code>’s previously forcefully added at the end of fractions by various macros of <strong>xintcfrac</strong>,</p></li> -<li><p><code>\xintNthElt</code> with a negative index returns from the tail of the list,</p></li> -<li><p>macro <code>\xintPRaw</code> to have something like what <code>\xintFrac</code> does in math mode; i.e. a <code>\xintRaw</code> which does not print the denominator if it is one.</p></li> +<li><p>more economical catcode management and re-loading +handling,</p></li> +<li><p>removal of all those <code>[0]</code>’s previously forcefully +added at the end of fractions by various macros of +<strong>xintcfrac</strong>,</p></li> +<li><p><code>\xintNthElt</code> with a negative index returns from the +tail of the list,</p></li> +<li><p>macro <code>\xintPRaw</code> to have something like what +<code>\xintFrac</code> does in math mode; i.e. a <code>\xintRaw</code> +which does not print the denominator if it is one.</p></li> </ul> <h2 id="a-20130924"><code>1.09a (2013/09/24)</code></h2> <ul> -<li><p>(<strong>xintexpr</strong>) <code>\xintexpr..\relax</code> and <code>\xintfloatexpr..\relax</code> admit functions in their syntax, with comma separated values as arguments, among them <code>reduce, sqr, sqrt, abs, sgn, floor, ceil, quo, rem, round, trunc, float, gcd, lcm, max, min, sum, prd, add, mul, not, all, any, xor</code>.</p></li> -<li><p>comparison (<code><</code>, <code>></code>, <code>=</code>) and logical (<code>|</code>, <code>&</code>) operators.</p></li> -<li><p>the command <code>\xintthe</code> which converts <code>\xintexpr</code>essions into printable format (like <code>\the</code> with <code>\numexpr</code>) is more efficient, for example one can do <code>\xintthe\x</code> if <code>\x</code> was defined to be an <code>\xintexpr..\relax</code>:</p> +<li><p>(<strong>xintexpr</strong>) <code>\xintexpr..\relax</code> and +<code>\xintfloatexpr..\relax</code> admit functions in their syntax, +with comma separated values as arguments, among them +<code>reduce, sqr, sqrt, abs, sgn, floor, ceil, quo, rem, round, trunc, float, gcd, lcm, max, min, sum, prd, add, mul, not, all, any, xor</code>.</p></li> +<li><p>comparison (<code><</code>, <code>></code>, <code>=</code>) +and logical (<code>|</code>, <code>&</code>) operators.</p></li> +<li><p>the command <code>\xintthe</code> which converts +<code>\xintexpr</code>essions into printable format (like +<code>\the</code> with <code>\numexpr</code>) is more efficient, for +example one can do <code>\xintthe\x</code> if <code>\x</code> was +defined to be an <code>\xintexpr..\relax</code>:</p> <pre><code>\def\x{\xintexpr 3^57\relax} \def\y{\xintexpr \x^(-2)\relax} \def\z{\xintexpr \y-3^-114\relax} \xintthe\z</code></pre></li> -<li><p><code>\xintnumexpr .. \relax</code> (now renamed <code>\xintiexpr</code>) is <code>\xintexpr round( .. ) \relax</code>.</p></li> -<li><p><code>\xintNewExpr</code> now works with the standard macro parameter character <code>#</code>.</p></li> -<li><p>both regular <code>\xintexpr</code>-essions and commands defined by <code>\xintNewExpr</code> will work with comma separated lists of expressions,</p></li> -<li><p>commands <code>\xintFloor</code>, <code>\xintCeil</code>, <code>\xintMaxof</code>, <code>\xintMinof</code> (package <strong>xintfrac</strong>), <code>\xintGCDof</code>, <code>\xintLCM</code>, <code>\xintLCMof</code> (package <strong>xintgcd</strong>), <code>\xintifLt</code>, <code>\xintifGt</code>, <code>\xintifSgn</code>, <code>\xintANDof</code>, …</p></li> -<li><p>The arithmetic macros from package <strong>xint</strong> now filter their operands via <code>\xintNum</code> which means that they may use directly count registers and <code>\numexpr</code>-essions without having to prefix them by <code>\the</code>. This is thus similar to the situation holding previously already when <strong>xintfrac</strong> was loaded.</p></li> -<li><p>a bug (<strong>xintfrac</strong>) introduced in <code>1.08b</code> made <code>\xintCmp</code> crash when one of its arguments was zero. <code>:-((</code></p></li> +<li><p><code>\xintnumexpr .. \relax</code> (now renamed +<code>\xintiexpr</code>) is +<code>\xintexpr round( .. ) \relax</code>.</p></li> +<li><p><code>\xintNewExpr</code> now works with the standard macro +parameter character <code>#</code>.</p></li> +<li><p>both regular <code>\xintexpr</code>-essions and commands defined +by <code>\xintNewExpr</code> will work with comma separated lists of +expressions,</p></li> +<li><p>commands <code>\xintFloor</code>, <code>\xintCeil</code>, +<code>\xintMaxof</code>, <code>\xintMinof</code> (package +<strong>xintfrac</strong>), <code>\xintGCDof</code>, +<code>\xintLCM</code>, <code>\xintLCMof</code> (package +<strong>xintgcd</strong>), <code>\xintifLt</code>, +<code>\xintifGt</code>, <code>\xintifSgn</code>, +<code>\xintANDof</code>, …</p></li> +<li><p>The arithmetic macros from package <strong>xint</strong> now +filter their operands via <code>\xintNum</code> which means that they +may use directly count registers and <code>\numexpr</code>-essions +without having to prefix them by <code>\the</code>. This is thus similar +to the situation holding previously already when +<strong>xintfrac</strong> was loaded.</p></li> +<li><p>a bug (<strong>xintfrac</strong>) introduced in +<code>1.08b</code> made <code>\xintCmp</code> crash when one of its +arguments was zero. <code>:-((</code></p></li> </ul> <h2 id="b-20130614"><code>1.08b (2013/06/14)</code></h2> <ul> -<li><p>(<strong>xintexpr</strong>) Correction of a problem with spaces inside <code>\xintexpr</code>-essions.</p></li> -<li><p>(<strong>xintfrac</strong>) Additional improvements to the handling of floating point numbers.</p></li> -<li><p>section <em>Use of count registers</em> documenting how count registers may be directly used in arguments to the macros of <strong>xintfrac</strong>.</p></li> +<li><p>(<strong>xintexpr</strong>) Correction of a problem with spaces +inside <code>\xintexpr</code>-essions.</p></li> +<li><p>(<strong>xintfrac</strong>) Additional improvements to the +handling of floating point numbers.</p></li> +<li><p>section <em>Use of count registers</em> documenting how count +registers may be directly used in arguments to the macros of +<strong>xintfrac</strong>.</p></li> </ul> <h2 id="a-20130611"><code>1.08a (2013/06/11)</code></h2> <ul> -<li><p>(<strong>xintfrac</strong>) Improved efficiency of the basic conversion from exact fractions to floating point numbers, with ensuing speed gains especially for the power function macros <code>\xintFloatPow</code> and <code>\xintFloatPower</code>,</p></li> -<li><p>Better management by <code>\xintCmp</code>, <code>\xintMax</code>, <code>\xintMin</code> and <code>\xintGeq</code> of inputs having big powers of ten in them.</p></li> -<li><p>Macros for floating point numbers added to the <strong>xintseries</strong> package.</p></li> +<li><p>(<strong>xintfrac</strong>) Improved efficiency of the basic +conversion from exact fractions to floating point numbers, with ensuing +speed gains especially for the power function macros +<code>\xintFloatPow</code> and <code>\xintFloatPower</code>,</p></li> +<li><p>Better management by <code>\xintCmp</code>, +<code>\xintMax</code>, <code>\xintMin</code> and <code>\xintGeq</code> +of inputs having big powers of ten in them.</p></li> +<li><p>Macros for floating point numbers added to the +<strong>xintseries</strong> package.</p></li> </ul> <h2 id="section-4"><code>1.08 (2013/06/07)</code></h2> <ul> -<li><p>(<strong>xint</strong> and <strong>xintfrac</strong>) Macros for extraction of square roots, for floating point numbers (<code>\xintFloatSqrt</code>), and integers (<code>\xintiSqrt</code>).</p></li> -<li><p>new package <strong>xintbinhex</strong> providing <em>conversion routines</em> to and from binary and hexadecimal bases.</p></li> +<li><p>(<strong>xint</strong> and <strong>xintfrac</strong>) Macros for +extraction of square roots, for floating point numbers +(<code>\xintFloatSqrt</code>), and integers +(<code>\xintiSqrt</code>).</p></li> +<li><p>new package <strong>xintbinhex</strong> providing <em>conversion +routines</em> to and from binary and hexadecimal bases.</p></li> </ul> <h2 id="section-5"><code>1.07 (2013/05/25)</code></h2> <ul> -<li><p>The <strong>xintexpr</strong> package is a new core constituent (which loads automatically <strong>xintfrac</strong> and <strong>xint</strong>) and implements the expandable expanding parser</p> +<li><p>The <strong>xintexpr</strong> package is a new core constituent +(which loads automatically <strong>xintfrac</strong> and +<strong>xint</strong>) and implements the expandable expanding +parser</p> <pre><code>\xintexpr . . . \relax,</code></pre> <p>and its variant</p> <pre><code>\xintfloatexpr . . . \relax</code></pre> -<p>allowing on input formulas using the infix operators <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>, and arbitrary levels of parenthesizing. Within a float expression the operations are executed according to the current value set by <code>\xintDigits</code>. Within an <code>\xintexpr</code>-ession the binary operators are computed exactly.</p> -<p>To write the <code>\xintexpr</code> parser I benefited from the commented source of the <code>l3fp</code> parser; the <code>\xintexpr</code> parser has its own features and peculiarities. <em>See its documentation</em>.</p></li> -<li><p>The floating point precision <code>D</code> is set (this is a local assignment to a <code>\mathchar</code> variable) with <code>\xintDigits := D;</code> and queried with <code>\xinttheDigits</code>. It may be set to anything up to <code>32767</code>.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a> The macro incarnations of the binary operations admit an optional argument which will replace pointwise <code>D</code>; this argument may exceed the <code>32767</code> bound.</p></li> -<li><p>The <strong>xintfrac</strong> macros now accept numbers written in scientific notation, the <code>\xintFloat</code> command serves to output its argument with a given number <code>D</code> of significant figures. The value of <code>D</code> is either given as optional argument to <code>\xintFloat</code> or set with <code>\xintDigits := D;</code>. The default value is <code>16</code>.</p></li> +<p>allowing on input formulas using the infix operators <code>+</code>, +<code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>, and +arbitrary levels of parenthesizing. Within a float expression the +operations are executed according to the current value set by +<code>\xintDigits</code>. Within an <code>\xintexpr</code>-ession the +binary operators are computed exactly.</p> +<p>To write the <code>\xintexpr</code> parser I benefited from the +commented source of the <code>l3fp</code> parser; the +<code>\xintexpr</code> parser has its own features and peculiarities. +<em>See its documentation</em>.</p></li> +<li><p>The floating point precision <code>D</code> is set (this is a +local assignment to a <code>\mathchar</code> variable) with +<code>\xintDigits := D;</code> and queried with +<code>\xinttheDigits</code>. It may be set to anything up to +<code>32767</code>.<a href="#fn1" class="footnote-ref" id="fnref1" +role="doc-noteref"><sup>1</sup></a> The macro incarnations of the binary +operations admit an optional argument which will replace pointwise +<code>D</code>; this argument may exceed the <code>32767</code> +bound.</p></li> +<li><p>The <strong>xintfrac</strong> macros now accept numbers written +in scientific notation, the <code>\xintFloat</code> command serves to +output its argument with a given number <code>D</code> of significant +figures. The value of <code>D</code> is either given as optional +argument to <code>\xintFloat</code> or set with +<code>\xintDigits := D;</code>. The default value is +<code>16</code>.</p></li> </ul> <h2 id="b-20130514"><code>1.06b (2013/05/14)</code></h2> <ul> -<li>Minor code and documentation improvements. Everywhere in the source code, a more modern underscore has replaced the @ sign.</li> +<li>Minor code and documentation improvements. Everywhere in the source +code, a more modern underscore has replaced the @ sign.</li> </ul> <h2 id="section-6"><code>1.06 (2013/05/07)</code></h2> <ul> -<li><p>Some code improvements, particularly for macros of <strong>xint</strong> doing loops.</p></li> -<li><p>New utilities in <strong>xint</strong> for expandable manipulations of lists:</p> +<li><p>Some code improvements, particularly for macros of +<strong>xint</strong> doing loops.</p></li> +<li><p>New utilities in <strong>xint</strong> for expandable +manipulations of lists:</p> <pre><code>\xintNthElt, \xintCSVtoList, \xintRevWithBraces</code></pre></li> -<li><p>The macros did only a double expansion of their arguments. They now fully expand them (using <code>\romannumeral-`0</code>). Furthermore, in the case of arguments constrained to obey the TeX bounds they will be inserted inside a <code>\numexpr..\relax</code>, hence completely expanded, one may use count registers, even infix arithmetic operations, etc…</p></li> +<li><p>The macros did only a double expansion of their arguments. They +now fully expand them (using <code>\romannumeral-`0</code>). +Furthermore, in the case of arguments constrained to obey the TeX bounds +they will be inserted inside a <code>\numexpr..\relax</code>, hence +completely expanded, one may use count registers, even infix arithmetic +operations, etc…</p></li> </ul> <h2 id="section-7"><code>1.05 (2013/05/01)</code></h2> -<p>Minor changes and additions to <strong>xintfrac</strong> and <strong>xintcfrac</strong>.</p> +<p>Minor changes and additions to <strong>xintfrac</strong> and +<strong>xintcfrac</strong>.</p> <h2 id="section-8"><code>1.04 (2013/04/25)</code></h2> <ul> -<li><p>New component <strong>xintcfrac</strong> devoted to continued fractions.</p></li> +<li><p>New component <strong>xintcfrac</strong> devoted to continued +fractions.</p></li> <li><p><strong>xint</strong>: faster division.</p></li> -<li><p><strong>xint</strong>: added expandable macros <code>\xintListWithSep</code> and <code>\xintApply</code> to handle token lists.</p></li> -<li><p><strong>xintfrac</strong>: added <code>\xintRound</code>.</p></li> -<li><p><strong>xintseries</strong> has a new implementation of <code>\xintPowerSeries</code> based on a Horner scheme, and new macro <code>\xintRationalSeries</code>. Both to help deal with the <em>denominator buildup</em> plague.</p></li> -<li><p><code>tex xint.dtx</code> extracts style files (no need for a <code>xint.ins</code>).</p></li> -<li><p>Bug fix (<strong>xintfrac</strong>): <code>\xintIrr {0}</code> crashed.</p></li> +<li><p><strong>xint</strong>: added expandable macros +<code>\xintListWithSep</code> and <code>\xintApply</code> to handle +token lists.</p></li> +<li><p><strong>xintfrac</strong>: added +<code>\xintRound</code>.</p></li> +<li><p><strong>xintseries</strong> has a new implementation of +<code>\xintPowerSeries</code> based on a Horner scheme, and new macro +<code>\xintRationalSeries</code>. Both to help deal with the +<em>denominator buildup</em> plague.</p></li> +<li><p><code>tex xint.dtx</code> extracts style files (no need for a +<code>xint.ins</code>).</p></li> +<li><p>Bug fix (<strong>xintfrac</strong>): <code>\xintIrr {0}</code> +crashed.</p></li> </ul> <h2 id="section-9"><code>1.03 (2013/04/14)</code></h2> <ul> -<li><p>New modules <strong>xintfrac</strong> (expandable operations on fractions) and <strong>xintseries</strong> (expandable partial sums with xint package).</p></li> -<li><p>Slightly improved division and faster multiplication (the best ordering of the arguments is chosen automatically).</p></li> -<li><p>Added illustration of Machin algorithm to the documentation.</p></li> +<li><p>New modules <strong>xintfrac</strong> (expandable operations on +fractions) and <strong>xintseries</strong> (expandable partial sums with +xint package).</p></li> +<li><p>Slightly improved division and faster multiplication (the best +ordering of the arguments is chosen automatically).</p></li> +<li><p>Added illustration of Machin algorithm to the +documentation.</p></li> </ul> <h2 id="section-10"><code>1.0 (2013/03/28)</code></h2> <p>Initial announcement:</p> <blockquote> -<p>The <strong>xint</strong> package implements with expandable TeX macros the basic arithmetic operations of addition, subtraction, multiplication and division, as applied to arbitrarily long numbers represented as chains of digits with an optional minus sign.</p> +<p>The <strong>xint</strong> package implements with expandable TeX +macros the basic arithmetic operations of addition, subtraction, +multiplication and division, as applied to arbitrarily long numbers +represented as chains of digits with an optional minus sign.</p> </blockquote> <blockquote> -<p>The <strong>xintgcd</strong> package provides implementations of the Euclidean algorithm and of its typesetting.</p> +<p>The <strong>xintgcd</strong> package provides implementations of the +Euclidean algorithm and of its typesetting.</p> </blockquote> <blockquote> <p>The packages may be used with Plain and with LaTeX.</p> </blockquote> -<section class="footnotes"> +<section class="footnotes footnotes-end-of-document" +role="doc-endnotes"> <hr /> <ol> -<li id="fn1"><p>but values higher than 100 or 200 will presumably give too slow evaluations.<a href="#fnref1" class="footnote-back">↩</a></p></li> +<li id="fn1" role="doc-endnote"><p>but values higher than 100 or 200 +will presumably give too slow evaluations.<a href="#fnref1" +class="footnote-back" role="doc-backlink">↩︎</a></p></li> </ol> </section> </body> diff --git a/Master/texmf-dist/doc/generic/xint/README.md b/Master/texmf-dist/doc/generic/xint/README.md index bd83ddc429f..26efec3af43 100644 --- a/Master/texmf-dist/doc/generic/xint/README.md +++ b/Master/texmf-dist/doc/generic/xint/README.md @@ -1,8 +1,8 @@ % README -% xint 1.4j -% 2021/07/13 +% xint 1.4k +% 2022/05/18 - Source: xint.dtx 1.4j 2021/07/13 (doc 2021/07/13) + Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c @@ -92,7 +92,7 @@ is a functionality of all major TeX engines since TeXLive 2019. License ======= -Copyright (C) 2013-2021 by Jean-Francois Burnol +Copyright (C) 2013-2022 by Jean-Francois Burnol This Work may be distributed and/or modified under the conditions of the LaTeX Project Public License version 1.3c. diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf Binary files differindex 41147e734da..559adccd364 100644 --- a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf +++ b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf diff --git a/Master/texmf-dist/doc/generic/xint/xint.pdf b/Master/texmf-dist/doc/generic/xint/xint.pdf Binary files differindex f9d5b3bb032..52f8052d930 100644 --- a/Master/texmf-dist/doc/generic/xint/xint.pdf +++ b/Master/texmf-dist/doc/generic/xint/xint.pdf diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx index a1ad014bc22..213000e7521 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -3,28 +3,28 @@ % Extract all files via "etex xint.dtx" and do "make help" % or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <13-07-2021 at 21:50:14 CEST>} +\def\xintdtxtimestamp {Time-stamp: <18-05-2022 at 20:55:23 CEST>} %</dtx> %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2021/07/13} -\def\xintbndldate{2021/07/13} -\def\xintbndlversion {1.4j} +\def\xintdocdate {2022/05/18} +\def\xintbndldate{2022/05/18} +\def\xintbndlversion {1.4k} %</drv> %<readme>% README %<changes>% CHANGE LOG -%<readme|changes>% xint 1.4j -%<readme|changes>% 2021/07/13 +%<readme|changes>% xint 1.4k +%<readme|changes>% 2022/05/18 %<readme|changes> -%<readme|changes> Source: xint.dtx 1.4j 2021/07/13 (doc 2021/07/13) +%<readme|changes> Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) %<readme|changes> Author: Jean-Francois Burnol %<readme|changes> Info: Expandable operations on big integers, decimals, fractions %<readme|changes> License: LPPL 1.3c %<readme|changes> %<*!readme&!changes&!dohtmlsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %<xintkernel>%% xintkernel: Paraphernalia for the xint packages %<xinttools>%% xinttools: Expandable and non-expandable utilities %<xintcore>%% xintcore: Expandable arithmetic on big integers @@ -128,7 +128,7 @@ is a functionality of all major TeX engines since TeXLive 2019. License ======= -Copyright (C) 2013-2021 by Jean-Francois Burnol +Copyright (C) 2013-2022 by Jean-Francois Burnol This Work may be distributed and/or modified under the conditions of the LaTeX Project Public License version 1.3c. @@ -152,6 +152,69 @@ See `xint.pdf` for contact information. %</readme>-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.4k (2022/05/18)` +---- + +### Breaking changes + + - **xintfrac**: the longstanding (but documented as undecided and + unstable) way of `\xintFloat` to output the zero value was `0.e0` and + it has now been modified into `0.0e0`. Customizable via + `\xintFloatZero`. + + - **xintfrac**/**xintexpr**: the behaviour of `\xintPFloat` (hence of + `\xintfloateval`) has again changed: when the output is an integer + (not using scientific notation) it does not get postfixed by `.0`. + This applies in particular for the zero value, now printed `0`. + Similarly, in the case of scientific notation with a single-digit + (trimmed) mantissa, no `.0` is used. + + Customizable via + `\xintPFloatIntSuffix`, `\xintPFloatLengthOneSuffix`, and + `\xintPFloatZero`. + + Also, `\xintPFloat` trims trailing zeros from the + full significand only if there are at least `4` of them, see + `\xintPFloatMinTrimmed`. + + - **xintfrac**/**xintexpr**: definition of `\xintFracToSci` migrated + from the former to the latter. + + - **xintexpr**: `\xintexpr{Safe,Restore}Catcodes` pairs now behave like + a "last in first out" stack. Check the `pdf` documentation for + details. + +### Bug fixes + + - **xintexpr**: the `\xintexpr{Safe,Restore}Catcodes` were documented + at user level, but also used by the package `\xintdefvar` or + `\xintdeffunc`. This could result in some bad interaction due to the + somewhat strange (but documented) behaviour of nested + `\xintexpr{Safe,Restore}Catcodes` (which has now been modified). + + - **xintexpr**: ever since `1.4`, `\xintdefufunc` (but not + `\xintdeffunc`) forgot to reset the catcodes to their status prior to + the sanitization done by the macro at the start of its execution. + +### New features + + - **xintfrac**: `\xintPFloatZero`, `\xintPFloatIntSuffix`, + `\xintPFloatLengthOneSuffix`, `\xintPFloatNoSciEmax`, + `\xintPFloatNoSciEmin` and `\xintPFloatMinTrimmed` customize the + output of `\xintPFloat`, hence also of `\xintfloateval` (and of + `\xinteval` when scientific notation was used in the expression). + Also added `\xintFloatZero`. + + - **xintfrac**: `\xintFloatToDecimal`. + + - **xintexpr**: `\xintFracToDecimal`, an alternative to + `\xintFracToSci` for the configuration of `\xintexprPrintOne`. + + - **xintexpr**: long awaited syntax `\xintieval[D]{...}` and + `\xintfloateval[Q]{...}` now implemented. The legacy syntax with + `\xintieval{[D]...}` and `\xintfloateval{[Q]...}` is kept for + backwards compatibility. + `1.4j (2021/07/13)` ---- @@ -2724,16 +2787,21 @@ cleanall: clean #! /bin/sh # <s>README.html and</s> CHANGES.html from <s>README.md and </s>CHANGES.md # tested with pandoc 1.13.1 +# updated 2022 for usage with pandoc 2.18 and its strange CSS obsessed by mobile devices # pandoc -o README.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 12pt;} # pre {white-space: pre-wrap; } # code {white-space: pre-wrap; } # .mono {font-family: monospace;}' README.md -pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 12pt;} +pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin-left : 10%; margin-right : 15%; margin-top: 4ex; font-size: 20px; font-family: serif; max-width: 100%; padding: 0; } pre {white-space: pre-wrap;} code {white-space: pre-wrap;} - #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px;}' CHANGES.md + a:link { color: blue; } + a:visited { color: green; } + a:hover { text-decoration: underline; color: hotpink } + a:active { color: brown; } + #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px; margin-left: 20px;}' CHANGES.md %</dohtmlsh>------------------------------------------------------ %<*drv>----------------------------------------------------------- @@ -2993,17 +3061,64 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; \usepackage[autolanguage,np]{numprint} \AtBeginDocument{\npthousandsep{,\hskip .5pt plus .1pt minus .1pt}} -\usepackage[dvipsnames]{xcolor} -\definecolor{joli}{RGB}{225,95,0} -\definecolor{JOLI}{RGB}{225,95,0} -\definecolor{BLUE}{RGB}{0,0,255} -\definecolor{niceone}{RGB}{38,128,192} -\definecolor{sedate}{RGB}{193,132,1} -\definecolor{saddlebrown}{rgb}{.545,.27,.075} -\definecolor{jfbrown}{RGB}{165,100,10}% - - - +\usepackage[dvipsnames,svgnames]{xcolor} +\definecolor{xintnamecolor}{RGB}{228,57,0} +\colorlet{XINTNAMECOLOR}{xintnamecolor} +\colorlet{xintnameimpcolor}{blue} +\colorlet{XINTNAMEIMPCOLOR}{xintnameimpcolor} +\definecolor{xintmanualurlcolor}{RGB}{38,128,192} +\colorlet{xintmanuallinkcolor}{blue} + + + + +% Colors for \verb and everbatim/everbatim* environments +% former legacy colors used in xint.pdf up to xint 1.4j (2021/07/13) +% (I should retrieve since when) +% \colorlet{verbcolor}{jfbrown} +% \colorlet{verbsoftwrapiconcolor}{blue} +% \colorlet{everbatimfgcolor}{Brown} +% \colorlet{everbatimbgcolor}{yellow!5} +% \colorlet{everbatimxfgcolor}{OrangeRed} + +% https://contrast-ratio.com/#rgb%28165%2C100%2C10%29-on-white +% says the contrast ratio on white is 4.74 and I do see the contrast +% is less strong than +% for the DarkBlue/Beige and Maroon/White combinations seen below +% \colorlet{verbcolor}{jfbrown} +% I will simply use also Maroon +\colorlet{verbcolor}{Maroon} +\colorlet{verbimpcolor}{Purple} +\colorlet{digitsttcolor}{Maroon} + +\colorlet{verbsoftwrapiconcolor}{DarkBlue} +\colorlet{everbatimfgcolor}{DarkBlue} +% +% According to +% https://contrast-ratio.com/#rgb%2811%2C35%2C139%29-on-rgb%28245%2C244%2C220%29 +% the DarkBlue on Beige +% gives a contrast-ratio of 11.58 which confirmed my intuition it is not bad +% "Passes AAA level for any size text and AA for user interface components and graphical objects" +% +% memo: with Apple ColorPicker it seems one needs to select "sRVB" (I guess +% "sRGB" in English) for values matching xcolor RGB input or the above html +% page rgb(R,G,B) input, also this did not work +% 100%, most probably due to the window transparency by default on my mac? +\colorlet{everbatimbgcolor}{Beige} + +% https://contrast-ratio.com/#rgb%28128%2C31%2C19%29-on-white +% gives 9.89 contrast ratio which is a bit less but still AAA +\colorlet{everbatimxfgcolor}{Maroon} + + +% colors for margin notes +\colorlet{marginnotecolor}{PineGreen} +\colorlet{marginwarningcolor}{Red} + +% colors for toc +\colorlet{tocsectioncolor}{cyan} +\colorlet{tocsectionimpcolor}{RoyalPurple} +\colorlet{tocbundlesectioncolor}{xintnamecolor} \usepackage{eso-pic}% après xcolor sinon Option clash for package xcolor. @@ -3042,8 +3157,8 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; linktoc=all,% breaklinks=true,% colorlinks=true,% -urlcolor=niceone,% -linkcolor=blue,% +urlcolor=xintmanualurlcolor,% +linkcolor=xintmanuallinkcolor,% pdfauthor={Jean-Fran\c cois Burnol},% pdftitle={The xintexpr and allied packages},% pdfsubject={Arithmetic with TeX},% @@ -3068,95 +3183,8 @@ pdfpagemode=UseNone,% -\DeclareFontFamily{T1}{newtxttb}{\hyphenchar\font\m@ne} - -\DeclareFontShape{T1}{newtxttb}{m}{n}{ - <-> s*[\newtxtt@scale]newtxttbq -}{} -\DeclareFontShape{T1}{newtxttb}{b}{n}{ - <-> s*[\newtxtt@scale]newtxbttbq -}{} -\DeclareFontShape{T1}{newtxttb}{bx}{n}{ - <-> ssub * newtxttb/b/n -}{} -\DeclareFontShape{T1}{newtxttb}{m}{sl}{ - <-> s*[\newtxtt@scale]newtxttslbq -}{} -\DeclareFontShape{T1}{newtxttb}{m}{it}{ - <-> ssub * newtxttb/m/sl -}{} - -% Ajouté le 9 mars 2016 - -\DeclareFontShape{T1}{newtxttb}{m}{sc}{%cap & small cap - <-> s*[\newtxtt@scale]newtxttscbq -}{} -\DeclareFontShape{T1}{newtxttb}{b}{sc}{%bold cap & small cap - <-> s*[\newtxtt@scale]newtxbttscbq -}{} -\DeclareFontShape{T1}{newtxttb}{b}{sl}{%bold slanted - <-> s*[\newtxtt@scale]newtxbttslbq -}{} -\DeclareFontShape{T1}{newtxttb}{b}{it}{%bold italic - <-> ssub * newtxttb/b/sl% -}{} -\DeclareFontShape{T1}{newtxttb}{bx}{sc}{%bold extended cap & small cap - <-> ssub * newtxttb/b/sc% -}{} -\DeclareFontShape{T1}{newtxttb}{bx}{sl}{%bold extended slanted - <-> ssub * newtxttb/b/sl% -}{} -\DeclareFontShape{T1}{newtxttb}{bx}{it}{%bold extended italic - <-> ssub * newtxttb/b/sl% -}{} - -% Ajouté le 9 mars 2016 -\DeclareEncodingSubset{TS1}{newtxttb}{0} -\DeclareFontFamily{TS1}{newtxttb}{\hyphenchar\font\m@ne} - -\DeclareFontShape{TS1}{newtxttb}{m}{n}{%medium - <-> s*[\newtxtt@scale]tcxtt% -}{} -\DeclareFontShape{TS1}{newtxttb}{m}{sc}{%cap & small cap - <->ssub * newtxttb/m/n% -}{} -\DeclareFontShape{TS1}{newtxttb}{m}{sl}{%slanted - <-> s*[\newtxtt@scale]tcxttsl% -}{} -\DeclareFontShape{TS1}{newtxttb}{m}{it}{%italic - <->ssub * newtxttb/m/sl% -}{} -\DeclareFontShape{TS1}{newtxttb}{b}{n}{%bold - <-> s*[\newtxtt@scale]tcxbtt% -}{} -\DeclareFontShape{TS1}{newtxttb}{b}{sc}{%bold cap & small cap - <->ssub * newtxttb/b/n% -}{} -\DeclareFontShape{TS1}{newtxttb}{b}{sl}{%bold slanted - <-> s*[\newtxtt@scale]tcxbttsl% -}{} -\DeclareFontShape{TS1}{newtxttb}{b}{it}{%bold italic - <->ssub * newtxttb/b/sl% -}{} -\DeclareFontShape{TS1}{newtxttb}{bx}{n}{%bold extended - <->ssub * newtxttb/b/n% -}{} -\DeclareFontShape{TS1}{newtxttb}{bx}{sc}{ %bold extended cap & small cap - <->ssub * newtxttb/b/sc% -}{} -\DeclareFontShape{TS1}{newtxttb}{bx}{sl}{%bold extended slanted - <->ssub * newtxttb/b/sl% -}{} -\DeclareFontShape{TS1}{newtxttb}{bx}{it}{%bold extended italic - <->ssub * newtxttb/b/it% -}{} - - \makeatother -% This is with a slashed 0 like the original txtt. -\newcommand\ttbfamily {\fontfamily{newtxttb}\selectfont } - \ifnum\dosourcexint=1 \else \renewcommand\familydefault\ttdefault @@ -3178,8 +3206,7 @@ pdfpagemode=UseNone,% \ifnum\dosourcexint=0 \inmanualmaintoctrue \fi -\def\sectioncouleur{{cyan}} - +\def\sectioncouleur{{tocsectioncolor}} \def\MARGEPAGENO {1.5em}% changera pour la partie implémentation @@ -3262,13 +3289,9 @@ pdfpagemode=UseNone,% % ===================== -\def\digitstt #1{\begingroup\color[named]{OrangeRed}#1\endgroup} +\def\digitstt #1{\begingroup\color{digitsttcolor}#1\endgroup} \let\dtt\digitstt -% \ctexttt is a remnant of 1.09n manual, don't have time to get rid of it now. -\newcommand\ctexttt [1]{\begingroup\color[named]{DarkOrchid}%\bfseries - #1\endgroup} - % \fexpan 22 octobre 2013 \newcommand\fexpan {\hyperref[ssec:expansions]{\textit{f}-expan}} % Septembre 2015 @@ -3299,7 +3322,7 @@ pdfpagemode=UseNone,% \def\@MyMarginNote [#1]#2{\@bsphack \vadjust{\vskip-\dp\strutbox \hbox{\smash{\hbox to 0pt - {\color[named]{PineGreen}\normalfont\small + {\color{marginnotecolor}\normalfont\small \hsize 1.6cm\rightskip.5cm minus.5cm \hss\vtop{#2}\ $\to$#1\ }}}% \vskip\dp\strutbox @@ -3307,7 +3330,7 @@ pdfpagemode=UseNone,% \def\MyMarginNoteWithBrace #1#2{\@bsphack \vadjust{\vskip-\dp\strutbox \hbox{\smash{\hbox to 0pt - {\color[named]{PineGreen}%\normalfont\small + {\color{marginnotecolor}%\normalfont\small \hss #1\ $\bigg\{$#2}}}% \vskip\dp\strutbox }\strut\@esphack} @@ -3318,18 +3341,18 @@ pdfpagemode=UseNone,% {\kern\dimexpr\FrameSep+\FrameRule\relax\ }} \def\etype #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \itshape \xintListWithSep{\,}{#1}\ $\star$\quad }}}% \vskip\dp\strutbox }\strut\@esphack} \def\xtype #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \itshape \xintListWithSep{\,}{#1}\ \ding{73}\quad }}}% \vskip\dp\strutbox }\strut\@esphack} \def\ntype #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \itshape \xintListWithSep{\,}{#1}\quad }}}% \vskip\dp\strutbox }\strut\@esphack} % @@ -3348,7 +3371,7 @@ pdfpagemode=UseNone,% % \def\NewWith #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent New with #1}\ }}}% @@ -3356,7 +3379,7 @@ pdfpagemode=UseNone,% % \def\CHANGED #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginwarningcolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent Changed at #1!}\ }}}% @@ -3364,7 +3387,7 @@ pdfpagemode=UseNone,% \def\DNU#1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginwarningcolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent Do not use! #1}\ }}}% @@ -3372,7 +3395,7 @@ pdfpagemode=UseNone,% \def\UNSTABLE#1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginwarningcolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent Unstable! #1}\ }}}% @@ -3380,7 +3403,7 @@ pdfpagemode=UseNone,% \def\unstable#1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginwarningcolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent unstable? #1}\ }}}% @@ -3388,7 +3411,7 @@ pdfpagemode=UseNone,% \def\DEPRECATED #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \normalfont\small\bfseries \hsize 2cm\rightskip.5cm minus.5cm \vtop{\noindent Deprecated! (#1)}\ }}}% @@ -3396,7 +3419,7 @@ pdfpagemode=UseNone,% % \def\CHANGEDf #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginwarningcolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent Changed at #1!}\ @@ -3405,7 +3428,7 @@ pdfpagemode=UseNone,% % \def\NewWithf #1{\@bsphack \vadjust{\vskip-\dp\strutbox - \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \hbox{\smash{\hbox to 0pt {\hss\color{marginnotecolor}% \normalfont\small\bfseries \hsize 1.5cm\rightskip.5cm minus.5cm \vtop{\noindent New with #1}\ @@ -3476,29 +3499,6 @@ pdfpagemode=UseNone,% -% \MacroFont and \MicroFont -% ========================= - -\def\restoreMicroFont {\def\MicroFont {\ttbfamily\makestarlowast -% \ifinlefted\else\ifineverb\else\color[named]{verbatim}\fi\fi -% \ifinlefted\else\color[named]{saddlebrown}\fi -% \ifinlefted\else\color[named]{sedate}\fi - \ifinlefted\else\color[named]{jfbrown}\fi -}} -\restoreMicroFont - -% Notice that \macrocode uses \macro@font which stores the \MacroFont meaning -% in force at \begin{document}. But doc.sty's verbatim uses current \MacroFont -% not the meaning at \begin{document}. Comprenne qui pourra... - -\def\restoreMacroFont {\def\MacroFont {\ttbfamily -% \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi -% \ifinlefted\else\color[named]{Blue}\fi -% \ifinlefted\else\color[named]{sedate}\fi - \ifinlefted\else\color[named]{Brown}\fi -}} -\restoreMacroFont - % \verb % ===== @@ -3528,6 +3528,14 @@ pdfpagemode=UseNone,% % with delimited argument. Here is what I do now, this is compatible % with short verbs. +\def\verbcolorcmd{\color{verbcolor}} +\def\verbsoftwrapiconcolorcmd{\color{verbsoftwrapiconcolor}} + +\def\restoreMicroFont {\def\MicroFont {\ttfamily\makestarlowast + \ifinlefted\else\verbcolorcmd\fi +}} +\restoreMicroFont + \def\verb {% \relax \ifmmode\else\leavevmode\null\fi @@ -3535,7 +3543,7 @@ pdfpagemode=UseNone,% \let\do\@makeother \dospecials \@ifstar{\@sverb}% \verb* is used in the index (obsolete: no indices at 1.3e), % leave it using ambient font - {\MicroFont % used to change font (ttbfamily=slashed 0), color, + {\MicroFont % used to change font (\ttfamily), color, % will make * active via \makestarlowast \catcode 32 10 \endlinechar 32 % allows to fetch across line breaks \frenchspacing % done globally in document @@ -3570,24 +3578,22 @@ pdfpagemode=UseNone,% #1\expandafter\@@jfverb_b\fi } -% \SoftWrapIcon box for line-breaking using discretionaries -% ========================================================= \DeclareFontFamily{U}{MdSymbolC}{} \DeclareFontShape {U}{MdSymbolC}{m}{n}{<-> MdSymbolC-Regular}{} - \newbox\SoftWrapIcon -\colorlet {softwrapicon}{blue} -% Emacs/AUCTeX uses very strange comment-like highlighting for \usefont{U}... \def\SetSoftWrapIcon{% \setbox\SoftWrapIcon\hb@xt@\z@ - {\hb@xt@\fontdimen2\font - {\hss{\color{softwrapicon}\usefont{U}{MdSymbolC}{m}{n}\char"97}\hss}% + {\kern.5ex%\hb@xt@\z@%\fontdimen2\font + %{ + \smash{\lower3pt\hbox{% + \verbsoftwrapiconcolorcmd\usefont{U}{MdSymbolC}{m}{n}\char 151 + }}%\hss}% \hss}% } -\AtBeginDocument {\SetSoftWrapIcon }% ttzfamily déjà fait +\AtBeginDocument {\SetSoftWrapIcon }% ok car ttzfamily déjà fait \catcode`_ 8 \makeatother @@ -3595,6 +3601,14 @@ pdfpagemode=UseNone,% % everbatim environment % ===================== +\def\restoreMacroFont {\def\MacroFont {\ttfamily + \ifinlefted\else\color{everbatimfgcolor}\fi +}} +\restoreMacroFont +% Notice that \macrocode uses \macro@font which stores the \MacroFont meaning +% in force at \begin{document}. But doc.sty's verbatim uses current \MacroFont +% not the meaning at \begin{document}. Comprenne qui pourra... + % October 13-14, 2014 % Verbatim with an \everypar hook, mainly to have background color, followed by % execution of the contents (not limited by a group-scope) @@ -3602,44 +3616,10 @@ pdfpagemode=UseNone,% \makeatletter \catcode`_ 11 -% Je modifie Mardi 18 février 2020 \MacroFont -% pour essayer couleur de foreground, -% je supprime donc le \ifineverb de \MacroFont. -% \newif\ifineverb -\def\everbatimtop {\MacroFont \small} -\let\everbatimbottom\relax -\let\everbatimhook\relax - -\def\everbatim {\s@everbatim\@everbatim } -\@namedef{everbatim*}{\s@everbatim\expandafter\@everbatimx\expandafter - {\the\newlinechar}} - -\def\everbatimeverypar{\strut - {\color{yellow!5}\vrule\@width\linewidth }% - \kern-\linewidth - \kern\everbatimindent } -\def\everbatimindent {\z@} -% voir plus loin atbegindocument - -\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist } - -\@namedef{endeverbatim*}{\endeverbatim\aftergroup\everbatimundoparskip} -\def\everbatimundoparskip{\vbox{}\kern-\baselineskip\kern-\parskip} -% Note 24 juin 2021 -% -% Si everbatim[*] suit immédiatement un premier everbatim* dont l'exécution -% n'a fait que des définitions de macros sans créer de paragraphe (ou un -% environnment de liste comme center) le \kern-\parskip émis après le rendu -% verbatim (et qui vient de \everbatimundoparskip) ne sera pas compensé. -% Plus précisément le everbatim* (ou everbatim) qui vient en -% deuxième utilise \trivlist mais en ayant mis les paramètres d'espacements -% verticaux à zéro. Donc il y aura chevauchement. -% -% Pour régler ce problème, on peut : -% - soit fusionner les deux everbatim*, -% - soit si cela est embêtant, par exemple si le second environnment est -% un everbatim, pas un everbatim*, ajouter \kern-\parskip entre les deux. +\def\everbatim {\s@everbatim\@everbatim} +\@namedef{everbatim*}{\s@everbatim\@everbatimx} +% Note: one can not use everbatim inside itself or everbatim* inside itself \def\s@everbatim {% % \ineverbtrue \everbatimtop % put there size changes @@ -3669,6 +3649,13 @@ pdfpagemode=UseNone,% }% \obeylines \@vobeyspaces } +\def\everbatimtop {\MacroFont \small}% +\let\everbatimhook\empty +\def\everbatimeverypar{\strut + {\color{everbatimbgcolor}\vrule\@width\linewidth }% + \kern-\linewidth + \kern\everbatimindent } +\def\everbatimindent {\z@}% voir plus loin atbegindocument \begingroup \lccode`X 13 @@ -3682,38 +3669,79 @@ pdfpagemode=UseNone,% |lowercase[|endgroup% both freezes catcodes and converts X to active ^^M |def|@everbatim #1X#2\end{everbatim}% [#2|end[everbatim]|everbatimbottom ] -|def|@everbatimx #1#2X#3\end{everbatimY}]% - {#3\end{everbatim*}% - \everbatimbottom +|def|@everbatimx #1X#2\end{everbatimY}]% + {#2\end{everbatim*}% +% No group here: this allows executed code to make macro +% definitions which may reused in later uses of everbatim. +% refactored 2022/01/11, rather than passing \newlinechar value +% as was done formerly via everbatim* (see above) and fetching it here as #1 +% it is thus assumed executed contents do not terminate a scope + \edef\everbatimrestorenewlinechar{\newlinechar\the\newlinechar\relax}% \newlinechar 13 +% refactored 2022/01/11 to fix a \parskip issue +% attention, \parskip thus set to zero for execution of contents +% reason: avoid extra space if everbatim* is in an \item of a list +% between verbatim and output of execution, if it starts a paragraph +% a \vskip-\parskip approach (cf former \everbatimundoparskip) +% would be no good in case contents create a display + \edef\everbatimrestoreparskip{\parskip\the\parskip\relax}% + \parskip\z@skip +% execution of the contents (expected to be LaTeX code...) \everbatimxprehook - \scantokens {#3}% - \newlinechar #1\relax + \scantokens {#2}% + \everbatimrestorenewlinechar + \everbatimrestoreparskip \everbatimxposthook +% input after \end{everbatim*} on same line in source is allowed }% - -% L'espace venant du endofline final mis par \scantokens sera inhibé si #3 se +% L'espace venant du endofline final mis par \scantokens sera inhibé si #2 se % termine par un % ou un \x, etc... -\def\everbatimxprehook {\colorlet{everbsavedcolor}{.}\color[named]{OrangeRed}} -\def\everbatimxposthook {\color{everbsavedcolor}} +\let\everbatimbottom\empty + +\def\endeverbatim{\if@newlist \leavevmode\fi\endtrivlist} +\@namedef{endeverbatim*}{\endeverbatim} + +% There is an issue with how to inhibit the \parskip if execution +% of contents generate a paragraph. Because the design is aimed at +% keeping output close to verbatim input. +% Even in a document with zero \parskip overall, the \parskip will possibly +% be reset to some annoying high value e.g. if we are in an \item of a list +% environment. +% In this documentation, many usage of everbatim* are indeed inside such +% \item's. The former (2020) approach was to do: +% \@namedef{endeverbatim*}{\endeverbatim\aftergroup\everbatimundoparskip} +% \def\everbatimundoparskip{\vbox{}\kern-\baselineskip\kern-\parskip\leavevmode} +% but it had its problems if executed contents start a display, with +% not enough vertical whitespace then +% Also if source had two everbatim* environments one after the other, +% the first one not producing any ouput, this caused overlap. +% The new approach (Feb 2022) is much simpler and avoids these problems. + + +% These definitions are provisory and get overwritten below in order +% to avoid color stack overflow problems with latex + dvipdfmx, and xelatex +\def\everbatimxprehook {\colorlet{everbsavedcolor}{.}% + \color{everbatimxfgcolor}}% +\def\everbatimxposthook{\color{everbsavedcolor}} +% actual definitions: +{\sbox0{\color{everbatimxfgcolor}\xdef\@tempa{\current@color}}} \ifpdf - \def\everbatimxprehook - {\pdfcolorstack\@pdfcolorstack push{0 1 0.5 0 k 0 1 0.5 0 K}\relax} - \def\everbatimxposthook - {\pdfcolorstack\@pdfcolorstack pop\relax} + \edef\everbatimxprehook + {\pdfcolorstack\noexpand\@pdfcolorstack push{\@tempa}\relax} + \def\everbatimxposthook{\pdfcolorstack\@pdfcolorstack pop\relax} \else % Le 24 juin 2021 je vérifie que ceci est encore nécessaire avex xelatex % (sinon color leak de OrangeRed à partir de la page 97 dans la doc) % et aussi pour dvipdfmx (sinon color stack overflow au moment de la page 98 % lors du passage par dvipdfmx) \ifxetex - \def\everbatimxprehook {\special{color push cmyk 0 1 0.5 0}} - \def\everbatimxposthook {\special{color pop}} + \edef\everbatimxprehook{\special{color push \@tempa}} + \def\everbatimxposthook{\special{color pop}} \else \ifnum\Withdvipdfmx=1 - \def\everbatimxprehook {\special{pdf:bcolor OrangeRed}} - \def\everbatimxposthook {\special{pdf:ecolor}} + \edef\everbatimxprehook{\special{color push \@tempa}} + \def\everbatimxposthook{\special{color pop}} \fi\fi\fi @@ -3877,20 +3905,20 @@ pdfpagemode=UseNone,% \expandafter\def\csname #1name\endcsname {\texorpdfstring {\hyperref[sec:#2]% - {\relax{\color{joli}\MakeNameUp{#1}}}}% + {\relax{\color{xintnamecolor}\MakeNameUp{#1}}}}% {#1}% \xspace }% \expandafter\def\csname #1nameimp\endcsname {\texorpdfstring {\hyperref[sec:#2imp]% - {\relax{\color{blue}\MakeNameUp{#1}}}}% + {\relax{\color{xintnameimpcolor}\MakeNameUp{#1}}}}% {#1}% \xspace }% }% \def\DOCxintfrontpage {\texorpdfstring - {\hyperref[frontpage]{\relax{\color{joli}TOC}}}% + {\hyperref[frontpage]{\relax{\color{xintnamecolor}TOC}}}% {TOC}% \xspace }% @@ -3943,7 +3971,7 @@ pdfpagemode=UseNone,% The \xintnameimp packages source code\par \gdef\DOCxintfrontpage {\texorpdfstring - {\hyperref[frontpage]{\relax{\color{blue}TOC}}}% + {\hyperref[frontpage]{\relax{\color{xintnameimpcolor}TOC}}}% {TOC}% \xspace }% \else @@ -3967,19 +3995,19 @@ pdfpagemode=UseNone,% \def\DOCxintexprintro {\texorpdfstring - {\hyperref[part:1]{\relax{\color{joli}\MakeNameUp{Start here}}}}% + {\hyperref[part:1]{\relax{\color{xintnamecolor}\MakeNameUp{Start here}}}}% {Start here}% \xspace }% \def\DOCxintexprmacros {\texorpdfstring - {\hyperref[sec:oldxintexpr]{\relax{\color{joli}\MakeNameUp{xintexpr}}}}% + {\hyperref[sec:oldxintexpr]{\relax{\color{xintnamecolor}\MakeNameUp{xintexpr}}}}% {xintexpr}% \xspace }% \def\DOCexamples {\texorpdfstring - {\hyperref[sec:examples]{\relax{\color{joli}\MakeNameUp{Examples}}}}% + {\hyperref[sec:examples]{\relax{\color{xintnamecolor}\MakeNameUp{Examples}}}}% {Examples}% \xspace }% @@ -4254,7 +4282,7 @@ pdfpagemode=UseNone,% \etocsetnexttocdepth{section} \localtableofcontents -\section {Usage} +\section {Introduction and changes} \begin{itemize} \item To use with |etex|, |pdftex|, ..., i.e.\@ with \TeX{} engines activating @@ -4346,38 +4374,28 @@ which got randomly shuffled to new places (at least I did delete large sections, which was a hard decision to take, almost breaking the palimpsest quality of the document). Reports welcome.% % -\footnote{Thanks to Jürgen Gilg for keeping the author motivated and - helping proof-read the 1.4 documentation.} +\footnote{Thanks to Jürgen Gilg for keeping the author motivated and helping + proof-read the 1.4 documentation. Sadly, Jürgen passed away unexpectedly in + 2022. His enthusiasm, kindness, and friendship will be profundly missed.} -\subsection{Improved support for logarithm, exponential, sine, etc...\@ at - the \texttt{1.4e} release of \texttt{2021/05/05}} - -They are now supported up to \dtt{62} digits and achieve «correct rounding»% -% -\footnote{This means that the produced value is the rounding to |Digits| - significant digits of the theoretical exact mathematical value. The - rounding mode is currently not customizable and is «rounding to nearest, - ties go to infinity of same sign».} -% -at least -in \dtt{99\%} of cases% -% -\footnote{It is even better than that, but depends a bit on how |Digits| is - located relative to some thresholds governing Taylor series - or other approximation means.} -% -for |Digits| being at least \dtt{9}. +\subsection{Breaking changes since the \texttt{1.4} release} -For Digits up to \dtt{8}, a special more approximate implementation is used, -and the functions achieve the correct rounding (particularly at |Digits| -equal to \dtt{8} or \dtt{7}) less often, but are significantly faster -(especially logarithm, exponential, powers) than working with \dtt{9} digits -or more. The achieved precision is largely enough for plots. - -See \xintlogname and \xinttrigname for some additional information. +\subsubsection{Breaking changes at the \texttt{1.4k} release} +\begin{enumerate}[noitemsep] + \item Changed behaviour for nested + \csbxint{exprSafeCatcodes}/\csbxint{exprRestoreCatcodes}. + \item The output format of \csbxint{floateval}, which by default is produced + by \csbxint{PFloat}, has changed once more (!): integers (without + scientific exponent) get now printed without a trailing "\dtt{.0}". + Furthermore trailing zeros in the significand are removed only if there are + at least \dtt{4} of them. This changed behaviour is reversible + via customizing macros. + \item \csbxint{Float} now outputs the zero value as + "\dtt{\xintFloat{0}}". Customizable via \csbxint{FloatZero}. +\end{enumerate} -\subsection{Breaking changes at the \texttt{1.4g} release} +\subsubsection{Breaking changes at the \texttt{1.4g} release} \begin{enumerate}[noitemsep] \item Power operators |**| and |^| are now parsed @@ -4394,7 +4412,7 @@ $$5^{4^{3^2}} = 5^{262144}\approx \xintTeXfromSci{\xintfloateval{5^4^3^2}}$$ respectively. \end{enumerate} -\subsection{Breaking changes at the \texttt{1.4f} release} +\subsubsection{Breaking changes at the \texttt{1.4f} release} \begin{enumerate}[noitemsep] \item \csbxint{ieval}|{[-D]...}|\IMPORTANT{} @@ -4414,7 +4432,7 @@ $$5^{4^{3^2}} = 5^{262144}\approx \xintTeXfromSci{\xintfloateval{5^4^3^2}}$$ of |Digits| and \dtt{64} digits. \end{enumerate} -\subsection{Breaking changes at the \texttt{1.4e} release} +\subsubsection{Breaking changes at the \texttt{1.4e} release} In principle, I try for breaking changes regarding output to happen only at major releases. But it is not as if I had a gigantic user base, and sometimes @@ -4429,13 +4447,16 @@ support is needed... \begin{itemize} \item \csbxint{floateval} output macro \csbxint{PFloat} has been modified. In - particular mantissas are trimmed of trailing zeros. Integers are printed - with a zero after the decimal mark. + particular mantissas are trimmed of trailing zeros. + {\setbox8\hbox{Integers are printed with a zero after the decimal mark.}% + \rule[0.5ex]{\wd8}{1pt}\kern-\wd8\box8}\CHANGED{1.4k again} \item \csbxint{eval} output macro \csbxint{FracToSci} has been modified, regarding the handling of numbers involving a decimal exponent; rather than - printing out an integer mantissa, it now uses the same conventions as - \csbxint{PFloat} (of course without pre-rounding to the |Digits| precision). - The \csa{xintFracToSciE} was removed because \csbxint{PFloatE} is used. + printing out an integer mantissa, it uses scientific notation, + i.e.\@ more specifically it uses the same conventions as + \csbxint{PFloat}, but of course without pre-rounding to the |Digits| precision. + The \csa{xintFracToSciE} macro was removed because \csbxint{PFloatE} + is used in its place. Notice though that fractions are still not automatically reduced to lowest terms even on output. I hesitated about this, but when for example the @@ -4443,7 +4464,7 @@ support is needed... it would be a very costly operation to apply \csbxint{Irr} or \csbxint{PIrr} to it. \item \csbxint{ieval} was modified to use on output - \csbxint{DecToString} and not anymore \csbxint{FracToSci}. + \csbxint{DecToString}, not \csbxint{FracToSci}. This means than in case of usage of the |[D]| optional argument with a negative |D| (i.e.\@ rounding the output to a multiple of a positive power @@ -4483,7 +4504,50 @@ support is needed... For bugfixes and possibly more details check |CHANGES.html|: \centeredline{|texdoc --list xint|} + + \begin{itemize} +\item The most important has been the improved support for logarithm, exponential, +sine, etc...\@ added at the \texttt{1.4e} release of \texttt{2021/05/05}: + +They\NewWith{1.4e !!} are now supported up to \dtt{62} digits and achieve «correct rounding»% +% +\footnote{This means that the produced value is the rounding to |Digits| + significant digits of the theoretical exact mathematical value. The + rounding mode is currently not customizable and is «rounding to nearest, + ties go to infinity of same sign».} +% +at least +in \dtt{99\%} of cases% +% +\footnote{It is even better than that, but depends a bit on how |Digits| is + located relative to some thresholds governing Taylor series + or other approximation means.} +% +for |Digits| being at least \dtt{9}. + +For Digits up to \dtt{8}, a special more approximate implementation is used, +and the functions achieve the correct rounding (particularly at |Digits| +equal to \dtt{8} or \dtt{7}) less often, but are significantly faster +(especially logarithm, exponential, powers) than working with \dtt{9} digits +or more. The achieved precision is largely enough for plots. + +See \xintlogname and \xinttrigname for some additional information. + +\item The long awaited\NewWith{1.4k} syntax \csbxint{ieval}|[D]{...}| and + \csbxint{floateval}|[Q]{...}| has been implemented. The legacy + \csbxint{ieval}|{[D]...}| and \csbxint{floateval}|{[Q]...}| syntax is kept + for backwards compatibility. + +\item \csbxint{FloatToDecimal}, \csbxint{FracToDecimal}.\NewWith{1.4k} + +\item \csbxint{PFloat}\NewWith{1.4k} is customizable via \csbxint{PFloatZero}, + \csbxint{PFloatIntSuffix}, \csbxint{PFloatLengthOneSuffix}, + \csbxint{PFloatNoSciEmax}, \csbxint{PFloatNoSciEmin} and + \csbxint{PFloatMinTrimmed}. + +\item \csbxint{FloatZero}.\NewWith{1.4k} + \item The concept of simultaneous assignments is extended:\NewWith{1.4i} in case of more variables than values the extraneous variables do not cause an error message but are simply set to the |nil| value; in case of more values @@ -4497,9 +4561,6 @@ For bugfixes and possibly more details check |CHANGES.html|: \item \csbxint{TeXfromSci}\NewWith{1.4g} - \item The most important feature is at |1.4e| the extended range and accuracy - of the scientific functions, up to \dtt{62} digits.%\NewWith{1.4e} - \item The constraints for the replacement macro to be used for \csbxint{exprPrintOne} have been much simplified. See the documentation of \csbxint{FracToSci} which is the package default. @@ -4590,7 +4651,7 @@ author a few decades to finish absorbing Python/NumPy. \end{itemize} \end{framed} -\subsection{Known bugs/features (last updated at \texttt{1.4i})} +\subsection{Known bugs/features (last updated at \texttt{1.4j})} \begin{description} \item[if(100>0,(100,125),(100,128)) breaks my code:] @@ -4668,6 +4729,14 @@ author a few decades to finish absorbing Python/NumPy. only at |1.4h|. The non-nested case |seq((i)?{i}{abort}+10, i=-2, -1, 0, 1)| works and the «must be last in expression if nested» limitation is currently considered a feature. + +\item[{seq([i,i\string^2], i=1..10) crashes with Ooops, looks like we are missing a + ]. Aborting!}] +% + The cause is that the square brackets do not hide the comma from |seq()| + parsing. This will probably remain ``wont-fix''. Work-arounds: either use + an extra pair of parentheses |seq(([i,i^2]), ...)| or hide the inner + comma within braces |seq([i{,}i^2], ...)|. \end{description} The list stops here, but there are certainly other pending bugs in my bug-log, @@ -4734,405 +4803,48 @@ The rendering here uses extra decoration. \localtableofcontents -\subsection{Oples and nutples: terminology for the \text{1.4} \xintname generation}\label{oples} - -\emph{Skip this on first reading, else you will never start using the - package.} \fbox{SKIP THIS!} (understood?) - -In this section I will describe a mathematical terminology which models -how the parser handles the input syntax with numbers, commas, and brackets, -and how it maps internally to \TeX\ specific concept, particularly braces and -macro arguments. - -\etocsetnexttocdepth{subsubsection} -\localtableofcontents - -\subsubsection{Base terminology} - -We start with a set $\mathcal{A}$ of \emph{atoms}, which represent numeric -data. In \TeX{} syntax such \emph{atoms} are always braced, more precisely, -currently they look like -% -\centeredline{\dtt{\{raw format within \TeX{} braces\}}} -% -The \TeX{} braces are not set-theoretical braces here, they are simply used -for \TeX nical reasons (one could imagine using rather some terminator token, -but ultimately support macros for built-in and user defined functions rely on -\TeX\ macros with undelimited parameters, at least so far). - -Our category $\mathcal{C}$ of «oples» is the smallest collection of -\emph{totally ordered finite sets} verifying these properties: -\begin{enumerate} -\item The empty set \dtt{$\emptyset$} is an \emph{ople}, i.e.\@ it belongs to - $\mathcal{C}$. -\item Each singleton set \dtt{$\{O\}$} whose element \dtt{$O$} is either an - \emph{atom} $a\in\mathcal{A}$ or an \emph{ople} qualifies as an \emph{ople}. -\item $\mathcal{C}$ is stable by concatenation. -\end{enumerate} - -Notes: -\begin{itemize} -\item -We refer to the empty set \dtt{$\emptyset$} via the variable \emph{nil}.% -% -\footnote{There is -actually a built-in variable with this name. At |1.4|, |\xintexpr\relax| is -legal and also generates the \emph{nil}.} - -\item It is convenient to accept the empty set as being also an - \emph{atom}. If this is done, then we may refer to the original - \emph{atoms} (elements of $\mathcal{A}$) as \emph{non empty numerical data}. - -\item -Concatenation is represented in the syntax by the -comma. Thus repeated commas are like only one and |nil| is a neutral element. - -\item A singleton \emph{ople} \dtt{$\{a\}$} whose single element is a - (non-empty) \emph{atom} is called a \emph{number}.% -% - \footnote{This has to be taken in a general sense, for example with - \ctanpackage{polexpr}, polynomials are represented by such «numbers».} -% - -\item -The operation of constructing \dtt{$\{O\}$} from the \emph{ople} \dtt{$O$} is -called \emph{bracing} (set theory, \TeX), or \emph{bracketing} (\xintexprname -input syntax, Python |lists|), or \emph{packing} (as a reverse to Python's -unpacking of sequence type objects). In the expression input syntax it -corresponds to enclosing \dtt{$O$} within square brackets: \dtt{$[O]$}. - -\item A braced \emph{ople} is called a \emph{nutple}. Among them \dtt{\{nil\}} - (aka $\{\emptyset\}$) is a bit special. It is called the \emph{none-ple}.% -% - \footnote{Prior to version |1.4j| of this documentation it was called the - \emph{not-ple}.} -% -It is not \dtt{nil}.% -% -\footnote{There is (experimental) a pre-defined «\dtt{None}» variable which - stands for the \emph{none-ple}. It can also be input as |[]|.} -\end{itemize} - -Each \emph{ople} has a \emph{length} which is its cardinality as set. The -singleton |oples| are called \emph{one-ples}. There are thus two types of -\emph{one-ples}: -\begin{itemize} -\item \emph{numbers} \dtt{$\{a\}$}, $a \in \mathcal{A}$, -\item \emph{nutples} \dtt{$\{O\}$}, $O \in \mathcal{C}$. -\end{itemize} - -If we consider the empty set |nil| on the same footing as |atoms|, the two -types have only one common object which is the \emph{none-ple}. As a rule -arithmetic operations will either break or silently convert the \emph{none-ple} -to the zero value: -\begin{everbatim*} -\xinteval{3+[], 5^[], 10*[]} -\end{everbatim*}. -But attention that \csbxint{iieval} in contrast to \csbxint{eval} is broken by -such inputs. - -\subsubsection{Items (and sub-items) versus elements} +\subsection{The three parsers} -In order to illustrate these concepts, let us consider how one should -interpret notation such as |3,5,7,9| when it arises in an -\csbxint{expr}|ession|: -\begin{description} -\item[tempting vocabulary:] Each of |3|, |5|, |7|, and |9| is an \emph{item}, or - \emph{element} of the (comma separated) \emph{list}. In other terms we have - here a list with 4 items. -\item[rigorous vocabulary:] each one of |3|, |5|, |7|, |9| stands for an - \emph{ople} (of the \emph{one-ple} type) and |3,5,7,9| stands for their \emph{concatenation}. +\xintexprname provides three numerical expression parsers corresponding to +these three respective tasks: +\begin{description}[noitemsep] +\item[\csh{xinteval}:] exact evaluations with fractions, decimal fixed point numbers, numbers + in scientific notation, with no size limitation, +\item[\csh{xintiieval}:] evaluations allowing only integers with no size limitation, +\item[\csh{xintfloateval}:] evaluations with floating points numbers according to the prevailing + precision (see \csbxint{Digits*}), \end{description} -It is important to understand that in an \csbxint{expr}|ession|, there is no -difference between |3,5,7| and |3,,,,5,,,,,,,,,7|. So the view of the comma -as separator is misleading. In other terms, the comma is NOT a separator but -the (associative) operator of concatenation of totally ordered sets, and the -number |3| for example represents a (singleton) set. - -If we want to refer to |3| or |5| or |7| or |9| as «the items of the -(open) list |3,5,7,9|» (and probably this documentation already has such -utterances, due to legacy reasons from the pre-|1.4| internal model), we -\emph{must} realize that this clashes with using the word \emph{item} as -synonymous to \emph{element} in the set-theoretical sense. - -To repeat, any ople \dtt{$O$} is a finite totally ordered set: if not the empty -set, it has \emph{elements} \dtt{$a_1$}, \dots, \dtt{$a_k$}, and the above means that -its \emph{items} are the singleton oples (aka one-ples) \dtt{$I_1=\{a_1\}$}, -\dots, \dtt{$I_k=\{a_k\}$}. Each \dtt{$a_j$} may be an |atom|, then -\dtt{$I_j$} is a |number|, or \dtt{$a_j$} is an |ople| (possibly the empty set), then -\dtt{$I_j$} is a |nutple| whose depth is one more than the one of the ople -\dtt{$a_j$}. - -Thus we can refer to «items» but must then understand they are not «elements»: -«items» are «singleton sub-sets». The cardinality (aka length) of an ople is -also the number of its -items. It would be tempting to use the terminology «sub-item» to keep in mind they are «sub-sets» -but this would again create confusion: a |nutple| has only one item which is -itself; and we need some terminology to refer to the individual numbers in the -|nutple| given in input as |[1,2,3]| for example. It is natural to refer to -|1|, |2|, |3| as «sub-items» of |[1,2,3]| as the latter may be an «item» (it -is in particular an «item» of itself, the unique one at that). - -We distinguish the |oples| of length zero (there is only one, the empty set) -or at least two as those which can never be an «item». Those of length one, -the |one-ples|, are exactly those which can be «items». Among them some may -have «sub-items», they are the |nutples| with the exception of the |none-ple|. -And the others do not have «sub-items», they are the |numbers| and the |none-ple| (whose input syntax is -either |[]| or the variable |None|).% -% -\footnote{% -A note on the \csbxint{verbosetrue} regime: for a variable defined to be -|3,5,7,9|, it will say that its value is |{3}{5}{7}{9}|, because it does not -keep the external set-theoretical braces. The braces here are only \TeX{} -braces, and |{3}| is an |atom|. The |number| would be |{{3}}| with the -external braces being set-theoretical and also used internally as \TeX{} -braces. From the four numbers |{{3}}|, ..., |{{9}}| concatenation gives -|{{3}{5}{7}{9}}|, which is the |ople| |3,5,7,9|. But the log view drops -deliberately the external braces. If the variable is defined to be the -|nutple| |[3,5,7,9]|, then the log view will be |{{3}{5}{7}{9}}| (up to -details on how exactly the numeric quantities are coded) and the actual -internal \TeX{} entity will be |{{{3}{5}{7}{9}}}|, where the two external -layers of braces are both set-theoretical and \TeX nical braces.} - - -\subsubsection{Oples as trees} - -We say that the empty set |nil| and \emph{atoms} are \emph{leaves}. - -We associate with any \emph{ople} a tree. The root is the ople. In the case of -the |nil| ople, there is nothing else than the root, which we then consider -also a \emph{leaf}. Else the children at top level are the successive -\emph{elements} (not «items»!) of the ople.% -% -\footnote{\label{fn:alttree}% - We could also consider a tree for which the children of the root node would - be its items and recursively; in that case the leaves would be |numbers| and - possibly the |None|. The tree of the |nil| would be the empty tree, the tree - of |None| would have a single node and no edges. Such a tree would match - the input syntax (of course applying the rule that iterated commas are like - only one). The tree which is described in this section matches more - directly the internal syntax, hence is more useful to the author, who is - also the sole reader who extracts some benefit from reading this - documentation once in a while.} -% -Among the elements some are \emph{atoms} giving \emph{leaves} of the tree, -others are \emph{nutples} which in turn have children. In the special case of -the \emph{none-ple} we consider it has a child, which is the empty set and this -is why we consider the empty set |nil| to be also a potential \emph{leaf}. We -then proceed recursively. We thus obtain from the root \emph{ople} a tree -whose vertices are either \emph{oples} or \emph{leaves}. Only the empty set -|nil| is both a \emph{leaf} and an \emph{ople}. - -Considering the empty set |nil| as an \emph{atom} fits with the \xintexprname -internal implementation based on \TeX: |nil| is an empty pair of braces |{}|, -whereas an \emph{atom} is a braced representation of a numeric value using -digits and other characters. We construct \emph{oples} by putting one after -the other such constituents and bracing them, and then repeating the process -recursively. - -It has also an impact on the definition of the \emph{depth} (a.k.a as -\emph{maximal dimension}) of an \emph{ople}. For example the \emph{ople} -$\{\emptyset A_1A_2\}$ with three elements, among them the empty set and two -atoms is said to have depth $1$, or to have maximal dimension $1$. And -$\{\{\emptyset\}A_1A_2\}$ is of depth $2$ because it has a leaf (the empty -set) which is a child of a child of the \emph{ople}. NumPy \emph{ndarrays} -have a more restricted structure for example -$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ is a $2$-dimensional array, where all -leaves are at the same depth. When slicing empties the array from its atoms, -NumPy keeps the shape information but prints the array as $[]$. This will not -be the case with \xintexprname, which has no other way to indicate the shape -than display it. -\begin{everbatim*} -\xinteval{[[],[]]} -\end{everbatim*} -\begin{everbatim*} -\xinteval{[[0,1],[10,11]][:,2:]} -\end{everbatim*} - -\subsubsection{Ople slicing and indexing} -\label{sssec:opleslicing} - -«Set-theoretical» slicing of an \emph{ople} means replacing it with one of its -subsets. This applies also if it is a \emph{number}. Then it can be sliced -only to itself or to the empty set (indeed it has only one element, which is -an atom). Similarly the \emph{none-ple} can only be sliced to give itself or -the empty set. And more generally a \emph{nutple} is a singleton so also can -only be set-sliced to either the empty set or itself. - -\xintexprname extends «Python-like» slicing to act on \emph{oples}: -\begin{itemize}[nosep] -\item if they are not \emph{nutples} set-theoretical slicing applies, -\item if they are \emph{nutples} (only case having a one-to-one - correspondence in Python) then the slicing happens \emph{within brackets}: - i.e.\@ the \emph{nutple} is unpacked then the set-theoretical slicing is - applied, then the result is \emph{repacked} to produce a new \emph{nutple}. -\end{itemize} -With these conventions the \emph{none-ple} for example is invariant under -slicing: unpacking it gives the empty set, which has only the empty set as -subset and repacking gives back the \emph{none-ple}. Slicing a general -\emph{nutple} returns a \emph{nutple} but now of course in general distinct -from the first one. - -The input syntax for Python slicing is to postfix a variable or a -parenthesized ople with |[a:b]|. See \autoref{ssec:lists} for more. There -are never any out-of-range errors when slicing or indexing. All operations -are licit and resolved by the |nil|, a.k.a. empty set. - -«Set-theoretical» item indexing of an \emph{ople} means reducing it to a -subset which is a singleton. It is thus a special case of set-theoretical -slicing (which is the general process of selecting a subset as replacement of -a set). - -\xintexprname extends «Python-like» indexing to act on \emph{oples}: -\begin{itemize}[nosep] -\item if they are not \emph{nutples} set-theoretical item indexing applies, -\item if they are \emph{nutples} (only case having a one-to-one - correspondence in Python) then the meaning becomes \emph{extracting}: i.e.\@ - the \emph{nutple} is unpacked then the set-theoretical indexing is applied, - but the result is \emph{not repacked}. -\end{itemize} -For example when applied to the \emph{none-ple} we always obtain -the |nil|. Whereas as we saw slicing the \emph{none-ple} always gives back the -\emph{none-ple}. Indexing is denoted in the syntax by postfixing by |[N]|. Thus -for \emph{nutples} (which are analogous to Python objects), there is genuine -difference between the |[N]| extractor and the |[N:N+1]| slicer. But for -\emph{oples} which are either |nil|, a \emph{number}, or of length at least 2, -there is no difference. - -\subsubsection{Nested slicing of oples} - -Nested slicing is a concept from NumPy, which is extended by \xintexprname to -trees of varying depths. We have a chain of slicers and extractors. I will -describe only the case of slicers and letting them act on a |nutple|. The -first slicer gives back a new |nutple|. The second slicer will be applied to -each of one of its remaining elements. However some of them may be -\emph{atoms} or the empty set. In the NumPy context all leaves are at the -same depth thus this can happen only when we have reached beyond the last -dimension (axis). This is not permitted by NumPy and generates an error. -\xintexprname does not generate an error. But any attempt to slice an -\emph{atom} or the empty set (as element of its container) removes it. Recall -we call them \emph{leaves}. We can not slice leaves. We can only slice -non-leaf elements: such items are necessarily |nutples|. The procedure then -applies recursively. - -If we handle an extractor rather than a slicer, the procedure is similar: we -can not extract out of an \emph{atom} or the empty set. They are thus -removed. Else we have a |nutple|. It is thus unpacked and replaced by the -selected element. This element may be an atom or the empty set and any further -slicer or extractor will remove them, or it is a |nutple| and the procedure -applies with the next slicer/extractor. - -\xintexprname allows to apply such a |[a:b,c:d,N,e:f,...]| chain of -slicing/extracting also to an \emph{ople}, which is not a \emph{nutple}. We -simply apply the first step as has been described previously and successive -steps will only get applied to either \emph{nutples} or \emph{leaves}, the -latter getting silently removed by any attempted operation. - -\subsubsection{Function arguments versus variables} -\label{sssec:funcargs} - -In a function declaration with \csbxint{deffunc}, the call signature is parsed -as a comma separated list, so here it is not true that repeated commas are -like only one: repeated commas are not allowed and will break the function -declaration. - -When \xintexprname parses a function call, it first constructs the ople which -is delimited by the opening and closing parentheses, then it applies the -function body, after having mapped the successive items (not the elements) of -the parsed ople to the variables appearing in the function call -signature. Hence the arguments in the call signature stand for |one-ples| -(i.e.\@ either |numbers| or |nutples|). - -Let me explain why we can not define a function |foo(A,B)| of two oples: the -function call will evaluate as an ople what is enclosed within the -parentheses. It is then impossible in general to split this uniquely into two -oples |A| and |B|, except if for example we know a priori the length of |A|. -We could imagine defining a declarative interface for a |foo(A,B)| with |A| -preset to have \dtt{37} items or at least a pre-defined number of items but -this is extraneous layer for a functionality no-one will use. - -The alternative would be to consider that declaring |foo(A,B)| means |A| will -pick-up always the first item and |B| all the remaining ones, and thus will be -an ople; here, there are some \TeX nical implementation reasons which have -dissuaded the author to do this. +and two secondary ones which act like the exact evaluator then round the +output to a given number of fractional digits, or convert them to +|False| or |True| according to whether they vanish or do not vanish. -In its place, a special syntax |foo(A,*B)| for the declaration of the function -is available. It means that |B| stands for the |nutple| which -receives as items all arguments in the function call beyond the first one -already assigned to |A|. - -More generally, the last positional argument in a function declaration can -have the form |*|\meta{argname}. This then means that \meta{argname} -represents a |nutple| which will receive as items all arguments in the -function call remaining after the earlier positional arguments have been -assigned. The declared function body is free to again use the syntax -|*|\meta{argname} which will unpack it and thus produce the ople concatenating -all such optional arguments. - -With \csbxint{defvar} one can define a variable with value an |ople| of -arbitrary cardinality. Such a variable can be used in a function call, it -will then occupy the place of as many arguments as its cardinality (which is -its number of elements, hence of its associated items). For example if -function |foo| was declared as a function of 5 arguments |f(a,b,c,d,e)| it is -legitimate to use it as |f(A,B)| if |A| is an ople-valued variable of length -three and |B| of length two. The actual arguments |a,b,c,d,e| will be made to -match the three items of |A| and the two items of |B|. - -\subsubsection{Final words on leaves} - -In case things were too clear, let's try to add a bit of confusion with an -extra word on \emph{leaves}. When we discuss informally (particularly to -compare with NumPy) an input such as -\begin{everbatim} -[[1, 2], [3, 4]] -\end{everbatim} -we may well refer to |1|, |2|, |3|, and |4| as being «the leaves of the 2d -array». But obviously we have here numbers and previously we explained that a -number is not a \emph{leaf}, its \emph{atom} is. Well, the point here is that -we must make a difference between the input form as above and the actual -constructed \emph{ople} the parser will obtain out of it. In the input we do -have numbers. The comma is a \emph{concatenator}, it is not a separator for -enumeration! The \emph{ople} which corresponds to it has a \TeX{} -representation like this: -\begin{everbatim} -{{{1}{2}}{{3}{4}}} -\end{everbatim} -where we don't have the \emph{numbers} anymore (which would look like |{{1}}|, -|{{2}}|, ...) but numeric \emph{atoms} |{1}|, |{2}|, |{3}|, |{4}| where the -braces are \TeX{} braces and \textbf{not} set-theoretical braces (the other -braces are both). Hence we should see the above as the |ople| -$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ with atoms $A_{00}=\{1\}$, ..., being the -\emph{leaves} of the tree associated to (or which is) the \emph{ople}. - -Numbers may be called the \emph{leaves} of the \textbf{input}, but once -parsed, the input becomes an \emph{ople} which is -(morally) a tree whose leaves are \emph{atoms} (and the empty set). -This discussion can also be revisited with footnote -%%\footref{fn:alttree} -\ref{fn:alttree} in mind. - -\subsubsection{Farewell, thanks for your visit!} - -I hope this is clear to everyone. If not, maybe time to say this section is -not needed to understand almost all of the manual, but I needed to -write it to be able to maintain in future my own software. - -\subsection{The three parsers} - -\xintexprname provides three numerical expression parsers and two subsidiary -ones. They are designed to be compatible with expansion only context. All -computations ultimately rely on (and reduce to) usage of the |\numexpr| -primitive from \eTeX{}% -% -\footnote{It can handle only integers, and they must be at most -$2^{31}-1={}$\dtt{\the\numexpr"7FFFFFFF\relax}. Thus some work has to be done -to handle arbitrarily big integers or arbitrary float precision.}. -% -These \eTeX{} extensions date -back to 1999 and are by default incorporated into the |pdftex| -etc...\@ executables from major modern \TeX{} installations for more than -fifteen years now. +\begin{framed} + Please note the following: + \begin{itemize}[noitemsep] + \item Although \csbxint{eval} manipulates arbitrarily long integers or + fractions it also accepts scientific notation on input, as well as + all the mathematical functions (evaluated using the prevailing + digits precision), and (depending on customization) can thus produce + also scientific notation on output. + \item So far, individual operations and the printing routine of + \csbxint{eval} do not automatically reduce fractions to their lowest + terms. + \end{itemize} +\end{framed} +% They are designed to be compatible with expansion only context. All +% computations ultimately rely on (and reduce to) usage of the |\numexpr| +% primitive from \eTeX{}% +% % +% \footnote{It can handle only integers, and they must be at most +% $2^{31}-1={}$\dtt{\the\numexpr"7FFFFFFF\relax}. Thus some work has to be done +% to handle arbitrarily big integers or arbitrary float precision.}. +% % +% These \eTeX{} extensions date +% back to 1999 and are by default incorporated into the |pdftex| +% etc...\@ executables from major modern \TeX{} installations for more than +% fifteen years now. +The interface is: \begin{itemize} \item \csbxint{eval}\marg{expression} handles integers, decimal numbers, numbers in scientific notation and fractions. The algebraic computations are @@ -5142,43 +4854,66 @@ fifteen years now. \xinteval{add(x/(x+1), x = 1000..1014)}\par \end{everbatim*} In this example, the fraction obtained by addition is already -irreducible, but this is not always the case: -\begin{snugframed} - By default, basic operations on fractions do not automatically reduce to - smallest terms the output: |A/B| multiplied by |C/D| - returns |AC/BD|, and |A/B| added to |C/D| uses |lcm(B, D)| as denominator. -\end{snugframed} +irreducible, but this is not always the case, as pointed above + Arbitrarily long numbers are allowed in the input. The space character (contrarily to the situation inside |\numexpr|) and also the underscore character (as allowed in Python too) can serve to separate groups of digits for better readability. But the package currently provides no macros to let the output be formatted with such separators. - -Formatting of numeric output is apart from some minimal facilities such as -\csbxint{TeXfromSci}\NewWith{1.4g}, -\csbxint{TeXFrac}, \csbxint{DecToString}, \csbxint{PRaw}, \csbxint{FracToSci} or \csbxint{PFloat} left -to user macros or third-party packages% \begin{everbatim*} \xinteval{123_456_789_012^5} \end{everbatim*} -\item \csbxint{iieval}\marg{expression} does exact computations \emph{on (big) - integers only.} It is (of course) slightly faster than \csbxint{eval} for - equivalent operations. The forward slash \oper{/} does the \emph{rounded} - integer division to match behaviour of |\numexpr|. The \oper{//} operator - does floored division as in \csbxint{eval}. The \oper{/:} is the associated +\item \csbxint{ieval}\oarg{D}\marg{expression} is the same parser as + \csbxint{eval}, i.e. accepts the same inputs and does all computations + exactly in the same manner, but it then rounds its final result to the + nearest integer, or, in case there is an optional argument |[D]|, to: + \begin{itemize} + \item if |D>0|: the nearest fixed point number with |D| digits after the + decimal mark, + \item if |D=0|: the nearest integer (as for \csbxint{ieval} with no optional argument), + \item if |D<0|: the rounded quotient by |10^(-D)|.\CHANGED{1.4f} + \end{itemize} + + Prior to |1.4k| the optional argument \oarg{D} had to be located + \emph{within} the braces at the start of the expression. At long last, this + is not required anymore.\NewWith{1.4k} The legacy syntax is and will keep + being allowed. + +\item \csbxint{iieval}\marg{expression} executes computations \emph{on (big) + integers only.} It is (only slightly) faster than \csbxint{eval} for + the same expression. + + Attention: the forward slash \oper{/} does the \emph{rounded} integer + division to match behaviour of |\numexpr|. The \oper{//} operator does + floored division as in \csbxint{eval}. The \oper{/:} is the associated modulo operator (we could easily let the catcode 12 |%| - character be an alias, but using such an unusual percent character would be - a bit cumbersome in a \TeX{} workflow, if only for matters of + character be an alias, but using such an unusual percent character + would be a bit cumbersome in a \TeX{} workflow, if only for matters of syntax highlighting in \TeX-aware text editors). \begin{everbatim*} \xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)}% only add fifth powers of multiples of 7 \end{everbatim*} -\item \csbxint{floateval}\marg{expression} does floating point computations - with a given precision \dtt{P}, as specified via a prior assignment - |\xintDigits:=P\relax |. The \oper{/} will compute the correct rounding of - the exact fraction. Again \oper{//} is floored division and \oper{/:} its +\item \csbxint{floateval}\oarg{Q}\marg{expression} does floating point + computations with a given precision |P|, as specified via a prior + assignment |\xintDigits:=P\relax | (the value |P| can be recovered + via \csbxint{theDigits}). + + Its optional argument |[Q]|, if present, means to do a \emph{final} float + rounding to a mantissa of |Q| digits (this thus makes sense only if + |Q<P|). + + A negative |Q| is allowed and means to round to |P+Q| digits only. + + Prior to |1.4k| the optional argument \oarg{Q} had to be located + \emph{within} the braces at the start of the expression. At long + last, this is not required anymore.\NewWith{1.4k} The legacy syntax is + and will keep being allowed. + + The infix operator \oper{/} will compute the correct rounding of the exact + fraction. The operator \oper{//} is floored division and \oper{/:} is its associated modulo (see also \func{divmod}). \begin{everbatim*} \begingroup @@ -5187,66 +4922,49 @@ to user macros or third-party packages% \endgroup \end{everbatim*} - The default is with \dtt{P=16} digits. The four basic - operations and the square root realize \emph{correct + The four basic operations and the square root achieve \emph{correct rounding.}\footnote{when the inputs are already floating point numbers with at most |P|-digits mantissas.} - It can be used with an optional argument |[Q]| which means to do a final - float rounding to mantissas of |Q| digits (this makes - sense only if |Q<P|). ATTENTION: the optional argument |[Q]| is to be - located \emph{within} the braces at the start of the expression. - - When |Q| is negative it means to round to |P+Q| digits only. - - On output, \csbxint{floateval} uses \csbxint{PFloat} for each number. This - can be modified (cf.\@ \csbxint{floatexprPrintOne}). + On output, \csbxint{floateval} uses \csbxint{PFloat} for each numeric + leaf. This can be modified (cf.\@ \csbxint{floatexprPrintOne}). \end{itemize} -The user can define variables and functions. Definition of functions is either -per parser (\csbxint{deffunc}, \csbxint{deffloatfunc}, ...), but there are -some restrictions, or generic (\csbxint{NewFunction}) but the latter is only -syntactic sugar for function-like disguise of a \TeX{} macro having not done -any pre-parsing. - -Two derived parsers: -\begin{itemize} -\item \csbxint{ieval}\marg{expression} does all computations like \csbxint{eval} - but rounds the result to the nearest integer. If there is an optional - argument |[D]|, the rounding is to: - \begin{itemize} - \item if |D>0|: the nearest fixed point number with |D| digits after the - decimal mark, - \item if |D=0|: the nearest integer, - \item if |D<0|: the rounded quotient by |10^(-D)|.\CHANGED{1.4f} - \end{itemize} - ATTENTION: the optional argument - |[D]| is to be located \emph{within} the braces at the start of the expression. -\item \csbxint{theboolexpr}\meta{expression}|\relax| does all computations like \csbxint{eval} - then converts all (non-empty) leaves% -% -\footnote{Currently, empty leaves are output using \csbxint{exprEmptyItem}, - i.e.\@ default to \dtt{\xintexprEmptyItem}. This may change.} -% -to |True| or |False| - (cf.\@ \csbxint{boolexprPrintOne}). There is no |\xintbooleval|. -\end{itemize} +% The user can define variables and functions. Definition of functions is either +% per parser (\csbxint{deffunc}, \csbxint{deffloatfunc}, ...), but there are +% some restrictions, or generic (\csbxint{NewFunction}) but the latter is only +% syntactic sugar for function-like disguise of a \TeX{} macro having not done +% any pre-parsing. -These macros are wrappers for a more core syntax: +There is a core syntax: \begin{itemize}[nosep] \item \csbxint{expr}\meta{expression}|\relax|, + \item \csbxint{iexpr}\meta{expression}|\relax|, \item \csbxint{iiexpr}\meta{expression}|\relax|, \item \csbxint{floatexpr}\meta{expression}|\relax|, - \item \csbxint{iexpr}\meta{expression}|\relax|, \item \csbxint{boolexpr}\meta{expression}|\relax|. \end{itemize} -This core syntax can be used directly in typesetting flow.\NewWith{1.4} In an -|\edef| they expand to some braced nested data (all computations having been -done) prefixed with some |\protected| «typesetter» macros. When using -\csbxint{eval} (in contrast to \csbxint{expr}), the protection of the -«typesetter» is by-passed and its action gives (expandably) -explicit digits and other characters such as those of scientific notation or -brackets.% +\csbxint{boolexpr}\meta{expression}|\relax| does all computations like +\csbxint{expr} then converts all (non-empty) leaves% +% +\footnote{Currently, empty leaves are output using \csbxint{exprEmptyItem}, + i.e.\@ default to \dtt{\xintexprEmptyItem}. This may change.} +% +to |True| or |False| (cf.\@ \csbxint{boolexprPrintOne}). There is no +|\xintbooleval|. + +Formerly this legacy syntax needed to be prefixed by |\xintthe| to appear in +the typesetting token flow. It may now be omitted.\NewWith{1.4} + +In an |\edef| these constructs expand to some braced nested data, all +computations having been completely done, which is prefixed with some +|\protected| «typesetter» macros. + +In an |\edef|, \csbxint{eval} (in contrast to \csbxint{expr}), or +\csbxint{floateval} (in contrast to \csbxint{floatexpr}) expand the +«typesetting macros» and the final complete expansion consists of +explicit digits and other characters such as those of scientific +notation or square brackets.% % \footnote{\csbxint{eval} and \csbxint{expr} both expand completely in exactly two steps. And \csbxint{expr} expands fully under \fexpan sion (of the @@ -5254,95 +4972,170 @@ brackets.% expand to nothing, then naturally \fexpan sion propagates to tokens following up in the input stream.} -It is possible to use the core syntax\NewWith{1.4} +In \LaTeX\ it is possible to use the core syntax\NewWith{1.4} \csbxint{expr}\meta{expression}|\relax| also in so-called moving arguments, -because when written out to a file the final expansion result uses only -standard catcodes and thus will get retokenized and the typesetter macro -(which being |\protected| is there intact in external file) will expand -as expected. +because when written out to a file the final expansion outcome uses only +standard catcodes and thus will get retokenized and expand as expected if +it has been written to an external file which is then reloaded. -One needs \csbxint{eval} et al.\@ only if one really wants the final digits (and -other characters), for example in a context where \TeX{} expects a number or a -dimension. +One needs \csbxint{eval} et al.\@ only if one really wants the final digits +(and other characters), for example in a context where \TeX{} expects a number +or a dimension. As alternative to \csbxint{eval}\marg{expression}, an equivalent is \csbxint{the}\csbxint{expr}\meta{expression}|\relax|. Similarly \csbxint{the} can prefix all other core parsers. And one can also use \csbxint{theexpr} as shortcut for \csbxint{the}\csbxint{expr}. -Throughout this documentation I will most of the time refer to \csbxint{eval} -and \csbxint{expr}. But beware that doing exact computations with fractions -leads very quickly to very big results (and furthermore one needs to use -explicitly the |reduce()| function to convert the fractions into smallest -terms). Thus most probably what you want is \csbxint{floateval} and -\csbxint{floatexpr}. - -\subsection{Expansion} +Doing exact computations with fractions leads very quickly to very big results +(and furthermore one needs to use explicitly the |reduce()| function to +convert the fractions into smallest terms). Thus most probably what you want +is \csbxint{floateval} and \csbxint{floatexpr}. -As mentioned already, the parsers are compatible with expansion-only -context. -Also, they expand the expression piece by piece: the normal mode of operation -of the parsers is to unveil the parsed material token by token. Unveiling is -a process combining space swallowing, brace removal (one level generally), and -\fexpan sion. +\subsection{Customization of the output from the three parsers} +\label{xintexprEmptyItem} +\label{xintexprPrintOne} +\label{xintiexprPrintOne} +\label{xintiiexprPrintOne} +\label{xintfloatexprPrintOne} +\label{xintboolexprPrintOne} -For example a closing parenthesis after some function arguments does not have -to be immediately visible, it and the arguments themselves may arise from -\fexpan sion (applied before grabbing each successive token). Even the ending -|\relax| may arise from expansion. Even though the \csbxint{eval} user -interface means that the package has at some point the entire expression in -its hands, it immediately re-inserts it into token stream with an additional -postfixed |\relax| and from this point on has lost any ways (a simple-minded -delimited macro won't do because the expression is allowed to contain -sub-\csbxint{expr}essions, even nested) to manipulate formally again the whole -thing; it can only re-discover it one token at a time. +The package provides only minimal facilities for formatting the numeric +output. A possibly not up-to-date list is (the first two use math +mode mark-up): \csbxint{TeXfromSci}, \csbxint{TeXFrac}, \csbxint{DecToString}, +\csbxint{PRaw}, \csbxint{FracToSci}, \csbxint{FracToDecimal}, +\csbxint{PFloat} and +\csbxint{FloatToDecimal}. More advanced formatting is left for the user to +provide by own macros or possibly using third-party packages. -This general behaviour (which allows much more freedom in assembling -expressions than is usually the case with familiar programming languages such -as Python, although admittedly that freedom will prove useful only to -power-\TeX users and possibly does not have that many significant use cases) -has significative exceptions. These exceptions are mostly related to -«pseudo»-functions. A «pseudo»-function will grab some of its arguments via -delimited macros. For example |subs(expr1,x=expr2)| needs to see the comma, -equal sign and closing parenthesis. But it has mechanisms to allow |expr1| and -|expr2| to possess their own commas and parentheses. - -Inner semi-colons on the other hand currently always can originate from expansion. -Defining functions or variables requires a visible semi-colon acting as -delimiter of the expression, but inner semi-colons do not need to be -hidden within braces or macros\NewWith{1.4}. +It is indeed possible to configure the parsers to use custom macros for output. +Here are the default package definitions: +\begin{everbatim} +\def\xintexprEmptyItem{[]} +\def\xintexprPrintOne{\xintFracToSci} +\def\xintiexprPrintOne{\xintDecToString} +\def\xintiiexprPrintOne #1{#1} +\def\xintfloatexprPrintOne{\xintPFloat} +\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} +\end{everbatim} +The typesetter for \csa{xintiiexpr} simply prints ``as is'', but this +may change in future, if some internal format is used requiring a +conversion step. Users can copy the above (\LaTeX\ users may want to +use |\renewcommand|) and modify the chosen macros. -The expansion stops only when the ending |\relax| has been found -(it is then removed from the token stream). +Regarding the current behaviour of \csbxint{floateval}, here is the +default configuration of \csbxint{PFloat}: +\begin{everbatim} +\def\xintPFloatE{e} +\def\xintPFloatZero{0} +\def\xintPFloatIntSuffix{} +\def\xintPFloatLengthOneSuffix{} +\def\xintPFloatNoSciEmax{5} +\def\xintPFloatNoSciEmin{-4} +\def\xintPFloatMinTrimmed{4} +\end{everbatim} +With the custom +\begin{everbatim} +\def\xintfloatexprPrintOne{\xintFloatToDecimal} +\end{everbatim} +the \csbxint{floateval} output wil use decimal fixed point notation, +i.e.\@ no scientific exponents, and as many zeros as are needed (but no +more, as trailing zeros will be removed from the significant digits). +Here is an example with the +default configuration and then when using \csbxint{FloatToDecimal}: +\begingroup % DÉBUT DU GROUPE POUR DES EXEMPLES +\begin{everbatim*} +\xintfloateval{exp(-32.456)/2000}\newline +\def\xintfloatexprPrintOne{\xintFloatToDecimal}% +\xintfloateval{exp(-32.456)/2000}\par +\end{everbatim*} -For catcode related matters see \csbxint{exprSafeCatcodes}. +Similarly, with +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToDecimal} +\end{everbatim} +the \csbxint{eval} output will use decimal fixed point notation (for the +numerators; the denominators are simply post-fixed with a |/| +delimiter). See \csbxint{FracToDecimal}, which like \csbxint{FracToSci} +however is not really a user level macro, it is restricted on its input +format, it understands only what is needed for the internal structure +currently used by \csbxint{eval}. Here is with the same input as above: +\begin{everbatim*} +\xinteval{exp(-32.456)/2000}\newline +\def\xintexprPrintOne{\xintFracToDecimal}% +\xinteval{exp(-32.456)/2000}\par +\end{everbatim*} +Notice that the |/2000| denominator remains ``as is'' in the +output in both cases, in conformity with the documented behaviour of +\csbxint{FracToSci} in the first example and of \csbxint{FracToDecimal} +for the second example. This has not changed since |1.4| (the handling +of the numerator part has changed at |1.4e| and again slightly at +|1.4k|, the zero value being now always printed as \dtt{0} and not +\dtt{0} or \dtt{0.0} depending on the input) but is to be considered +unstable and undecided so far. + +A more costly typesetter could be for example: +\begin{everbatim} +\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}} +\end{everbatim} +Then the fraction (inclusive of its power of ten part) will be reduced +to lowest terms (see \csbxint{Irr}), next the trailing zeros will be +moved as an exponent (positive or negative) to the numerator, and +finally this numerator with a power of ten part will be printed in +decimal fixed point notation, with as few zeros as are needed. With the +use case above: +\begin{everbatim*} +\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}} +\xinteval{exp(-32.456)/2000}\par +\end{everbatim*} +This trailing |/2| is somewhat of a pain, but as documented and +mentioned already \csbxint{DecToStringREZ} currently has not been +educated to identify its presence and handle it. Slightly faster (see +\csbxint{PIrr}) is +\begin{everbatim} +\def\xintexprPrintOne#1{\xintDecToStringREZ{\xintPIrr{#1}}} +\end{everbatim} +which with the used example produces the same output. -A word of warning on the bracketed optional argument of respectively -\csbxint{floatexpr} and \csbxint{iexpr}. When defining macros which will hand -over some argument to one of these two parsers, the argument may potentially -start with a left square bracket |[| (e.g. argument could be |[1, 2, 3]|) and -this will break the parser. The fix is to use in the macro definition -|\xintfloatexpr\empty|. This extra |\empty| token will prevent the parser -thinking there is an optional argument and it will then disappear during -expansion. +\endgroup % FIN DU GROUPE POUR LES EXEMPLES + +\medskip +Nested structures (for full internal details, see \autoref{oples}) +are rendered by default using left and right brackets, +commas and spaces in a non-customizable way, except via +\csa{xintexprEmptyItem}. For full customizability, use +\csbxint{thealign}, which is described in the next section. + +% The \csbxint{PFloatE} is now allowed to a be macro with an argument delimited +% by a dot, this argument will be the exponent.\NewWith{1.4e} The output must be produced +% \fexpan dably and again be delimited by a dot. The default does not grab the +% exponent and simply inserts the letter |e|. + +\paragraph{\TeX hackers note:} +Attention! The macros used in place of \csbxint{FracToSci} and +\csbxint{PFloat} must currently understand the raw \xintfracname format +|A/B[N]|, with the |/B| and |[N]| parts being optional. These requirements +may change at any release. + +Currently the interface for the macro used by +\csbxint{floatexprPrintOne} % changed at |1.4e|.\CHANGED{1.4e} +must be the same as +\csbxint{PFloat}. %, i.e. the target precision is |[P]| not a +%braced argument. +But it will always be employed with the |[P|] present hence does not +have to consider it to be optional. + +The replacement macros must be compatible with expansion-only context, but do not +have to be \fexpan dable. -\begin{footnotesize} - If comparing to other languages able to handle floating point numbers or big - integers, such as Python, one should take into account that what the \xintname - packages manipulate are streams of ascii bytes, one per digit. At no time - (due to expandability) is it possible to store intermediate results in an - arithmetic CPU register; each elementary operation via |\the\numexpr| will - output digit tokens (hence as many bytes), not things such as handles to - memory locations where some numbers are stored as memory words. The process - can never put aside things but can only possibly permute them with upcoming - tokens, to use them later, or, via combinations of |\expanded| and - |\unexpanded| or some other more antiquated means grab some tokens and shift - the expansion to some distant locations to later come back. The process is a - never-ending one-dimensional one...\par -\end{footnotesize} +% % pour mémoire +% \footnote{The constraints on any replacement to \csbxint{FracToSci} are much +% simplified at |1.4e|. Previously it had to be able to accept also input in +% fixed point notation, and in scientific notation with a catcode 12 |e|.} +% % -\subsection{\csh{xintthealign} and its customization} +\subsubsection{\csh{xintthealign} for multiple items outputs} \label{xintthealign} With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the @@ -5419,63 +5212,6 @@ l.c.m.=\xintthealign\xintiiexpr ndmap(lcm, 1..12; 1..10)\relax \] \end{everbatim*} -\subsection{Customization of typesetting of individual items} -\label{xintexprEmptyItem} -\label{xintexprPrintOne} -\label{xintiexprPrintOne} -\label{xintiiexprPrintOne} -\label{xintfloatexprPrintOne} -\label{xintboolexprPrintOne} - -The way individual items are formatted (whether or not using -\csa{xintthealign}) is also customizable. Here are the default package -definitions: -%\kern-2pt -% the \kern is to fix some extra white line from first line being a bit overfull -\begin{everbatim} -\def\xintexprEmptyItem{[]} -\let\xintexprPrintOne\xintFracToSci -\let\xintiexprPrintOne\xintDecToString -\def\xintiiexprPrintOne #1{#1} -\let\xintfloatexprPrintOne\xintPFloat -\def\xintPFloatE{e} -\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} -\end{everbatim} -Attention! The above macros convert from \xintexprname internal numeric data -format to «printed» output; they are thus susceptible to require adjustments -if the internal data format changes, which may happen at each release. Of course -the default for |\xintexprPrintOne| etc...\@ will be adjusted accordingly, but -user custom definitions may break. - -The interface for \csbxint{floatexprPrintOne} was changed.\CHANGED{1.4e} -It must now be the same as \csbxint{PFloat}, i.e. the target precision is |[P]| not a -braced argument. It will always be used with this |[P|] present so does not -have to consider it to be optional. It still must be expandable. - -The \csbxint{PFloatE} is now allowed to a be macro with an argument delimited -by a dot, this argument will be the exponent.\NewWith{1.4e} The output must be produced -\fexpan dably and again be delimited by a dot. The default does not grab the -exponent and simply inserts the letter |e|. - -Currently, this means that the macros used in place of \csbxint{FracToSci} and -\csbxint{PFloat} should understand the raw \xintfracname format |A/B[N]|, with -the |/B| and |[N]| parts being optional.% -% -\footnote{The constraints on any replacement to \csbxint{FracToSci} are much - simplified at |1.4e|. Previously it had to be able to accept also input in - fixed point notation, and in scientific notation with a catcode 12 |e|.} -% -The typesetter for -\csa{xintiiexpr} simply prints ``as is'', but this may change in future. - -The used macros must be compatible with expansion-only context, but do not -have to be \fexpan dable. - -Note: when not using \csbxint{thealign}, output of nested structures uses left -and right brackets, and commas and spaces in a non-customizable way, except -via \csa{xintexprEmptyItem}. Use the \csa{xintthealign} interface for full -customizability. - \subsection{Built-in operators and their precedences} @@ -6013,10 +5749,10 @@ Miscellaneous notes: % labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt, % listparindent=\leftmarginiii] - \funcdesc[]{random} returns a random float |x| verifying |0 <= x < 1|. It obeys - the prevailing precision as set by \csbxint{Digits}: i.e.\@ with |P| being the - precision the random float multiplied by |10^P| is an integer, uniformly - distributed in the |0..10^P-1| range. + \funcdesc[]{random} returns a random float |x| verifying |0 <= x < 1|. It + obeys the prevailing precision as set by \csbxint{Digits}: i.e.\@ with |P| + being the precision the random float multiplied by |10^P| is an integer, + uniformly distributed in the |0..10^P-1| range. This description implies that if |x| turns out to be |<0.1| then its (normalized) mantissa has |P-1| digits and a trailing zero, if |x<0.01| @@ -8243,6 +7979,454 @@ some example here... % obtained via the expansion of the package macros during the \TeX{} % run.% +\subsection{Oples and nutples: the \texttt{1.4} terminology} +\label{oples} + +\emph{Skip this on first reading, else you will never start using the + package.} \fbox{SKIP THIS!} (understood?) + +In this section I will describe a mathematical terminology which models +how the parser handles the input syntax with numbers, commas, and brackets, +and how it maps internally to \TeX\ specific concept, particularly braces and +macro arguments. + +\etocsetnexttocdepth{subsubsection} +\localtableofcontents + +\subsubsection{Base terminology} + +We start with a set $\mathcal{A}$ of \emph{atoms}, which represent numeric +data. In \TeX{} syntax such \emph{atoms} are always braced, more precisely, +currently they look like +% +\centeredline{\dtt{\{raw format within \TeX{} braces\}}} +% +The \TeX{} braces are not set-theoretical braces here, they are simply used +for \TeX nical reasons (one could imagine using rather some terminator token, +but ultimately support macros for built-in and user defined functions rely on +\TeX\ macros with undelimited parameters, at least so far). + +Our category $\mathcal{C}$ of «oples» is the smallest collection of +\emph{totally ordered finite sets} verifying these properties: +\begin{enumerate} +\item The empty set \dtt{$\emptyset$} is an \emph{ople}, i.e.\@ it belongs to + $\mathcal{C}$. +\item Each singleton set \dtt{$\{O\}$} whose element \dtt{$O$} is either an + \emph{atom} $a\in\mathcal{A}$ or an \emph{ople} qualifies as an \emph{ople}. +\item $\mathcal{C}$ is stable by concatenation. +\end{enumerate} + +Notes: +\begin{itemize} +\item +We refer to the empty set \dtt{$\emptyset$} via the variable \emph{nil}.% +% +\footnote{There is +actually a built-in variable with this name. At |1.4|, |\xintexpr\relax| is +legal and also generates the \emph{nil}.} + +\item It is convenient to accept the empty set as being also an + \emph{atom}. If this is done, then we may refer to the original + \emph{atoms} (elements of $\mathcal{A}$) as \emph{non empty numerical data}. + +\item +Concatenation is represented in the syntax by the +comma. Thus repeated commas are like only one and |nil| is a neutral element. + +\item A singleton \emph{ople} \dtt{$\{a\}$} whose single element is a + (non-empty) \emph{atom} is called a \emph{number}.% +% + \footnote{This has to be taken in a general sense, for example with + \ctanpackage{polexpr}, polynomials are represented by such «numbers».} +% + +\item +The operation of constructing \dtt{$\{O\}$} from the \emph{ople} \dtt{$O$} is +called \emph{bracing} (set theory, \TeX), or \emph{bracketing} (\xintexprname +input syntax, Python |lists|), or \emph{packing} (as a reverse to Python's +unpacking of sequence type objects). In the expression input syntax it +corresponds to enclosing \dtt{$O$} within square brackets: \dtt{$[O]$}. + +\item A braced \emph{ople} is called a \emph{nutple}. Among them \dtt{\{nil\}} + (aka $\{\emptyset\}$) is a bit special. It is called the \emph{none-ple}.% +% + \footnote{Prior to version |1.4j| of this documentation it was called the + \emph{not-ple}.} +% +It is not \dtt{nil}.% +% +\footnote{There is (experimental) a pre-defined «\dtt{None}» variable which + stands for the \emph{none-ple}. It can also be input as |[]|.} +\end{itemize} + +Each \emph{ople} has a \emph{length} which is its cardinality as set. The +singleton |oples| are called \emph{one-ples}. There are thus two types of +\emph{one-ples}: +\begin{itemize} +\item \emph{numbers} \dtt{$\{a\}$}, $a \in \mathcal{A}$, +\item \emph{nutples} \dtt{$\{O\}$}, $O \in \mathcal{C}$. +\end{itemize} + +If we consider the empty set |nil| on the same footing as |atoms|, the two +types have only one common object which is the \emph{none-ple}. As a rule +arithmetic operations will either break or silently convert the \emph{none-ple} +to the zero value: +\begin{everbatim*} +\xinteval{3+[], 5^[], 10*[]} +\end{everbatim*}. +But attention that \csbxint{iieval} in contrast to \csbxint{eval} is broken by +such inputs. + +\subsubsection{Items (and sub-items) versus elements} + +In order to illustrate these concepts, let us consider how one should +interpret notation such as |3,5,7,9| when it arises in an +\csbxint{expr}|ession|: +\begin{description} +\item[tempting vocabulary:] Each of |3|, |5|, |7|, and |9| is an \emph{item}, or + \emph{element} of the (comma separated) \emph{list}. In other terms we have + here a list with 4 items. +\item[rigorous vocabulary:] each one of |3|, |5|, |7|, |9| stands for an + \emph{ople} (of the \emph{one-ple} type) and |3,5,7,9| stands for their \emph{concatenation}. +\end{description} +It is important to understand that in an \csbxint{expr}|ession|, there is no +difference between |3,5,7| and |3,,,,5,,,,,,,,,7|. So the view of the comma +as separator is misleading. In other terms, the comma is NOT a separator but +the (associative) operator of concatenation of totally ordered sets, and the +number |3| for example represents a (singleton) set. + +If we want to refer to |3| or |5| or |7| or |9| as «the items of the +(open) list |3,5,7,9|» (and probably this documentation already has such +utterances, due to legacy reasons from the pre-|1.4| internal model), we +\emph{must} realize that this clashes with using the word \emph{item} as +synonymous to \emph{element} in the set-theoretical sense. + +To repeat, any ople \dtt{$O$} is a finite totally ordered set: if not the empty +set, it has \emph{elements} \dtt{$a_1$}, \dots, \dtt{$a_k$}, and the above means that +its \emph{items} are the singleton oples (aka one-ples) \dtt{$I_1=\{a_1\}$}, +\dots, \dtt{$I_k=\{a_k\}$}. Each \dtt{$a_j$} may be an |atom|, then +\dtt{$I_j$} is a |number|, or \dtt{$a_j$} is an |ople| (possibly the empty set), then +\dtt{$I_j$} is a |nutple| whose depth is one more than the one of the ople +\dtt{$a_j$}. + +Thus we can refer to «items» but must then understand they are not «elements»: +«items» are «singleton sub-sets». The cardinality (aka length) of an ople is +also the number of its +items. It would be tempting to use the terminology «sub-item» to keep in mind they are «sub-sets» +but this would again create confusion: a |nutple| has only one item which is +itself; and we need some terminology to refer to the individual numbers in the +|nutple| given in input as |[1,2,3]| for example. It is natural to refer to +|1|, |2|, |3| as «sub-items» of |[1,2,3]| as the latter may be an «item» (it +is in particular an «item» of itself, the unique one at that). + +We distinguish the |oples| of length zero (there is only one, the empty set) +or at least two as those which can never be an «item». Those of length one, +the |one-ples|, are exactly those which can be «items». Among them some may +have «sub-items», they are the |nutples| with the exception of the |none-ple|. +And the others do not have «sub-items», they are the |numbers| and the |none-ple| (whose input syntax is +either |[]| or the variable |None|).% +% +\footnote{% +A note on the \csbxint{verbosetrue} regime: for a variable defined to be +|3,5,7,9|, it will say that its value is |{3}{5}{7}{9}|, because it does not +keep the external set-theoretical braces. The braces here are only \TeX{} +braces, and |{3}| is an |atom|. The |number| would be |{{3}}| with the +external braces being set-theoretical and also used internally as \TeX{} +braces. From the four numbers |{{3}}|, ..., |{{9}}| concatenation gives +|{{3}{5}{7}{9}}|, which is the |ople| |3,5,7,9|. But the log view drops +deliberately the external braces. If the variable is defined to be the +|nutple| |[3,5,7,9]|, then the log view will be |{{3}{5}{7}{9}}| (up to +details on how exactly the numeric quantities are coded) and the actual +internal \TeX{} entity will be |{{{3}{5}{7}{9}}}|, where the two external +layers of braces are both set-theoretical and \TeX nical braces.} + + +\subsubsection{Oples as trees} + +We say that the empty set |nil| and \emph{atoms} are \emph{leaves}. + +We associate with any \emph{ople} a tree. The root is the ople. In the case of +the |nil| ople, there is nothing else than the root, which we then consider +also a \emph{leaf}. Else the children at top level are the successive +\emph{elements} (not «items»!) of the ople.% +% +\footnote{\label{fn:alttree}% + We could also consider a tree for which the children of the root node would + be its items and recursively; in that case the leaves would be |numbers| and + possibly the |None|. The tree of the |nil| would be the empty tree, the tree + of |None| would have a single node and no edges. Such a tree would match + the input syntax (of course applying the rule that iterated commas are like + only one). The tree which is described in this section matches more + directly the internal syntax, hence is more useful to the author, who is + also the sole reader who extracts some benefit from reading this + documentation once in a while.} +% +Among the elements some are \emph{atoms} giving \emph{leaves} of the tree, +others are \emph{nutples} which in turn have children. In the special case of +the \emph{none-ple} we consider it has a child, which is the empty set and this +is why we consider the empty set |nil| to be also a potential \emph{leaf}. We +then proceed recursively. We thus obtain from the root \emph{ople} a tree +whose vertices are either \emph{oples} or \emph{leaves}. Only the empty set +|nil| is both a \emph{leaf} and an \emph{ople}. + +Considering the empty set |nil| as an \emph{atom} fits with the \xintexprname +internal implementation based on \TeX: |nil| is an empty pair of braces |{}|, +whereas an \emph{atom} is a braced representation of a numeric value using +digits and other characters. We construct \emph{oples} by putting one after +the other such constituents and bracing them, and then repeating the process +recursively. + +It has also an impact on the definition of the \emph{depth} (a.k.a as +\emph{maximal dimension}) of an \emph{ople}. For example the \emph{ople} +$\{\emptyset A_1A_2\}$ with three elements, among them the empty set and two +atoms is said to have depth $1$, or to have maximal dimension $1$. And +$\{\{\emptyset\}A_1A_2\}$ is of depth $2$ because it has a leaf (the empty +set) which is a child of a child of the \emph{ople}. NumPy \emph{ndarrays} +have a more restricted structure for example +$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ is a $2$-dimensional array, where all +leaves are at the same depth. When slicing empties the array from its atoms, +NumPy keeps the shape information but prints the array as $[]$. This will not +be the case with \xintexprname, which has no other way to indicate the shape +than display it. +\begin{everbatim*} +\xinteval{[[],[]]} +\end{everbatim*} +\begin{everbatim*} +\xinteval{[[0,1],[10,11]][:,2:]} +\end{everbatim*} + +\subsubsection{Ople slicing and indexing} +\label{sssec:opleslicing} + +«Set-theoretical» slicing of an \emph{ople} means replacing it with one of its +subsets. This applies also if it is a \emph{number}. Then it can be sliced +only to itself or to the empty set (indeed it has only one element, which is +an atom). Similarly the \emph{none-ple} can only be sliced to give itself or +the empty set. And more generally a \emph{nutple} is a singleton so also can +only be set-sliced to either the empty set or itself. + +\xintexprname extends «Python-like» slicing to act on \emph{oples}: +\begin{itemize}[nosep] +\item if they are not \emph{nutples} set-theoretical slicing applies, +\item if they are \emph{nutples} (only case having a one-to-one + correspondence in Python) then the slicing happens \emph{within brackets}: + i.e.\@ the \emph{nutple} is unpacked then the set-theoretical slicing is + applied, then the result is \emph{repacked} to produce a new \emph{nutple}. +\end{itemize} +With these conventions the \emph{none-ple} for example is invariant under +slicing: unpacking it gives the empty set, which has only the empty set as +subset and repacking gives back the \emph{none-ple}. Slicing a general +\emph{nutple} returns a \emph{nutple} but now of course in general distinct +from the first one. + +The input syntax for Python slicing is to postfix a variable or a +parenthesized ople with |[a:b]|. See \autoref{ssec:lists} for more. There +are never any out-of-range errors when slicing or indexing. All operations +are licit and resolved by the |nil|, a.k.a. empty set. + +«Set-theoretical» item indexing of an \emph{ople} means reducing it to a +subset which is a singleton. It is thus a special case of set-theoretical +slicing (which is the general process of selecting a subset as replacement of +a set). + +\xintexprname extends «Python-like» indexing to act on \emph{oples}: +\begin{itemize}[nosep] +\item if they are not \emph{nutples} set-theoretical item indexing applies, +\item if they are \emph{nutples} (only case having a one-to-one + correspondence in Python) then the meaning becomes \emph{extracting}: i.e.\@ + the \emph{nutple} is unpacked then the set-theoretical indexing is applied, + but the result is \emph{not repacked}. +\end{itemize} +For example when applied to the \emph{none-ple} we always obtain +the |nil|. Whereas as we saw slicing the \emph{none-ple} always gives back the +\emph{none-ple}. Indexing is denoted in the syntax by postfixing by |[N]|. Thus +for \emph{nutples} (which are analogous to Python objects), there is genuine +difference between the |[N]| extractor and the |[N:N+1]| slicer. But for +\emph{oples} which are either |nil|, a \emph{number}, or of length at least 2, +there is no difference. + +\subsubsection{Nested slicing of oples} + +Nested slicing is a concept from NumPy, which is extended by \xintexprname to +trees of varying depths. We have a chain of slicers and extractors. I will +describe only the case of slicers and letting them act on a |nutple|. The +first slicer gives back a new |nutple|. The second slicer will be applied to +each of one of its remaining elements. However some of them may be +\emph{atoms} or the empty set. In the NumPy context all leaves are at the +same depth thus this can happen only when we have reached beyond the last +dimension (axis). This is not permitted by NumPy and generates an error. +\xintexprname does not generate an error. But any attempt to slice an +\emph{atom} or the empty set (as element of its container) removes it. Recall +we call them \emph{leaves}. We can not slice leaves. We can only slice +non-leaf elements: such items are necessarily |nutples|. The procedure then +applies recursively. + +If we handle an extractor rather than a slicer, the procedure is similar: we +can not extract out of an \emph{atom} or the empty set. They are thus +removed. Else we have a |nutple|. It is thus unpacked and replaced by the +selected element. This element may be an atom or the empty set and any further +slicer or extractor will remove them, or it is a |nutple| and the procedure +applies with the next slicer/extractor. + +\xintexprname allows to apply such a |[a:b,c:d,N,e:f,...]| chain of +slicing/extracting also to an \emph{ople}, which is not a \emph{nutple}. We +simply apply the first step as has been described previously and successive +steps will only get applied to either \emph{nutples} or \emph{leaves}, the +latter getting silently removed by any attempted operation. + +\subsubsection{Function arguments versus variables} +\label{sssec:funcargs} + +In a function declaration with \csbxint{deffunc}, the call signature is parsed +as a comma separated list, so here it is not true that repeated commas are +like only one: repeated commas are not allowed and will break the function +declaration. + +When \xintexprname parses a function call, it first constructs the ople which +is delimited by the opening and closing parentheses, then it applies the +function body, after having mapped the successive items (not the elements) of +the parsed ople to the variables appearing in the function call +signature. Hence the arguments in the call signature stand for |one-ples| +(i.e.\@ either |numbers| or |nutples|). + +Let me explain why we can not define a function |foo(A,B)| of two oples: the +function call will evaluate as an ople what is enclosed within the +parentheses. It is then impossible in general to split this uniquely into two +oples |A| and |B|, except if for example we know a priori the length of |A|. +We could imagine defining a declarative interface for a |foo(A,B)| with |A| +preset to have \dtt{37} items or at least a pre-defined number of items but +this is extraneous layer for a functionality no-one will use. + +The alternative would be to consider that declaring |foo(A,B)| means |A| will +pick-up always the first item and |B| all the remaining ones, and thus will be +an ople; here, there are some \TeX nical implementation reasons which have +dissuaded the author to do this. + +In its place, a special syntax |foo(A,*B)| for the declaration of the function +is available. It means that |B| stands for the |nutple| which +receives as items all arguments in the function call beyond the first one +already assigned to |A|. + +More generally, the last positional argument in a function declaration can +have the form |*|\meta{argname}. This then means that \meta{argname} +represents a |nutple| which will receive as items all arguments in the +function call remaining after the earlier positional arguments have been +assigned. The declared function body is free to again use the syntax +|*|\meta{argname} which will unpack it and thus produce the ople concatenating +all such optional arguments. + +With \csbxint{defvar} one can define a variable with value an |ople| of +arbitrary cardinality. Such a variable can be used in a function call, it +will then occupy the place of as many arguments as its cardinality (which is +its number of elements, hence of its associated items). For example if +function |foo| was declared as a function of 5 arguments |f(a,b,c,d,e)| it is +legitimate to use it as |f(A,B)| if |A| is an ople-valued variable of length +three and |B| of length two. The actual arguments |a,b,c,d,e| will be made to +match the three items of |A| and the two items of |B|. + +\subsubsection{Final words on leaves} + +In case things were too clear, let's try to add a bit of confusion with an +extra word on \emph{leaves}. When we discuss informally (particularly to +compare with NumPy) an input such as +\begin{everbatim} +[[1, 2], [3, 4]] +\end{everbatim} +we may well refer to |1|, |2|, |3|, and |4| as being «the leaves of the 2d +array». But obviously we have here numbers and previously we explained that a +number is not a \emph{leaf}, its \emph{atom} is. Well, the point here is that +we must make a difference between the input form as above and the actual +constructed \emph{ople} the parser will obtain out of it. In the input we do +have numbers. The comma is a \emph{concatenator}, it is not a separator for +enumeration! The \emph{ople} which corresponds to it has a \TeX{} +representation like this: +\begin{everbatim} +{{{1}{2}}{{3}{4}}} +\end{everbatim} +where we don't have the \emph{numbers} anymore (which would look like |{{1}}|, +|{{2}}|, ...) but numeric \emph{atoms} |{1}|, |{2}|, |{3}|, |{4}| where the +braces are \TeX{} braces and \textbf{not} set-theoretical braces (the other +braces are both). Hence we should see the above as the |ople| +$\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ with atoms $A_{00}=\{1\}$, ..., being the +\emph{leaves} of the tree associated to (or which is) the \emph{ople}. + +Numbers may be called the \emph{leaves} of the \textbf{input}, but once +parsed, the input becomes an \emph{ople} which is +(morally) a tree whose leaves are \emph{atoms} (and the empty set). +This discussion can also be revisited with footnote +%%\footref{fn:alttree} +\ref{fn:alttree} in mind. + +\subsubsection{Farewell, thanks for your visit!} + +I hope this is clear to everyone. If not, maybe time to say this section is +not needed to understand almost all of the manual, but I needed to +write it to be able to maintain in future my own software. + +\subsection{Expansion (for geeks only)} + +As mentioned already, the parsers are compatible with expansion-only +context. + +Also, they expand the expression piece by piece: the normal mode of operation +of the parsers is to unveil the parsed material token by token. Unveiling is +a process combining space swallowing, brace removal (one level generally), and +\fexpan sion. + +For example a closing parenthesis after some function arguments does not have +to be immediately visible, it and the arguments themselves may arise from +\fexpan sion (applied before grabbing each successive token). Even the ending +|\relax| may arise from expansion. Even though the \csbxint{eval} user +interface means that the package has at some point the entire expression in +its hands, it immediately re-inserts it into token stream with an additional +postfixed |\relax| and from this point on has lost any ways (a simple-minded +delimited macro won't do because the expression is allowed to contain +sub-\csbxint{expr}essions, even nested) to manipulate formally again the whole +thing; it can only re-discover it one token at a time. + +This general behaviour (which allows much more freedom in assembling +expressions than is usually the case with familiar programming languages such +as Python, although admittedly that freedom will prove useful only to +power-\TeX users and possibly does not have that many significant use cases) +has significative exceptions. These exceptions are mostly related to +«pseudo»-functions. A «pseudo»-function will grab some of its arguments via +delimited macros. For example |subs(expr1,x=expr2)| needs to see the comma, +equal sign and closing parenthesis. But it has mechanisms to allow |expr1| and +|expr2| to possess their own commas and parentheses. + +Inner semi-colons on the other hand currently always can originate from expansion. +Defining functions or variables requires a visible semi-colon acting as +delimiter of the expression, but inner semi-colons do not need to be +hidden within braces or macros\NewWith{1.4}. + +The expansion stops only when the ending |\relax| has been found +(it is then removed from the token stream). + +For catcode related matters see \csbxint{exprSafeCatcodes}. + +A word of warning on the bracketed optional argument of respectively +\csbxint{floatexpr} and \csbxint{iexpr}. When defining macros which will hand +over some argument to one of these two parsers, the argument may potentially +start with a left square bracket |[| (e.g. argument could be |[1, 2, 3]|) and +this will break the parser. The fix is to use in the macro definition +|\xintfloatexpr\empty|. This extra |\empty| token will prevent the parser +from thinking there is an optional argument and it will then disappear during +expansion. + +\begin{footnotesize} + If comparing to other languages able to handle floating point numbers or big + integers, such as Python, one should take into account that what the \xintname + packages manipulate are streams of ascii bytes, one per digit. At no time + (due to expandability) is it possible to store intermediate results in an + arithmetic CPU register; each elementary operation via |\the\numexpr| will + output digit tokens (hence as many bytes), not things such as handles to + memory locations where some numbers are stored as memory words. The process + can never put aside things but can only possibly permute them with upcoming + tokens, to use them later, or, via combinations of |\expanded| and + |\unexpanded| or some other more antiquated means grab some tokens and shift + the expansion to some distant locations to later come back. The process is a + never-ending one-dimensional one...\par +\end{footnotesize} \clearpage \etocdepthtag.toc {part1B} @@ -8279,6 +8463,10 @@ At \dtt{8} digits a special, faster, mode is used, which is less accurate. But f under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Söll}, let them both be thanked here. +Jürgen passed away in 2022. I will miss our friendship which was born and grew +from numerous and regular exchanges on topics not limited to this package or +even the \TeX\ world. Let's now continue to «take care and keep motivated» ! + \subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig} The library is loaded automatically by \xintexprname at start-up. @@ -8717,7 +8905,7 @@ anecdotical evidence showing it is good. \markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} \etocdepthtag.toc {macros} -\addtocontents{toc}{\gdef\string\sectioncouleur{{joli}}} +\addtocontents{toc}{\gdef\string\sectioncouleur{{tocbundlesectioncolor}}} \addtocontents{toc}{\gdef\string\SKIPSECTIONINTERSPACE{\kern\smallskipamount}} \renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} @@ -9328,18 +9516,14 @@ be expressed as such a fraction even if the inputs are both integers and the mathematical result is an integer. The |B=1| is not removed.% % \footnote{refer to the documentation of \csbxint{PRaw} for an alternative.} -\item macros with |Float| in their names produce on output scientific -format with |P=|\nobreak\csbxint{theDigits} digits, a lowercase |e| and an -exponent |N|. The first digit is not zero, it is preceded by an optional minus -sign and is followed by a dot and |P-1| digits. Trailing zeroes are not -trimmed. There is one exceptional case: -\begin{itemize}[nosep] -\item if the value is mathematically zero, it is output as |0.e0|, - i.e.\@ zeros after the decimal mark are removed and the exponent is always |0|. -\end{itemize} -Future versions of the package may modify this. -\end{itemize} +\item macros from \xintfracname having |Float| in their names deliver a number + in the scientific notation as described in the documentation of + \csbxint{Float}. + The exceptions are \csbxint{PFloat} and its variant \csbxint{PFloatb} which + do some customizable pretty printing of the result. The former is also used + by default by \csbxint{floateval}. +\end{itemize} \subsection{Count registers and variables}\label{sec:useofcount} @@ -10811,7 +10995,7 @@ positive, and |N = 10^x Q - R| if |Q| turns out to be negative, which is exactly the case when |N| is at most |-10^x|. |\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as -|\xintDSH|\x\n, \emph{i.e.\@} multiplication by $10^{-|x|}$. For |x| zero or +|\xintDSH|\x\n, \emph{i.e.\@} multiplication by $10^{-\text{|x|}}$. For |x| zero or positive it returns the two numbers |{Q}{R}| described above, each one within braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed simultaneously. @@ -10994,9 +11178,10 @@ satisfy |d>0| and |M^2-d=N| with \xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B \end{everbatim*} -A rational approximation to $\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ which is a -majorant and the error is at most |1/2M| (if |N| is a perfect square |k^2| -this gives |k+1/(2k+2)|, not |k|.) +A rational approximation to $\sqrt{\text{|N|}}$ is +$\text{|M|}-\frac{\text{|d|}}{\text{|2M|}}$ which is a majorant and the error +is at most |1/2M| (if |N| is a perfect square |k^2| this gives |k+1/(2k+2)|, +not |k|.) Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating point numbers. @@ -11530,7 +11715,7 @@ to proceed is via a redefinition of \csbxint{floatexprPrintOne} and/or \csbxint{exprPrintOne}. \begin{everbatim*} \[\def\xintfloatexprPrintOne[#1]#2{\xintTeXfromSci{\xintPFloat[#1]{#2}}} - \xintfloateval{[10] 2^100, 3^100, 13^100}\] + \xintfloateval[10]{2^100, 3^100, 13^100}\] \end{everbatim*} \par\vskip-\belowdisplayskip \begin{everbatim*} @@ -11777,70 +11962,35 @@ from removing the |[N]| part if |N=0| and removing the |B| if |B=1|. \xintPRaw {123e10/321e10}, \xintPRaw {123e9/321e10}, \xintPRaw {\xintIrr{861/123}} \end{everbatim*} -\subsection{\csh{xintFracToSci}}\label{xintFracToSci} - - -\csa{xintFracToSci}\NewWith{1.4} is for usage by \csbxint{eval} for formatting -the output of numbers: the output routine of \csbxint{eval} uses -\csbxint{exprPrintOne} whose current default definition is: -\begin{everbatim} -\let\xintexprPrintOne\xintFracToSci -\end{everbatim} -Any replacement should obey the following blueprint: -\begin{itemize}[noitemsep] -\item to\xtype{} be expandable, but not necessarily \fexpan dable, -\item to accept on input |A|, |A/B|, |A[N]|, or |A/B[N]|, i.e. the ``raw'' - \xintfracname format, but with optional |/B| and |[N]| parts, - which can be called the ``relaxed raw format''. -\end{itemize} -These constraints\CHANGED{1.4e} are much simplified at |1.4e| (and \csa{xintFracToSci} has -been internally simplified to only have to obey the reduced constraints, which -is a breaking change). - -At |1.4e| the handling\CHANGED{1.4e} by this macro of input with a scientific -exponent part has changed. Rather than producing an integer mantissa it now -does as \csbxint{PFloat} (apart from the float-rounding of course) in -particular it trims out trailing zeros. - -Attention, \csa{xintFracToSci} does not behave as the other public macros from -\xintfracname: -\begin{itemize}[noitemsep] -\item it is expandable, but not \fexpan dable, so it can't appear as argument - to other \xintfracname macros without an explicit |\expanded{...}| wrapper - (as they only \fexpan d their arguments). -\item it expects input already (after \fexpan sion) in ``relaxed raw'' - \xintfracname format.\IMPORTANT{} -\end{itemize} - -\noindent\csa{xintFracToSciE} has been removed at |1.4e|, see \csbxint{PFloatE}. - \subsection{\csh{xintDecToStringREZ}}\label{xintDecToStringREZ} -\csa{xintDecToStringREZ}\etype{\Ff} uses fixed point notation -for the output. The argument is first parsed in the same way as for any other -\xintfracname macros,\NewWith{1.4e} which means that it is first transformed into an -internal format having a numerator |A|, a denominator |B| and a power of ten -exponent |N|. The following recipe applies: +\csa{xintDecToStringREZ}\etype{\Ff} uses fixed point (decimal) notation +for the output. The |REZ| means that it trims (REmoves) trailing Zeros. The name +is a bit strange, because\NewWith{1.4e} it its not limited to +\emph{decimal numbers} but accepts the same kind of inputs as most other +\xintfracname macros. The parsing of this input transforms it first +into an internal format having a numerator |A|, a denominator |B| and a +power of ten exponent |N|, standing for the fraction |A/B| times +\dtt{10} to the power |N|. Then the following recipe applies: \begin{itemize}[noitemsep] \item the zero value is printed as \dtt{\xintDecToStringREZ{0}} (no decimal point). \item trailing zeros of |A| and |B| are removed and |N| is adjusted, \item if the new |B| is not \dtt{1}, it will appear in the output as |/B|, -\item fixed point notation is used for |AeN|: +\item fixed point decimal notation is used for |AeN|: \begin{itemize}[noitemsep] \item if |N| is non-negative, the output is an integer with |N| trailing - zeros, + zeros (and no decimal mark) \item if |N| is negative a decimal point is used, and if |AeN| is less than - one in absolute value, output will start with \dtt{0.} (with a decimal point). + one in absolute value, output will start with \dtt{0.} (i.e. a decimal mark). \end{itemize} \end{itemize} -Please note the following: +The following should be noted: \begin{enumerate}[noitemsep] \item the fraction |AeN/B| or even |A/B| is not pre-reduced into lowest terms, \item the macro does not check if |B| contains only powers of \dtt{2} and \dtt{5}, so |1/2| is printed as \dtt{\xintDecToString{1/2}}, not as \dtt{0.5}. \end{enumerate} -The definitive behaviour remains to be decided regarding these two points. - +The definitive behaviour remains to be decided regarding these last two points. \begin{everbatim*} \xintDecToStringREZ{0}, \xintDecToStringREZ{1/2}, \xintDecToStringREZ{0.5000}\newline \xintDecToStringREZ{1.23456789e5}, \xintDecToStringREZ {1.23456789e-3}\newline @@ -11850,15 +12000,22 @@ The definitive behaviour remains to be decided regarding these two points. \xintDecToStringREZ{70/14} % is not reduced to lowest terms \end{everbatim*} +See \csbxint{FloatToDecimal} for a variant which first rounds the input +to some given number of significant digits. + \subsection{\csh{xintDecToString}}\label{xintDecToString} -\csa{xintDecToString}\etype{\Ff} uses fixed point notation for the output. It -was introduced at |1.3| as experimental backport from a -\href{http://ctan.org/pkg/polexpr}{polexpr} macro, and its behaviour remains -somewhat undecided in particular regarding whether it should identify inputs -which correspond to decimal numbers, \emph{after reduction to lowest terms}. +\csa{xintDecToString}\etype{\Ff} uses fixed point notation for the output. +Is behaviour remains +somewhat undecided in so far as whether it should identify inputs +which correspond to decimal numbers (i.e. fractions with only powers of +two and five in their denominator, once reduced to lowest terms). + +As with \csbxint{DecToStringREZ}, the name is a bit strange as inputs are in no +way limited to decimal numbers but are of the most general type accepted by +the \xintfracname macros. -It follows the same rules as \csbxint{DecToStringREZ} except that it does not +It is the same macro as \csbxint{DecToStringREZ} except that it does not remove trailing zeros, in fact \csbxint{DecToStringREZ}|{f}| is defined as \csbxint{DecToString}|{|\csbxint{REZ}|{f}}|. @@ -11872,13 +12029,16 @@ remove trailing zeros, in fact \csbxint{DecToStringREZ}|{f}| is defined as \end{everbatim*} Since |1.4e|\CHANGED{1.4e}, \csbxint{DecToString} is the default for -\csbxint{iexprPrintOne}, which governs the \csbxint{ieval} output format (in -this use case there is never a |/B| fractional part). +\csbxint{iexprPrintOne}, which governs the \csbxint{ieval} output format: in +this use case there is never a |/B| fractional part and the output is always +either an integer (if \csbxint{ieval} was used without optional argument) or a +decimal string \begin{everbatim} -\let\xintiexprPrintOne\xintDecToString +\def\xintiexprPrintOne{\xintDecToString} \end{everbatim} -Any replacement of \csbxint{iexprPrintOne} should obey the following blueprint: +Any replacement of \csbxint{DecToString} as the expansion of +\csbxint{iexprPrintOne} should obey the following blueprint: \begin{itemize}[noitemsep] \item to\xtype{} be expandable, but not necessarily \fexpan dable, \item to accept on input |A| or |A[N]|. @@ -12717,7 +12877,9 @@ expression will be fed to |\numexpr|. It is a shortcut for doing See also the \xintexprname-added variant \csbxint{SetDigits*}. \end{framed} -\subsection{\csh{xintFloat}}\label{xintFloat} +\subsection{\csh{xintFloat}} +\label{xintFloat} +\label{xintFloatZero} The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional @@ -12729,8 +12891,13 @@ prefixed by a minus sign and is followed by a dot and |P-1| digits, then a lower case |e| and an exponent |N|. The trailing zeroes are not trimmed. \begin{framed} - There is currently one exceptional case: the zero value, which gets output - as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be. + There is one exception to the general description: the zero value, which + gets output as \dtt{\xintFloat{0}}.\CHANGEDf{1.4k} This was changed at + |1.4k|, until then it was using \dtt{0.e0} as output. Customize via + \csh{xintFloatZero} whose default definition is: +\begin{everbatim} +\def\xintFloatZero{0.0e0} +\end{everbatim} \end{framed} Starting with |1.2k|, when the input is a fraction |AeN/BeM| @@ -12776,81 +12943,282 @@ transitive in the number of kept digits. +\subsection{\csh{xintFloatToDecimal}} +\label{xintFloatToDecimal} + +|\xintFloatToDecimal [P]{f}|\etype{{\upshape[\numx]}\Ff} does float rounding +on input like \csbxint{Float} then outputs the number using decimal notation, +i.e. with as many zeros as are needed (and no more) and no scientific +exponent.\NewWith{1.4k} + +In other terms it behaves (and is essentially defined) as: +\begin{everbatim} +\xintDecToStringREZ{\xintFloat[optional P]{<input>}} +\end{everbatim} +Examples: +\begin{everbatim*} +\xintFloatToDecimal{6.02e23}\newline +\xintFloatToDecimal{6.02000000000000e23}\newline +\xintFloatToDecimal[20]{1/7e10}\newline +\xintFloatToDecimal[30]{1/7e10} +\end{everbatim*} + +See \csbxint{DecToString}. + \subsection{\csh{xintPFloat}} \label{xintPFloat} -\label{xintPFloatE} |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like \csbxint{Float} but ``pretty-prints'' the output. -This macro was added at |1.1| as a (very primitive) "prettifying printer" for -floating point number, and was basically influenced by Maple. +This macro was initially added at |1.1| as a (very primitive) "prettifying +printer" for floating point number, and was then somewhat influenced by Maple, +for example the zero value was printed as "\dtt{0.}". Then at |1.4e| there was +breaking change and the rules became somewhat similar to observed Python +behaviour: mantissas trimmed of trailing zeros (whether or not scientific +notation was used in the output) and integers printed with a trailing +"\dtt{.0}", in particular the zero value was printed as "\dtt{0.0}". -The old rules were: -\begin{enumerate}[nosep] -\item The input is float-rounded to either |Digits| or the optional argument, -\item zero is printed as \dtt{0.}, -\item \dtt{x.yz...eN} is printed ``as is'' if the exponent |N| is at least - \dtt{6} or at most \dtt{-6}, -\item else fixed point decimal notation is used, -\item and there is no trimming of trailing zeroes. -\end{enumerate} +|1.4k|\CHANGED{1.4k} brings some breaking changes, which are reversible +via customizing macros: +\begin{itemize} +\item Integers (when scientific notation is dropped) without a "\dtt{.0}" + suffix. +\item Same for the zero value, now "\dtt{\xintPFloat{0}}". +\item Significands are trimmed of trailing zeros only if that removes at least + \dtt{4} zeros. The rationale is that automatic removal of trailing zeros + (which was influenced at |1.4e| from practice with Python in interactive + mode) proves annoying visually with aligned values in tables, as this + creates voids, so we want to do this only when really the + presence of trailing zeros is not some kind of numerical fluke. +\end{itemize} +These changes impact the \csbxint{floateval} output as +\csbxint{floatexprPrintOne} defaults to using \csbxint{PFloat}. -At |1.4e|, there is breaking change\CHANGED{1.4e}. The new rules are: +The default rules are thus now: \begin{enumerate}[nolistsep] -\item The input is float-rounded to either |Digits| or the optional argument, -\item zero is printed as \dtt{0.0}, -\item \dtt{x.yz...eN} is printed in decimal fixed point if |-4<=N<=+5| - else it is printed in scientific notation, -\item Trailing zeros of the mantissa are trimmed always, -\item In case of decimal fixed point output format, and the value is an integer, there - is a trailing |.0|, -\item In case of scientific notation with a one-digit trimmed mantissa - there is an added |.0| too. +\item The input is float-rounded to either |Digits| or the optional argument. +\item zero is printed as \dtt{\xintPFloat{0}}.\CHANGED{1.4k} +\item \dtt{x.yz...eN} is printed in decimal fixed point if + $-4\leq\text{|N|}\leq+5$ else it is printed in scientific notation. +\item Trailing zeros of the mantissa are trimmed if, and only if there are at least \dtt{4} + of them.\CHANGED{1.4k} +\item In case of fixed point output format, and the value is an integer, the + integer is printed with no decimal mark.\CHANGED{1.4k} +\item In case of scientific notation output format, and the mantissa has only + one digit, no decimal mark is used. \end{enumerate} +Please note that ``trailing zeros'' refers to the ``trailing zeros of the full width +significand after float-rounding'', and not only to trailing zeros used in the input. + +% The old rules were: +% \begin{enumerate}[nosep] +% \item The input is float-rounded to either |Digits| or the optional argument, +% \item zero is printed as \dtt{0.}, +% \item \dtt{x.yz...eN} is printed ``as is'' if the exponent |N| is at least +% \dtt{6} or at most \dtt{-6}, +% \item else fixed point decimal notation is used, +% \item and there is no trimming of trailing zeroes. +% \end{enumerate} -The |1.4e| changes will affect all usages of \csbxint{floateval} as the latter -applies per default (cf.\@ \csbxint{floatexprPrintOne}) \csbxint{PFloat} to -each numerical leaf of the computed expression. +% At |1.4e|, there is breaking change\CHANGED{1.4e}. The new rules are: -\csa{xintPFloatE}\NewWith{1.4b} was added to allow customizing the -symbol used on output for separating the significand from the exponent, if -output uses scientific notation. The separator defaults to |e|, according to -this definition: +\begingroup\color{everbatimxfgcolor} +\begin{multicols}2 +\def\test #1{\item #1${}\to{}$\xintPFloat{#1}}% +\string\xintDigits\ at \xinttheDigits +\begin{itemize}[nosep,font=\normalcolor] +\test {0} +\test {1.2340000e-7}\test {1.2340000e-6}\test {1.2340000e-5}\test {1.2340000e-4} +\test {1.2340000e-3}\test {1.2340000e-2}\test {1.2340000e-1} +\test {1.2340000e0}\test {1.2340000e1}\test {1.2340000e2}\test {1.2340000e3} +\test {1.2340000e4}\test {1.2340000e5}\test {1.2340000e6}\test {1.2340000e7} +\test {1e-7/7}\test {1e-6/7}\test {1e-5/7}\test {1e-4/7} +\test {1e-3/7}\test {1e-2/7}\test {1e-1/7} +\test {1e0/7}\test {1e1/7}\test {1e2/7}\test {1e3/7} +\test {1e4/7}\test {1e5/7}\test {1e6/7}\test {1e7/7} +\end{itemize} +\end{multicols} +\endgroup + +\subsubsection{Customizing macros of \csh{xintPFloat}} +\label{xintPFloatE} +\label{xintPFloatZero} +\label{xintPFloatIntSuffix} +\label{xintPFloatLengthOneSuffix} +\label{xintPFloatNoSciEmin} +\label{xintPFloatNoSciEmax} +\label{xintPFloatMinTrimmed} + +A number of macros allow to customize the behaviour of \csbxint{PFloat}: +\begin{itemize} +\item \csa{xintPFloatE}\NewWith{1.4b} allows to modify the separator of the + scientific notation. Here is its default: +% + \footnote{For \TeX perts: it is allowed to define + \csa{xintPFloatE} as a macro which grabs the exponent as an argument + delimited by a dot, and produces \fexpan dably an output also delimited by + a dot (it will removed via further internal processing).\NewWith{1.4e}} +% \begin{everbatim} \def\xintPFloatE{e} \end{everbatim} -It is now possible\NewWith{1.4e} to let it grab the exponent as an argument (delimited by a -dot) and format it (output must be delimited by a dot, which will be removed -later on). +\item \csa{xintPFloatZero}\NewWith{1.4k} says how to print the zero value. + The default: +\begin{everbatim} +\def\xintPFloatZero{0} +\end{everbatim} + +\item \csa{xintPFloatIntSuffix}\NewWith{1.4k} is postfixed to integer values + (when scientific notation is not used). Its default at |1.4k| is to add + nothing. It replaces the formerly hard-coded "\dtt{.0}" from |1.4e| (prior + to that trailing zeros from the full significand of |P| or + \csbxint{theDigits} digits were not trimmed). +\begin{everbatim} +\def\xintPFloatIntSuffix{} +\end{everbatim} + +\item \csa{xintPFloatLengthOneSuffix}\NewWith{1.4k} is postfixed to trimmed + mantissas having only one digit, when scientific notation is used. Its + default at |1.4k| is to add nothing. It replaces formerly hard-coded + "\dtt{.0}". +\begin{everbatim} +\def\xintPFloatLengthOneSuffix{} +\end{everbatim} + +\item \csa{xintPFloatNoSciEmax}\NewWith{1.4k} is the maximal scientific exponent + which will trigger use of decimal fixed point notation and + \csa{xintPFloatNoSciEmin} is the minimal one. Their defaults at |1.4k| are the + same as the formerly hard-coded behaviour from |1.4e|: +\begin{everbatim} +\def\xintPFloatNoSciEmax{5} +\def\xintPFloatNoSciEmin{-4} +\end{everbatim} + For example (with the package default width of \dtt{16} digits for mantissas + of floating point numbers): \begin{everbatim*} -\begin{multicols}2 -\def\test #1{#1${}\to{}$\xintPFloat{#1}}\string\xintDigits\ at \xinttheDigits -\begin{itemize}[nosep] -\item \test {0} -\item \test {1.2340000e-7} -\item \test {1.2340000e-6} -\item \test {1.2340000e-5} -\item \test {1.2340000e-4} -\item \test {1.2340000e-3} -\item \test {1.2340000e-2} -\item \test {1.2340000e-1} -\end{itemize} -Change of scientific separator to |E|.\def\xintPFloatE{E}% -\begin{itemize}[nosep] -\item \test {1.2340000e0} -\item \test {1.2340000e1} -\item \test {1.2340000e2} -\item \test {1.2340000e3} -\item \test {1.2340000e4} -\item \test {1.2340000e5} -\item \test {1.2340000e6} -\item \test {1.2340000e7} -\end{itemize} -\end{multicols} +\begingroup +\def\xintPFloatNoSciEmin{-20} +\xintPFloat{1e-19/7}\newline +\xintPFloat{1e-20/7}\par +\def\xintPFloatNoSciEmax{19} +\xintPFloat{1e20/7}\newline +\xintPFloat{1e21/7}\par +\endgroup \end{everbatim*} +\item \csa{xintPFloatMinTrimmed}\NewWith{1.4k} is the minimal number +of trailing zeros which have to be present to activate actual trimming. +The default definition is: +\begin{everbatim} +\def\xintPFloatMinTrimmed{4} +\end{everbatim} +Defining it to expand to \dtt{-1} or \dtt{0} will enable the trimming of +trailing zeros always, and setting it to a high value will prevent it +altogther. + +\end{itemize} + +To mimick approximately the Python behaviour in interactive sessions, +one can use the following configuration: +\begin{everbatim} +\def\xintPFloatZero{0.0}% +\def\xintPFloatIntSuffix{.0}% +\def\xintPFloatLengthOneSuffix{.0}% +\def\xintPFloatNoSciEmax{15}% +\def\xintPFloatNoSciEmin{-4}% +\def\xintPFloatMinTrimmed{-1}% +\end{everbatim} +\begingroup\color{everbatimxfgcolor} +\def\xintPFloatZero{0.0}% +\def\xintPFloatIntSuffix{.0}% +\def\xintPFloatLengthOneSuffix{.0}% +\def\xintPFloatNoSciEmax{15}% +\def\xintPFloatNoSciEmin{-4}% +\def\xintPFloatMinTrimmed{-1}% +\def\test#1{#1${}\to{}$\xintPFloat{#1}\newline}% +\test{0.} +\test{1234.} +\test{6e100} +\test{1234567812345678.12345678} +\test{12345678123456781.2345678} +\test{12345678.12340} +\test{12345678.123400} +\test{0.1234567812345678} +\test{0.00012345678123456785} +\test{0.000012345678123456785}\par +\endgroup +% +The above using the default \csbxint{Digits} setting of \dtt{16} digits. +This can not naturally match exactly CPython which uses internally radix +|2| not |10|, and has (by default) mantissas with \dtt{53=1+52} bits. + +Same, but playing with \ctanpackage{xintsession} in its |&fp| mode: +\begin{everbatim} +>>> &fp +fp mode (16 digits) +>>> \\def\xintPFloatZero{0.0} +(executing \\def\xintPFloatZero {0.0} in background) +) +Runaway argument? +def\xintPFloatZero {0.0}\message { +}\xs_fetch_aa \endinput +! File ended while scanning use of \\. +<inserted text> + \par +<*> xintsession^^M + +? S +OK, entering \scrollmode... + +*\xintsession + + You are back to the xintexpr interactive session! + (current mode: fp (Digits=16), with Digits=16) + + ">>> " means central computing is waiting for input + "... " means that multi-line input continues. Use `;' to terminate it. + + Say `&bye' at any time to terminate the session and the TeX run. +>>> \def\xintPFloatZero{0.0} +(executing \def \xintPFloatZero {0.0} in background) + +>>> \def\xintPFloatIntSuffix{.0}\def\xintPFloatLengthOneSuffix{.0} + +(executing \def \xintPFloatIntSuffix {.0}\def \xintPFloatLengthOneSuffix {.0} i +n background) + +>>> \def\xintPFloatNoSciEmax{15}\def\xintPFloatNoSciEmin{-4} + +(executing \def \xintPFloatNoSciEmax {15}\def \xintPFloatNoSciEmin {-4} in back +ground) + +>>> \def\xintPFloatMinTrimmed{-1} +(executing \def \xintPFloatMinTrimmed {-1} in background) + +>>> 0., 1234., 6e100; +@_1 0.0, 1234.0, 6.0e100 +>>> 1234567812345678.12345678; +@_2 1234567812345678.0 +>>> 12345678123456781.2345678; +@_3 1.234567812345678e16 +>>> 12345678.12340; +@_4 12345678.1234 +>>> 12345678.123400; +@_5 12345678.1234 +>>> 0.1234567812345678; +@_6 0.1234567812345678 +>>> 0.00012345678123456785; +@_7 0.0001234567812345679 +>>> 0.000012345678123456785; +@_8 1.234567812345679e-5 +>>> &bye +\end{everbatim} +This is with version |0.4alpha (2021-11-01)| of +\ctanpackage{xintsession}. Probably some ``magic'' shortcuts will be +added in future to its interface for this kind of tasks, in place of +the |\def|. % \subsection{\csh{xintFloatE}}\label{xintFloatE} % %! {\small New with |1.097|.} @@ -13035,7 +13403,7 @@ handled exactly. And as said above its absolute value may exceed the \TeX\ bound \subsection{\csh{xintFloatSqrt}}\label{xintFloatSqrt} \csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating -point approximation of $\sqrt{|f|}$, either using the optional precision |P| or +point approximation of $\sqrt{\text{|f|}}$, either using the optional precision |P| or the value of |\xinttheDigits|. More precisely since |1.2f| the macro achieves so-called \emph{correct @@ -13838,7 +14206,7 @@ needs a general calculus of special functions. This is why the package \csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff} evaluates the sum -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\text{|n|}}$. The +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot \text{|f|}^{\text{|n|}}$. The initial and final indices are given to a |\numexpr| expression. The |\coeff| macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time |\coeff{n}| is needed) should be defined as a one-parameter expandable macro, @@ -13942,7 +14310,7 @@ an expanding only context, doing |\edef\g{\f}| is no option, then \csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx} computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ with each +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot \text{|f|}^{\,\text{|n|}}$ with each term of the series truncated to |D| digits\etype{\Ff\Ff\numx} after the decimal point. As usual, |A| and |B| are completely expanded through their inclusion in a @@ -14011,7 +14379,7 @@ of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give estimate a priori how many ending digits are not reliable: if there are |N| terms and |N| has |k| digits, then digits up to but excluding the last |k| may usually be trusted. If we are optimistic and the series is -alternating we may even replace |N| with $\sqrt{|N|}$ to get the number |k| +alternating we may even replace |N| with $\sqrt{\text{|N|}}$ to get the number |k| of digits possibly of dubious significance. \subsection{\csh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} @@ -14033,7 +14401,7 @@ Let us illustrate this on the numerical exploration of the identity % Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus, |D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10 -terms of their respective series. We will assume $|h|<0.5$. With only +terms of their respective series. We will assume $\text{|h|}<0.5$. With only ten terms kept in the power series we do not have quite 3 digits precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things more precisely than, say circa 5 digits after the decimal points. @@ -14094,7 +14462,7 @@ release. \noindent\csa{xintFloatPowerSeries}|[P]{A}{B}{\coeff}{f}|% \ntype{{\upshape[\numx]}\numx\numx} computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot \text{|f|}^{\,\text{|n|}}$ with a floating point precision given by the optional parameter |P| or by the current setting of |\xintDigits|.\etype{\Ff\Ff} @@ -16926,61 +17294,65 @@ before a problematic (but reasonable) character catcode, or even to use \subsubsection{\csh{xintexprSafeCatcodes}} \label{xintexprSafeCatcodes} -For an even more radical way, there is \csbxint{exprSafeCatcodes} which sets -the catcodes of many characters to safe values. This is a non-expandable step -as it changes catcodes. +Some problems with active characters can be resolved on the fly by prefixing +them by |\string| but some aspects of the parsing done by \csbxint{expr} +involves delimited macros which need the comma, equality sign and closing +parenthesis to have their standard catcodes. + +So \csbxint{exprSafeCatcodes} is provided as a utility to set in one go +catcodes of many characters to \csbxint{expr}-safely compatible values. This +is a non-expandable step as it changes catcodes. % This is used % internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it % does not have to be protected against active characters when used at % top-level. -\csbxint{defvar}, \csbxint{deffunc}, et al., execute it before fetching their -semi-colon delimited arguments, so they can be used (also in the document -body) for example with Babel+French (which makes the semi-colon active in the -(\LaTeX) document body). This applies also to \csbxint{NewExpr}. +\csbxint{defvar}, \csbxint{deffunc}, et al., use it, and then they restore +catcodes to the prior state via \csbxint{exprRestoreCatcodes}. % As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some % |\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the % expressions, even if all is from the replacement text of some macro whose % definition was done under some special catcode regime. -But, if used in the body of macro definitions problems may arise from the -catcode regime at that location. This applies in particular to the -semi-colon as used by \csbxint{deffunc}, \csbxint{defvar} and variants as -delimiter. Thus make sure the semi-colon has its normal catcode when issueing -\csbxint{deffunc} inside some macro definition. +% \csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of +% characters in expression bodies as it does some |\scantokens| which will reset +% compatible catcodes. -\csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of -characters in expression bodies as it does some |\scantokens| which will reset -compatible catcodes. And also, characters inside the -expression may usually be prefixed with |\string|; but some aspects of the parsing -use delimited macros which need the comma, equality sign and closing -parenthesis to have standard catcodes. +% Even if used in a context where catcodes are already set, \csbxint{deffunc}, +% \csbxint{defvar} and variants ignore completely the colon in |:=| so it can +% have any (reasonable) catcode. Moreover it is optional. -Even if used in a context where catcodes are already set, \csbxint{deffunc}, -\csbxint{defvar} and variants ignore completely the colon in |:=| so it can -have any (reasonable) catcode. Moreover it is optional. - -The semi-colon in the syntax of \csbxint{Digits} is no real problem either -(cf. \csbxint{Digits} documentation). - -\begin{framed} - It is important to ALWAYS shortly let \csbxint{exprSafeCatcodes} be followed - by \csbxint{exprRestoreCatcodes}.\IMPORTANTf{} If one uses twice - \csbxint{exprSafeCatcodes} then the next \csbxint{exprRestoreCatcodes} will - restore the ancient catcode regime at time of the first one. -\end{framed} +% The semi-colon in the syntax of \csbxint{Digits} is no real problem either +% (cf. \csbxint{Digits} documentation). \subsubsection{\csh{xintexprRestoreCatcodes}} \label{xintexprRestoreCatcodes} -Restores the catcodes to the earlier state. More precisely, -\csbxint{exprSafeCatcodes} sets a toggle (with local scope). If the toggle is -set already it does not restore the current catcodes. The next -\csa{xintexprRestoreCatcodes} unsets the toggle. -So, in case of nesting, the -catcodes are restored to what they were when the \emph{first} un-paired -\csbxint{exprSafeCatcodes} got executed. +Restores the catcodes to the state prevailing at the time of the last executed +\csbxint{exprSafeCatcodes} (if located at the same \LaTeX\ environment or +\TeX\ grouping level). + +Prior to |1.4k|, in a situation like the following: +\begin{everbatim} +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprRestoreCatcodes +\end{everbatim} +On exit, the catcodes recovered their status as prior to the \emph{first} +\csbxint{exprSafeCatcodes}. Since |1.4k|, they are set to what they were +prior to the \emph{last} \csbxint{exprSafeCatcodes}, i.e. the mechanism is now +similar to a ``last in, first out'' stack. + +Note that no global assignments are made so the behaviour can be modified +by usage of \TeX\ groups or \LaTeX\ environments: e.g. if an +\csbxint{exprSafeCatcodes} is issued inside a \LaTeX\ environment it does not +have to be paired by \csbxint{exprRestoreCatcodes} explicitly, the catcode +scope is limited by the environment. \bigskip @@ -16988,30 +17360,26 @@ Spaces inside an |\xinttheexpr...\relax| should mostly be innocuous (except inside macro arguments). |\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding -catcodes: (unbraced) digits, binary operators, minus and plus signs as -prefixes, dot as decimal mark, parentheses, may be indifferently of catcode -letter or other or subscript or superscript, ..., it doesn't matter.% -% -\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is - escape-char agnostic. It should work with any \csa{escapechar} setting - including -1.} - -The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, -|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if -in the expression, as everything is expanded along the way. If one of them is -active, it should be prefixed with |\string|. +catcodes, % (unbraced) digits, binary operators, minus and plus signs as +% prefixes, dot as decimal mark, parentheses, may be indifferently of catcode +% letter or other or subscript or superscript, ..., except that they +% should not be \emph{active}, as for example are |!?;:| with |babel-french|.% +% % +% \footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is +% escape-char agnostic. It should work with any \csa{escapechar} setting +% including -1.} +but the characters +% |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, +%|=|, |(|, |)|, |"|, |[|, |]|, |;|, +in the expression should not be «active» (except on purpose) as everything is +expanded along the way, and |\xintexpr| will choke on typesetting related +commands. One can use |\string| to prefix a problematic character. -The exclamation mark |!| should have its standard catcode: with catcode letter -it is used internally and hence will confuse the parsers if it comes from the -expression. Digits, slash, square brackets, minus sign, in the output from an |\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the output has its standard catcode ``letter''. -A macro with arguments will expand and grab its arguments before the -parser may get a chance to see them, so the situation with catcodes and spaces -is not the same within such macro arguments. @@ -17258,37 +17626,41 @@ arguments having at most |P| significant places already. \label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval} \csbxint{eval}\etype{x} is an \fexpan dable macro which is basically defined -like this (DON'T BELIEVE THIS; it has been entirely revamped at |1.4|): +like this (this is obsolete since |1.4|): \begin{everbatim} -\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}% OLD DEFINITION < 1.4 +\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}% THIS IS OLD DEFINITION \end{everbatim} -thus expands in two steps (its exact definition differs from the one given -above in order to achieve a slight optimization). +thus expands in two steps. \begin{everbatim*} \xinteval{add(x^2, x = 100..110), add(x^3, x = 100..110)} \end{everbatim*} -\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its optional -argument must be located inside the braces: +\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its +optional argument may be located in the expected location for \LaTeX\ users +since |1.4k|, but was long constrained to be inside the braces. \begin{everbatim*} -\xintieval{[7] 355/113} +\xintieval[7]{355/113} = \xintieval{[7]355/113} \end{everbatim*} +If one defines a macro which will do something such as |\xintieval{#1}| it is +recommended to code it as |\xintieval{\empty#1}| in case the |#1| will start +with some |[|, which will end up confusing |\xintieval|. + \csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}. \begin{everbatim*} \xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)} \end{everbatim*} -\csbxint{floateval}\etype{x} is similarly related to \csbxint{thefloatexpr}. Its optional -argument must be located inside the braces: +\csbxint{floateval}\etype{x} is similarly related to +\csbxint{thefloatexpr}. The same remarks as for |\xintieval| apply. \begin{everbatim*} -\xintfloateval{[7] 355/113} +\xintfloateval [7]{355/113} = \xintfloateval{[7] 355/113} \end{everbatim*} -When negative it tells how many digits to remove from the prevailing precision -(\csbxint{theDigits}): +When negative, the optional argument tells how many digits to remove from the +prevailing precision (\csbxint{theDigits}): \begin{everbatim*} -\xintfloateval{[-2] 355/113} has \xinttheDigits\ minus 2 digits. +\xintfloateval[-2]{355/113}=\xintfloateval{[-2]355/113} has \xinttheDigits\ minus 2 digits. \end{everbatim*} These macros are useful when one uses some extra wrapper doing some parsing of @@ -17327,6 +17699,111 @@ from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in \end{everbatim*} +\subsection{\csh{xintFracToSci}}\label{xintFracToSci} + +% je ne dois pas mettre \Ff car la macro n'utilise pas \XINT_infrac + +\csa{xintFracToSci}\NewWith{1.4} is for usage by \csbxint{eval} for +formatting the output of numbers. It is not meant for direct use at +user level as it currently expects input formatted in the so-called +``relaxed raw format'' from \xintfracname, i.e. |A/B[N]|, with |/B| and +|[N]| being optional parts, and |A|, |B|, |N| being integers, |B| always +positive if present, and |A| having at most one leading minus sign (and +no sign if it is zero, and no leading zeros). + +Here is what it does:\CHANGED{1.4e} +\begin{itemize}[noitemsep,nosep] +\item with input respectively: |A|, |A/B|, |A[N]|, |A/B[N]| +\item it produces this output: |A|, |A/B| (if |B| is not |1|), |A| if + |N=0|, |A/B| if |N=0| (no |B| if |1|), and if + |N| is not zero, the output will be |AeN| written in scientific notation + exactly like it would by \csbxint{PFloat} but without of course prior + rounding to a given number of digits; in particular trailing zeros in the + significand will be removed. Then this value in scientific notation + (or decimal fixed point notation if the scientific exponent is in the + range deciding so by \csbxint{PFloat}) will be attached to a trailing + denominator part |/B| (if not equal to |1|). +\end{itemize} +Please note: +\begin{itemize} +\item there is no reduction of the fraction |A/B| to lowest terms, +\item trailing zeros in |B| are not moved and incorporated +into the final scientific exponent, +\item no attempt is made to check is |B| is only products of |2|'s and + |5|'s and thus could be integrated into some pure decimal notation for + the numerator or at least its significand. +\end{itemize} +This has not changed since |1.4| but is to be considered +\emph{unstable}. Actually even the description above was until |1.4k| +only to be found in the commented source code... So everything is +susceptible to change at some later release. + +Changes\CHANGED{1.4k} of \csbxint{PFloat} at |1.4k| have an impact here. +In particular the zero value will give \dtt{0} whether the input was +some |0|, |0e-5|, |0/3|, |0.00|, etc\dots, whereas at |1.4e| it would +have been +\dtt{0.0} for cases triggering some \csbxint{PFloat} subroutine. See +\csbxint{PFloatZero} for reenacting the |1.4e| behaviour. + +\medskip + +The output routine of \csbxint{eval} uses +\csbxint{exprPrintOne} whose current default definition is: +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToSci} +\end{everbatim} +Any replacement should obey the following blueprint: +\begin{itemize}[noitemsep] +\item to\xtype{} be expandable, but not necessarily \fexpan dable, +\item to accept on input |A|, |A/B|, |A[N]|, or |A/B[N]|, i.e. the + ``relaxed raw'' + \xintfracname format. +\end{itemize} +% These constraints\CHANGED{1.4e} are much simplified at |1.4e| (and +% \csa{xintFracToSci} has been internally simplified to only have to obey +% the reduced constraints, which is a breaking change). + +% At |1.4e| the handling\CHANGED{1.4e} by this macro of input with a scientific +% exponent part has changed. Rather than producing an integer mantissa it now +% does as \csbxint{PFloat}, apart of course from its initial step of +% float-rounding. It trims out trailing zeros of the input always. + +Attention, \csa{xintFracToSci} does not behave as do the public macros from +\xintfracname: +\begin{itemize}[noitemsep] +\item it is expandable, but not \fexpan dable, so it can't appear as argument + to \xintfracname macros without an explicit |\expanded{...}| wrapper + (as they only \fexpan d their arguments). +\item it expects input which after \fexpan sion will be in ``relaxed raw'' + \xintfracname format.\IMPORTANT{} +\end{itemize} + +%\noindent\csa{xintFracToSciE} has been removed at |1.4e|, see \csbxint{PFloatE}. + +\subsection{\csh{xintFracToDecimal}} +\label{xintFracToDecimal} + +% je ne dois pas mettre \Ff car la macro n'utilise pas \XINT_infrac +% mais je pourrais utiliser \xtype +It is a variant of \csbxint{FracToSci}\NewWith{1.4k} +which differs from it in so far as it outputs a numerator using decimal +notation, i.e. with as many zeros as are needed (and no more) and no +scientific exponent. The denominator goes through ``as is'' except if +it is |1|, then it is omitted. + +In other terms its behaviour is currently intermediate between +\csbxint{DecToString} and \csbxint{DecToStringREZ}, as it does not +remove trailing zeros of the denominator. + +It is not meant to be used directly as it shares the same limitations +of \csbxint{FracToSci} for user level usage, but solely as a way to +customize \csbxint{exprPrintOne}: +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToDecimal} +\end{everbatim} +Consider its behaviour as \emph{unstable} and \emph{barely documented}. + + \subsection{The \csh{xintthecoords} macro} \label{xintthecoords} @@ -19157,7 +19634,7 @@ currently this is implemented by using either |\xintifForFirst| or \etocsettocdepth{subsubsection}% 2015/09/15 \etocdepthtag.toc {implementation} -\addtocontents{toc}{\gdef\string\sectioncouleur{[named]{RoyalPurple}}} +\addtocontents{toc}{\gdef\string\sectioncouleur{{tocsectionimpcolor}}} \def\storedlinecounts {} \def\StoreCodelineNo #1{\edef\storedlinecounts{% @@ -19182,7 +19659,8 @@ currently this is implemented by using either |\xintifForFirst| or \makestarlowast \xmacro@code } -\def\macro@font {\ttbfamily }% slashed 0 +% finally 2022/05/17 removes slashed 0 dedicated ttbfamily usage +\def\macro@font {\ttfamily }% % \lverb % ====== @@ -19253,7 +19731,7 @@ currently this is implemented by using either |\xintifForFirst| or % there is a group to handle restore \def\MicroFont {%\ttzfamily - \color[named]{Purple}\makestarlowast } + \color{verbimpcolor}\makestarlowast } % privatecodecomments % =================== @@ -19278,6 +19756,16 @@ currently this is implemented by using either |\xintifForFirst| or \hangindent\parindent } +% \added +% ====== + +% new 2022/05/16 +\newcommand\added[2][]{% + \par\smallskip\noindent + \textbf{Added at #2\space(\xintreleasedate{#2})\if\relax\detokenize{#1}\relax + \else\space[on #1]\fi.}% +} + % \xintreleasedate % ================ @@ -19674,7 +20162,7 @@ math shift catcode. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2021/07/13 v1.4j Paraphernalia for the xint packages (JFB)]% + [2022/05/18 v1.4k Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -20634,7 +21122,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2021/07/13 v1.4j Expandable and non-expandable utilities (JFB)]% + [2022/05/18 v1.4k Expandable and non-expandable utilities (JFB)]% % \end{macrocode} % \lverb|\XINT_toks is used in macros such as \xintFor. It is not used % elsewhere in the xint bundle.| @@ -22995,7 +23483,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2021/07/13 v1.4j Expandable arithmetic on big integers (JFB)]% + [2022/05/18 v1.4k Expandable arithmetic on big integers (JFB)]% % \end{macrocode} % \subsection{(WIP!) Error conditions and exceptions} % \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification @@ -26349,7 +26837,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2021/07/13 v1.4j Expandable operations on big integers (JFB)]% + [2022/05/18 v1.4k Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -28928,7 +29416,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2021/07/13 v1.4j Expandable binary and hexadecimal conversions (JFB)]% + [2022/05/18 v1.4k Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb|1.2n switches to \csname-governed expansion at various places.| @@ -29600,7 +30088,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2021/07/13 v1.4j Euclide algorithm with xint package (JFB)]% + [2022/05/18 v1.4k Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintBezout}} % \lverb|& @@ -30134,7 +30622,7 @@ mode) and will go ahead hoping repair\endcsname %\let<*xintfrac>\gardesinactifs %</xintgcd>^^A---------------------------------------------------- %<*xintfrac>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 72; sentence-end-double-space: t; -*- % \clearpage\csname xintfracnameUp\endcsname % \section{Package \xintfracnameimp implementation} % \RaisedLabel{sec:fracimp} @@ -30200,7 +30688,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2021/07/13 v1.4j Expandable operations on fractions (JFB)]% + [2022/05/18 v1.4k Expandable operations on fractions (JFB)]% % \end{macrocode} % \subsection{\csh{XINT_cntSgnFork}} % \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or @@ -30229,8 +30717,6 @@ mode) and will go ahead hoping repair\endcsname {% \expandafter#1% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \the\numexpr \XINT_abs##1+% \XINT_len_fork ##2##3\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: @@ -30240,7 +30726,13 @@ mode) and will go ahead hoping repair\endcsname }}\XINT_flen{ }% % \end{macrocode} % \subsection{\csh{XINT_outfrac}} +% \changed{1.06b} % \lverb|& +% 1.06b version now outputs 0/1[0] and not 0[0] in case of zero. More generally +% all macros have been checked in xintfrac, xintseries, xintcfrac, to make sure +% the output format for fractions was always A/B[n]. (except \xintIrr, +% \xintJrr, \xintRawWithZeros). +% % Months later (2014/10/22): perhaps I should document what this macro does % before I forget? from {e}{N}{D} it outputs N/D[e], checking in passing if % D=0 or if N=0. It also makes sure D is not < 0. I am not sure but I don't @@ -30278,17 +30770,22 @@ mode) and will go ahead hoping repair\endcsname }% % \end{macrocode} % \subsection{\csh{XINT_inFrac}}\label{src-XINT_infrac} +% \added{1.03} % \lverb|& % Parses fraction, scientific notation, etc... and produces {n}{A}{B} % corresponding to A/B times 10^n. No reduction to smallest terms. -% +% | +% \changed{1.07} +% \lverb|& % Extended in 1.07 to accept scientific notation on input. With lowercase % e only. The \xintexpr parser does accept uppercase E also. Ah, by the way, % perhaps I should at least say what this macro does? (belated addition % 2014/10/22...), before I forget! It prepares the fraction in the internal % format {exponent}{Numerator}{Denominator} where Denominator is at least 1. -% -% 2015/10/09: this venerable macro from the very early days (1.03, 2013/04/14) +% | +% \changed[2015/10/09]{1.2} +% \lverb|& +% This venerable macro from the very early days % has gotten a lifting for release 1.2. There were two kinds of issues: % % 1) use of \W, \Z, \T delimiters was very poor choice as this could clash with @@ -30339,7 +30836,9 @@ mode) and will go ahead hoping repair\endcsname % numerator and denominator will be parsed for the more general format % allowing decimal digits and scientific part and possibly multiple leading % signs. -% +% | +% \changed{1.2l} +% \lverb|& % 1.2l fixes frailty of \XINT_infrac (hence basically of all xintfrac macros) % respective to non terminated \numexpr input: \xintRaw{\the\numexpr1} for % example. The issue was that \numexpr sees the / and expands what's next. @@ -30380,8 +30879,7 @@ mode) and will go ahead hoping repair\endcsname }% % \end{macrocode} % \lverb|An empty [] is not allowed. (this was authorized in 1.2, removed in -% 1.2f). As nobody reads xint documentation, no one will have noticed the -% fleeting possibility.| +% 1.2f).| % \begin{macrocode} \def\XINT_infrac_res_ca #1[#2]\xint:/\XINT_W[\XINT_W\XINT_T {\expandafter{\the\numexpr #2}{#1}{1}}% @@ -30391,14 +30889,19 @@ mode) and will go ahead hoping repair\endcsname {\expandafter{\the\numexpr #3}{#2}{#1}}% % \end{macrocode} % \subsection{\csh{XINT_frac_gen}} -% \lverb|Extended in 1.07 to recognize and accept scientific notation both at +% \changed{1.07} +% \lverb|Extended at to recognize and accept scientific notation both at % the numerator and (possible) denominator. Only a lowercase e will do here, % but uppercase E is possible within an \xintexpr..\relax -% -% Completely rewritten for 1.2 2015/10/10. The parsing handles inputs such as +% | +% \changed{1.2} +% \lverb|& +% Completely rewritten. The parsing handles inputs such as % \A.\Be\C/\D.\Ee\F where each of \A, \B, \D, and \E may need f-expansion and % \C and \F will end up in \numexpr. -% +% | +% \changed{1.2f} +% \lverb|& % 1.2f corrects an issue to allow \C and \F to be \count variable (or % expressions with \numexpr): 1.2 did a bad \numexpr0#1 which allowed only % explicit digits for expanded #1.| @@ -30467,16 +30970,12 @@ mode) and will go ahead hoping repair\endcsname {% \expandafter\XINT_frac_gen_F\the\numexpr #5-#2-% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \numexpr\XINT_length_loop #1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \relax\expandafter~% \romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop @@ -30518,8 +31017,9 @@ mode) and will go ahead hoping repair\endcsname % \lverb|This is the core macro for \xintREZ. To be used as % \romannumeral0\XINT_factortens{...}. Output is A.N. (formerly {A}{N}) where % A is the integer stripped from trailing zeroes and N is the number of -% removed zeroes. Only for positive strict integers! -% +% removed zeroes. Only for positive strict integers!| +% \changed{1.3a} +% \lverb|& % Completely rewritten at 1.3a to replace a double \xintReverseOrder by a % direct \numexpr governed expansion to the end and back, à la 1.2. I should % comment more... and perhaps improve again in future. @@ -30681,6 +31181,7 @@ mode) and will go ahead hoping repair\endcsname }% % \end{macrocode} % \subsection{\csh{xintRaw}} +% \added{1.07} % \lverb|& % 1.07: this macro simply prints in a user readable form the fraction after its % initial scanning. Useful when put inside braces in an \xintexpr, when the @@ -30694,8 +31195,10 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_raw #1#2#3{ #2/#3[#1]}% % \end{macrocode} % \subsection{\csh{xintiLogTen}} +% \added{1.3e} % \lverb|& -% New at 1.3e. The exponent a, such that 10^a<= abs(x) < 10^(a+1). +% The exponent a, such that 10^a<= abs(x) < 10^(a+1). No rounding done on x, +% handled as an exact fraction. % | % \begin{macrocode} \def\xintiLogTen {\the\numexpr\xintilogten}% @@ -30735,7 +31238,7 @@ mode) and will go ahead hoping repair\endcsname }% % \end{macrocode} % \subsection{\csh{xintPRaw}} -% \lverb|1.09b| +% \added{1.09b} % \begin{macrocode} \def\xintPRaw {\romannumeral0\xintpraw }% \def\xintpraw @@ -30774,94 +31277,6 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% % \end{macrocode} -% \subsection{\csh{xintFracToSci}} -% \lverb|1.4, refactored and much simplified at 1.4e. -% -% It only needs to be x-expandable, and indeed the implementation here is only -% x-expandable. -% -% (2021/04/13) the user documentation was really deplorable, I have -% tried to improve it and in the process tried to remember what this macro was -% supposed to do, and improved comments here, also lamentable. -% -% At 1.4e-dev this became provisorily basically like defunct \xintSPRaw, but -% doing less parsing at it does not go to \xintPRaw with its \XINT_infrac -% induced overhead. Previous 1.4b \xintFracToSci was much complicated from -% having to allow fixed point notation on input and scientific notation with a -% catcode 12 "e". Refactoring of \xintiexpr has removed these constraints. -% Now: -% -%( Input: A, A/B, A[N], A/B[N] -%: Output: AeN/B with special cases: -%: 0 if input gives a zero value -%: /B is skipped in output if B=1 in input -%: eN is skipped in output if N=0 in input -%) -% -% 0[N] when N not zero is possible as input, but 0/B currently not I think, -% and -0 for example never arises as one is guaranteed that A is in strict -% integer format. -% -% (2021/05/05) Finally for 1.4e release I modify. This is breaking -% change for all \xinteval output in case of scientific notation: it will not -% be with an integer mantissa, but in regular scientific notation, using the -% same rules as \xintPFloat. -% -% Of course there will be no float rounding applied! Also, as [0] will always -% or almost always be present from an \xinteval, we want then to use integer -% not scientific notation. But expression contained decimal fixed point input, -% or uses scientific functions, then probably the N will not be zero and this -% will trigger usage of scientific notation in output. -% -% Implementing these changes sort of ruin our previous efforts to minimize -% grabbing the argument, but well. So the rules now are -% -%( Input: A, A/B, A[N], A/B[N] -%: Output: A, A/B, A if N=0, A/B if N=0 -%: If N is not zero, scientific notation like \xintPFloat,& -% i.e. behaviour like \xintfloateval apart from the rounding& -% to Digits. In particular trailing zeros are trimmed. -%: The zero gives 0, except in A[N] and A/B[N] cases, it may give& -% 0.0 -%) -% -% As a result of these last minute 1.4e changes, the \xintFracToSciE is -% removed. -% | -% -% \begin{macrocode} -\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToSci #1/#2#3[#4% -{% - \xint_gob_til_W #2\XINT_FracToSci_noslash\W - \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R - \XINT_FracToSci_slash_N #1/#2#3[#4% -}% -\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R - \XINT_FracToSci_noslash_N #2[#3% -}% -\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% -{% - \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1[#2]}% - \fi -}% -\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% -{% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\if\XINT_isOne{#3}1\else/#3\fi\fi -}% -\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% -{% - \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1#2[#4]}% - \fi - \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi -}% -% \end{macrocode} % \subsection{\csh{xintRawWithZeros}} % \lverb|& % This was called \xintRaw in versions earlier than 1.07| @@ -30890,7 +31305,8 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_rawz_Bb #1#2{ #2/#1}% % \end{macrocode} % \subsection{\csh{xintDecToString}} -% \lverb|1.3. This is a backport from polexpr 0.4. It is definitely not in +% \added{1.3} +% \lverb|This is a backport from polexpr 0.4. It is definitely not in % final form, consider it to be an unstable macro.| % \begin{macrocode} \def\xintDecToString{\romannumeral0\xintdectostring}% @@ -30913,13 +31329,15 @@ mode) and will go ahead hoping repair\endcsname }% % \end{macrocode} % \subsection{\csh{xintDecToStringREZ}} -% \lverb|1.4e. And I took this opportunity to improve documentation in manual.| +% \added{1.4e} +% \lverb|And I took this opportunity to improve documentation in manual.| % \begin{macrocode} \def\xintDecToStringREZ{\romannumeral0\xintdectostringrez}% \def\xintdectostringrez#1{\expandafter\XINT_dectostr\romannumeral0\xintrez{#1}}% % \end{macrocode} % \subsection{\csh{xintFloor}, \csh{xintiFloor}} -% \lverb|1.09a, 1.1 for \xintiFloor/\xintFloor. Not efficient if big negative +% \added{1.09a} +% \lverb|1.1 for \xintiFloor/\xintFloor. Not efficient if big negative % decimal exponent. Also sub-efficient if big positive decimal exponent.| % \begin{macrocode} \def\xintFloor {\romannumeral0\xintfloor }% @@ -30931,7 +31349,7 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_ifloor #1/#2.{\xintiiquo {#1}{#2}}% % \end{macrocode} % \subsection{\csh{xintCeil}, \csh{xintiCeil}} -% \lverb|1.09a| +% \added{1.09a} % \begin{macrocode} \def\xintCeil {\romannumeral0\xintceil }% \def\xintceil #1{\xintiiopp {\xintFloor {\xintOpp{#1}}}}% @@ -30969,8 +31387,6 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_denom_fork #1% {% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \ifnum#1<\xint_c_ \expandafter\XINT_denom_B @@ -30983,10 +31399,10 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_denom_B -#1.#2#3{\XINT_dsx_addzeros{#1}#3;}% % \end{macrocode} % \subsection{\csh{xintTeXFrac}} -% \lverb|1.03 (2013/04/14). Useless typesetting macro. -% -% Renamed (2021/05/24) from \xintFrac at 1.4g. Old name deprecated but -% still usable.| +% \added{1.03} +% \lverb|Useless typesetting macro.| +% \changed[2021/05/24]{1.4g} +% \lverb|Renamed from \xintFrac. Old name deprecated but still usable.| % \begin{macrocode} \ifdefined\documentclass \def\xintfracTeXDeprecation#1#2{% @@ -31030,8 +31446,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_fracfrac_E \fi\space\frac #1#2{\fi \space #1\cdot }% % \end{macrocode} % \subsection{\csh{xintTeXsignedFrac}} -% \lverb|& -% Renamed (2021/05/24) from \xintSignedFrac at 1.4g. Old name deprecated but +% \changed[2021/05/24]{1.4g} +% \lverb|Renamed from \xintSignedFrac. Old name deprecated but % still usable.| % \begin{macrocode} \def\xintSignedFrac {\xintfracTeXDeprecation\xintSignedFrac\xintTeXsignedFrac}% @@ -31061,7 +31477,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintTeXfromSci}} -% \lverb|1.4g. The main problem is how to name this and related macros. +% \added{1.4g} +% \lverb|The main problem is how to name this and related macros. % % I use \expanded here, as \xintFracToSci is not f-expandable. But why do I % bother with the external \expanded? @@ -31096,8 +31513,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \fi % \end{macrocode} % \subsection{\csh{xintTeXOver}} -% \lverb|& -% Renamed (2021/05/24) from \xintFwOver at 1.4g. Old name deprecated but +% \changed[2021/05/24]{1.4g} +% \lverb|Renamed from \xintFwOver. Old name deprecated but % still usable.| % \begin{macrocode} \def\xintFwOver {\xintfracTeXDeprecation\xintFwOver\xintTeXOver}% @@ -31127,8 +31544,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintTeXsignedOver}} -% \lverb|& -% Renamed (2021/05/24) from \xintSignedFwOver at 1.4g. Old name deprecated but +% \changed[2021/05/24]{1.4g} +% \lverb|Renamed from \xintSignedFwOver. Old name deprecated but % still usable.| % \begin{macrocode} \def\xintSignedFwOver {\xintfracTeXDeprecation\xintSignedFwOver\xintTeXsignedOver}% @@ -31197,9 +31614,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_rez_E #1.#2.#3.{ #3/#2[#1]}% % \end{macrocode} % \subsection{\csh{xintE}} -% \lverb|1.07: The fraction is the first argument contrarily to \xintTrunc and -% \xintRound. -% +% \added{1.07} +% \lverb|The fraction is the first argument contrarily to \xintTrunc and +% \xintRound.| +% \changed{1.1} +% \lverb|& % 1.1 modifies and moves \xintiiE to xint.sty.| % \begin{macrocode} \def\xintE {\romannumeral0\xinte }% @@ -31214,7 +31633,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_e_end #1.#2#3{ #2/#3[#1]}% % \end{macrocode} % \subsection{\csh{xintIrr}, \csh{xintPIrr}} -% \lverb|\xintPIrr (partial Irr, which ignores the decimal part) added at 1.3.| +% \changed{1.04}\lverb|fixes a buggy \xintIrr {0}.| +% \changed{1.05}\lverb|modifies the initial parsing and post-processing to use \xintrawwithzeros +% and to more quickly deal with an input denominator equal to 1.| +% \changed{1.08}\lverb|this version does not remove a /1 denominator.| +% \changed{1.3} +% \lverb|added \xintPIrr (partial Irr, which ignores the decimal part).| % \begin{macrocode} \def\xintIrr {\romannumeral0\xintirr }% \def\xintPIrr{\romannumeral0\xintpirr }% @@ -31390,7 +31814,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintTFrac}} -% \lverb|1.09i, for frac in \xintexpr. And \xintFrac is already assigned. T for +% \added{1.09i} +% \lverb|For frac in \xintexpr. And \xintFrac is already assigned. T for % truncation. However, potentially not very efficient with numbers in scientific % notations, with big exponents. Will have to think it again some day. I % hesitated how to call the macro. Same convention as in maple, but some people @@ -31415,8 +31840,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \subsection{\csh{xintTrunc}, \csh{xintiTrunc}} % \lverb|& % -% This of course has a long history. Only showing here some comments. -% +% This of course has a long history. Only showing here some comments.| +% \changed{1.2i} +% \lverb|& % 1.2i release notes: ever since its inception this macro was stupid for a % decimal input: it did not handle it separately from the general fraction % case A/B[N] with B>1, hence ended up doing divisions by powers of ten. But @@ -31428,9 +31854,10 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % is quite longer and making it f-expandable would not shorten it... I decided % for the time being to not complicate things here. % | +% \changed[2020/02/18]{1.4a} % \lverb|& % -% 1.4a (2020/02/18) adds handling of a negative first argument. +% Adds handling of a negative first argument. % % Zero input still gives single digit 0 output as I did not want to complicate % the code. But if quantization gives 0, the exponent [D] will be there. Well @@ -31492,8 +31919,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_trunc_CE #1.#2{\XINT_trunc_E #2.{#1}}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_trunc_sp_C -#1.#2#3{\XINT_trunc_sp_Ca #2.#1.}% \def\XINT_trunc_sp_Ca #1% @@ -31580,9 +32005,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintTTrunc}} -% \lverb|1.1. Modified in 1.2i, it does simply \xintiTrunc0 with no -% shortcut (the latter having been modified) -%| +% \added{1.1} % \begin{macrocode} \def\xintTTrunc {\romannumeral0\xintttrunc }% \def\xintttrunc {\xintitrunc\xint_c_}% @@ -31625,8 +32048,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\XINT_dsrr #1\xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax.}% % \end{macrocode} % \subsection{\csh{xintXTrunc}} -% \lverb@1.09j [2014/01/06] This is completely expandable but not f-expandable. -% Rewritten for 1.2i (2016/12/04): +% \added[2014/01/06]{1.09j} +% \lverb@This is completely expandable but not f-expandable.@ +% \changed[2016/12/04]{1.2i} +% \lverb|& +% Rewritten: % % - no more use of \xintiloop from xinttools.sty % (replaced by \xintreplicate... from xintkernel.sty), @@ -31635,9 +32061,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \csname...\endcsname % % - handles better the case of an input already a decimal number -% -% Need to transfer code comments into public dtx. -% @ +% | % \begin{macrocode} \def\xintXTrunc #1%#2% {% @@ -31667,8 +32091,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }%[ \def\XINT_xtrunc_zero #1#2]{0.\romannumeral\xintreplicate{#1}0}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_d #1#2#3/#4[#5]% {% @@ -31694,8 +32116,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \fi\XINT_xtrunc_BisSmall {#2}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_BisOne\XINT_xtrunc_BisSmall #1#2#3#4% {\XINT_xtrunc_sp_e {#2}{#4}{#3}}% @@ -31731,8 +32151,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% .\the\numexpr \xint_c_x^viii+#1!}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_small_a #1.#2!#3% {% @@ -31742,8 +32160,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #3\XINT_sepbyviii_Z_end 2345678\relax }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_prepare_b {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }% @@ -31775,13 +32191,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \X }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_prepare_g #1;{\XINT_xtrunc_e {#1}}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_e #1#2% {% @@ -31792,24 +32204,18 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \fi #2\xint:{#1}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_I -#1\xint:#2#3#4% {% \expandafter\XINT_xtrunc_I_a\romannumeral0#2{#4}{#2}{#1}{#3}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_I_a #1#2#3#4#5% {% \expandafter\XINT_xtrunc_I_b\the\numexpr #4-#5\xint:#4\xint:{#5}{#2}{#3}{#1}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_I_b #1% {% @@ -31819,8 +32225,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof #1% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IA_c -#1\xint:#2\xint:#3#4#5#6% {% @@ -31830,8 +32234,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \the\numexpr (#1+\xint_c_ii^v)/\xint_c_ii^vi-\xint_c_i\xint:#1\xint:{#5}{#4}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IA_d #1% {% @@ -31841,8 +32243,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof #1% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IAA_e -#1\xint:#2% {% @@ -31850,32 +32250,24 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IAB_e #1\xint:#2% {% 0.\romannumeral\XINT_rep#1\endcsname0#2% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IA_xd #1\xint:#2\xint:% {% \expandafter\XINT_xtrunc_IA_xe\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_IA_xe #1\xint:#2\xint:#3#4% {% \XINT_xtrunc_loop {#2}{#4}{#3}{#1}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_IB_c #1\xint:#2\xint:#3#4#5#6% {% @@ -31883,16 +32275,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINT_split_xfork #1.#6\xint_bye2345678\xint_bye..{#3}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_IB_d #1.#2.#3% {% \expandafter\XINT_xtrunc_IA_d\the\numexpr#3-\xintLength {#1}\xint:{#1}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_II #1\xint:% {% @@ -31909,16 +32297,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_xtrunc_II_c\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_II_c #1\xint:#2\xint:#3#4#5% {% #3.\XINT_xtrunc_loop {#2}{#4}{#5}{#1}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_loop #1% {% @@ -31937,8 +32321,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \XINT_xtrunc_loop {#3}{#2}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_transition \expandafter\XINT_xtrunc_loop_a\the\numexpr #1\xint:#2#3#4% @@ -31956,8 +32338,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral\xintreplicate{#3-\xintLength{#1}}0#1% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_sp_e #1% {% @@ -31968,16 +32348,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \fi #1\xint:% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_I -#1\xint:#2#3% {% \expandafter\XINT_xtrunc_sp_I_a\the\numexpr #1-#3\xint:#1\xint:{#3}{#2}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_I_a #1% {% @@ -31987,8 +32363,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof #1% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_IA_b -#1\xint:#2\xint:#3#4% {% @@ -31996,8 +32370,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \the\numexpr#2-\xintLength{#4}\xint:{#4}\romannumeral\XINT_rep#1\endcsname0% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_IA_c #1% {% @@ -32007,8 +32379,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof #1% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_IAA -#1\xint:#2% {% @@ -32016,16 +32386,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_IAB #1\xint:#2% {% 0.\romannumeral\XINT_rep#1\endcsname0#2% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_IB_b #1\xint:#2\xint:#3#4% {% @@ -32033,16 +32399,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINT_split_xfork #1.#4\xint_bye2345678\xint_bye..{#3}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_xtrunc_sp_IB_c #1.#2.#3% {% \expandafter\XINT_xtrunc_sp_IA_c\the\numexpr#3-\xintLength {#1}\xint:{#1}% }% % \end{macrocode} -% \lverb@& -% @ % \begin{macrocode} \def\XINT_xtrunc_sp_II #1\xint:#2#3% {% @@ -32050,6 +32412,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintAdd}} +% \changed{1.3} % \lverb|Big change at 1.3: a/b+c/d uses lcm(b,d) as denominator.| % \begin{macrocode} \def\xintAdd {\romannumeral0\xintadd }% @@ -32126,6 +32489,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }\XINT_fadd_G{ }% % \end{macrocode} % \subsection{\csh{xintSub}} +% \changed{1.3} % \lverb|Since 1.3 will use least common multiple of denominators.| % \begin{macrocode} \def\xintSub {\romannumeral0\xintsub }% @@ -32148,8 +32512,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % may be empty. % % Refactored slightly at 1.4. \XINT_Sum used in xintexpr code. -% -% % | % \begin{macrocode} \def\xintSum {\romannumeral0\xintsum }% @@ -32192,9 +32554,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_fmul_zero #1.#2{ 0/1[0]}% % \end{macrocode} % \subsection{\csh{xintSqr}} -% \lverb|1.1 modifs comme xintMul. -% -% | % \begin{macrocode} \def\xintSqr {\romannumeral0\xintsqr }% \def\xintsqr #1{\expandafter\XINT_fsqr\romannumeral0\xintraw {#1}}% @@ -32271,9 +32630,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\xintfac #1{\expandafter\XINT_fac_fork\the\numexpr\xintNum{#1}.[0]}% % \end{macrocode} % \subsection{\csh{xintBinomial}} -% \lverb|1.2f. Binomial coefficients. \xintiBinomial deprecated at 1.2o and -% removed at 1.3; -% \xintBinomial needed by xintexpr.sty.| +% \added{1.2f} % \begin{macrocode} \def\xintBinomial {\romannumeral0\xintbinomial}% \def\xintbinomial #1#2% @@ -32283,7 +32640,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintPFactorial}} -% \lverb|1.2f. Partial factorial. For needs of xintexpr.sty.| +% \added{1.2f} +% \lverb|Partial factorial. For needs of xintexpr.sty.| % \begin{macrocode} \def\xintipfactorial #1#2% {% @@ -32346,18 +32704,16 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_fdiv_C #1#2{\XINT_outfrac {#2}{#1}}% % \end{macrocode} % \subsection{\csh{xintDivFloor}} -% \lverb|1.1. Changed at 1.2p to not append /1[0] ending but rather output a +% \added{1.1} +% \lverb|Changed at 1.2p to not append /1[0] ending but rather output a % big integer in strict format, like \xintDivTrunc and \xintDivRound. -% -% -% % | % \begin{macrocode} \def\xintDivFloor {\romannumeral0\xintdivfloor }% \def\xintdivfloor #1#2{\xintifloor{\xintDiv {#1}{#2}}}% % \end{macrocode} % \subsection{\csh{xintDivTrunc}} -% \lverb|1.1. \xintttrunc rather than \xintitrunc0 in 1.1a| +% \added{1.1} % \begin{macrocode} \def\xintDivTrunc {\romannumeral0\xintdivtrunc }% \def\xintdivtrunc #1#2{\xintttrunc {\xintDiv {#1}{#2}}}% @@ -32369,11 +32725,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\xintdivround #1#2{\xintiround 0{\xintDiv {#1}{#2}}}% % \end{macrocode} % \subsection{\csh{xintModTrunc}} -% \lverb|1.1. \xintModTrunc {q1}{q2} computes q1 - q2*t(q1/q2) with t(q1/q2) +% \added{1.1} +% \lverb|\xintModTrunc {q1}{q2} computes q1 - q2*t(q1/q2) with t(q1/q2) % equal to the truncated division of two fractions q1 and q2. % -% Its former name, prior to 1.2p, was \xintMod. -% +% Its former name, prior to 1.2p, was \xintMod.| +% \changed{1.3} +% \lverb|& % At 1.3, uses least common multiple denominator, like \xintMod (next).| % \begin{macrocode} \def\xintModTrunc {\romannumeral0\xintmodtrunc }% @@ -32422,9 +32780,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_modtrunc_pos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}% % \end{macrocode} % \subsection{\csh{xintDivMod}} -% \lverb|1.2p. \xintDivMod{q1}{q2} outputs {floor(q1/q2)}{q1 - q2*floor(q1/q2)}. -% Attention that it relies on \xintiiE{x}{e} returning x if e < 0. -% +% \added{1.2p} +% \lverb|\xintDivMod{q1}{q2} outputs {floor(q1/q2)}{q1 - q2*floor(q1/q2)}. +% Attention that it relies on \xintiiE{x}{e} returning x if e < 0.| +% \changed{1.3} +% \lverb|& % Modified (like \xintAdd and \xintSub) at 1.3 to use a l.c.m for final % denominator of the "mod" part.| % \begin{macrocode} @@ -32474,11 +32834,14 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_divmod_bpos_finish #1#2#3{{#1}{#2#3}}% % \end{macrocode} % \subsection{\csh{xintMod}} -% \lverb|1.2p. \xintMod{q1}{q2} computes q1 - q2*floor(q1/q2). Attention that +% \added{1.2p} +% \lverb|\xintMod{q1}{q2} computes q1 - q2*floor(q1/q2). Attention that % it relies on \xintiiE{x}{e} returning x if e < 0. % % Prior to 1.2p, that macro had the meaning now attributed to \xintModTrunc. -% +% | +% \changed{1.3} +% \lverb|& % Modified (like \xintAdd and \xintSub) at 1.3 to use a l.c.m for final % denominator.| % \begin{macrocode} @@ -32541,7 +32904,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_mod_bpos_a #1.#2#3#4{\xintiirem {#3}{#4}/#2[#1]}% % \end{macrocode} % \subsection{\csh{xintIsOne}} -% \lverb|New with 1.09a. Could be more efficient. For fractions with big +% \added{1.09a} +% \lverb|Could be more efficient. For fractions with big % powers of tens, it is better to use \xintCmp{f}{1}. Restyled in 1.09i.| % \begin{macrocode} \def\xintIsOne {\romannumeral0\xintisone }% @@ -32595,8 +32959,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_fgeq_Fd #1\Z #2#3% {% @@ -32802,8 +33164,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_fcmp_Fd #1\Z #2#3% {% @@ -33218,8 +33578,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % | % % \subsection{\csh{xintDigits}, \csh{xintSetDigits}} +% \changed{1.3} % \lverb|& -% % 1.3f allows \xintDigits= in place of \xintDigits:= syntax. % It defines \xintDigits*[:]= which reloads xinttrig.sty. Perhaps this should % be default, well. @@ -33249,7 +33609,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % -% \subsection{\csh{xintFloat}} +% \subsection{\csh{xintFloat}, \csh{xintFloatZero}} % \lverb|& % 1.2f and 1.2g brought some refactoring which resulted in faster treatment of % decimal inputs. 1.2i dropped use of some old routines dating back to pre 1.2 @@ -33299,6 +33659,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % the macro used internally by the float macros for parsing their inputs, we % simply make now \xintFloat a wrapper of \XINTinFloat.| % \begin{macrocode} +\def\xintFloatZero{0.0e0}% 1.4k breaking change. Replaces hard-coded 0.e0 \def\xintFloat {\romannumeral0\xintfloat }% \def\xintfloat #1{\XINT_float_chkopt #1\xint:}% \def\XINT_float_chkopt #1% @@ -33329,7 +33690,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% 0-\XINT_float_pos \krof #1% }%[ -\def\XINT_float_zero #1]#2.{ 0.e0}% +\def\XINT_float_zero #1]#2.{\expanded{ \xintFloatZero}}% \def\XINT_float_neg-{\expandafter-\romannumeral0\XINT_float_pos}% \def\XINT_float_pos #1#2[#3]#4.% {% @@ -33337,7 +33698,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_float_pos_done #1.#2;{ #2e#1}% % \end{macrocode} -% \subsection{\csh{XINTinFloat}, \csh{XINTinFloatS}, \csh{XINTiLogTen}} +% \subsection{\csh{XINTinFloat}, \csh{XINTinFloatS}} % \lverb|& % This routine is like \xintFloat but produces an output of the shape A[N] % which is then parsed faster as input to other float macros. @@ -33368,8 +33729,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % Since 1.2k, \XINTinFloat always correctly rounds its argument, even if it % is a fraction with very big numerator and denominator. See the discussion of % \xintFloat. -% -% 1.3e adds \XINTFloatiLogTen. % | % \begin{macrocode} \def\XINTinFloat {\romannumeral0\XINTinfloat }% @@ -33383,8 +33742,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\if #1!\xint_dothis\XINT_infloat_clean_a\fi\xint_orthat{ }#1}% % \end{macrocode} % \lverb|Ici on ajoute les zeros pour faire exactement avec P chiffres. -% Car le #1 = P - L avec L la longueur de #2, (ou de abs(#2), ici le #2 peut -% avoir un signe) qui est < P| +% Car le #1 = P - L avec L la longueur de #2, (ou plutôt de abs(#2), +% car ici le #2 peut avoir un signe) et L < P| % \begin{macrocode} \def\XINT_infloat_clean_a !#1.#2[#3]% {% @@ -33403,23 +33762,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}% \def\XINT_infloatS_clean_a !#1.{ }% % \end{macrocode} -% \lverb|1.3e ajoute \XINTFloatiLogTen. Le comportement pour un input nul est non -% encore finalisé. Il changera lorsque NaN, +Inf, -Inf existeront. -% | -% \begin{macrocode} -\def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}% -\def\XINTfloatilogten [#1]#2% - {\expandafter\XINT_floatilogten\romannumeral0\XINT_infloat[#1]{#2}#1.}% -\def\XINTFloatiLogTendigits{\the\numexpr\XINTfloatilogten[\XINTdigits]}% -\def\XINT_floatilogten #1{% - \if #10\xint_dothis\XINT_floatilogten_z\fi - \if #1!\xint_dothis\XINT_floatilogten_a\fi - \xint_orthat\XINT_floatilogten_b #1% -}% -\def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% -\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% -% \end{macrocode} % \lverb|début de la routine proprement dite, % l'argument optionnel est obligatoire.| % \begin{macrocode} @@ -33731,7 +34073,99 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}% % \end{macrocode} -% \subsection{\csh{xintPFloat}, \csh{xintPFloatE}} +% \subsection{\csh{XINTFloatiLogTen}} +% \added{1.3e} +% \lverb|Le comportement pour un input nul est non +% encore finalisé. Il changera lorsque NaN, +Inf, -Inf existeront. +% | +% \begin{macrocode} +\def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}% +\def\XINTfloatilogten [#1]#2% + {\expandafter\XINT_floatilogten\romannumeral0\XINT_infloat[#1]{#2}#1.}% +\def\XINTFloatiLogTendigits{\the\numexpr\XINTfloatilogten[\XINTdigits]}% +\def\XINT_floatilogten #1{% + \if #10\xint_dothis\XINT_floatilogten_z\fi + \if #1!\xint_dothis\XINT_floatilogten_a\fi + \xint_orthat\XINT_floatilogten_b #1% +}% +\def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% +\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% +\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% +% \end{macrocode} +% \subsection{\csh{xintFloatSciExp}} +% \added[2022/05/16]{1.4k} +% \lverb|Hesitation about whether keeping the general \romannumeral0 +% trigger which is documented as general rule.| +% \begin{macrocode} +\def\xintFloatSciExp {\the\numexpr\xintfloatsciexp }% +\def\xintpfloatsciexp #1{\XINT_floatsciexp_chkopt #1\xint:}% +\def\XINT_floatsciexp_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatsciexp_opt + \else\expandafter\XINT_floatsciexp_noopt + \fi #1% +}% +\def\XINT_floatsciexp_noopt #1\xint:% +{% + \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[\XINTdigits]{#1}% + \XINTdigits.% +}% +\def\XINT_floatsciexp_opt [\xint:#1]#2% +{% + \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[#1]{#2}#1.% +}% +\def\XINT_floatsciexp #1{% + \if #10\xint_dothis\XINT_floatsciexp_z\fi + \if #1!\xint_dothis\XINT_floatsciexp_a\fi + \xint_orthat\XINT_floatsciexp_b #1% +}% +\def\XINT_floatsciexp_z 0[0]#1.{0\relax}% +\def\XINT_floatsciexp_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% +\def\XINT_floatsciexp_b #1[#2]#3.{#2+#3-1\relax}% +% \end{macrocode} +% \subsection{\csh{xintFloatSignificand}} +% \added[2022/05/16]{1.4k} +% \lverb|Hesitation about whether returning abcd... or a.bcd... +% with a separator +% and slight hesitation about handling of zero.| +% \begin{macrocode} +\def\xintFloatSignificand {\romannumeral0\xintfloatsignificand}% +\def\xintfloatsignificand #1{\XINT_floatsgf_chkopt #1\xint:}% +\def\XINT_floatsgf_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatsgf_opt + \else\expandafter\XINT_floatsgf_noopt + \fi #1% +}% +\def\XINT_floatsgf_noopt #1\xint:% +{% + \expandafter\XINT_floatsgf_post + \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% +}% +\def\XINT_floatsgf_opt [\xint:#1]% +{% + \expandafter\XINT_floatsgf_opt_a\the\numexpr #1.% +}% +\def\XINT_floatsgf_opt_a #1.#2% +{% + \expandafter\XINT_floatsgf_post + \romannumeral0\XINTinfloat[#1]{#2}#1.% +}% +\def\XINT_floatsgf_post #1% +{% + \xint_UDzerominusfork + #1-\XINT_floatsgf_zero + 0#1\XINT_floatsgf_neg + 0-\XINT_floatsgf_pos + \krof #1% +}%[ +\def\XINT_floatsgf_zero #1]#2.{\XINT_dsx_addzeros{#2};}% +\def\XINT_floatsgf_neg-{\XINT_floatsgf_pos}% +\def\XINT_floatsgf_pos #1[#2]#3.{ #1}% +% \end{macrocode} +% \subsection{\csh{xintPFloat}} +% \added{1.1} +% \changed{1.4e} % \lverb|& % % xint has not yet incorporated a general formatter as it was @@ -33756,8 +34190,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % % 1.4b added \xintPFloatE to customize whether to use % e or E. -% -% +% | +% \lverb|& % 1.4e, with some hesitation, decided to make a breaking change and to modify % the behaviour. % @@ -33774,19 +34208,69 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % there is an added ".0" too %) % -% Further, \xintPFloatE can now grab the scientific exponent K which is -% presented to it as explicit tokens (digit tokens, at least one, and an -% optional minus sign) delimited by a dot. It is thus now possible to -% customize at will for example adding a + sign in case of positive scientific -% exponent. The macro must be f-expandable. +% Further, \xintPFloatE can now also be redefined as a macro with a parameter +% delimited by a full stop, with the full stop also in its ouput as +% terminator. It would then grab the scientific exponent K as explicit digit +% possibly prefixed by a minus sign. The macro must be f-expandable. % +% The macro \xintPFloat_wopt is only there for a micro gain as the package +% does +% +% \let\xintfloatexprPrintOne\xintPFloat_wopt +% +% as it knows it will +% be used always with a [P] argument in the xintexpr.sty context. +% | +% \changed[2022/05/18]{1.4k} +% \lverb|& +% Addition of customization via \xintPFloatZero, \xintPFloatLengthOneSuffix, +% \xintPFloatNoSciEmax, \xintPFloatNoSciEmin which replace formerly +% hard-coded behaviour. +% +% Breaking change to not add ".0" suffix to integers (when scientific +% notation dropped) or to one-digit mantissas. +% +% In my own practice I started being annoyed by the automatic trimming of +% zeros added at 1.4e. +% +% This change had been influenced by using Python in interactive mode +% which since 3.1 prints floats (in decimal conversion) choosing the +% shortest string. In particular it trims trailing zeros, and it drops +% the scientific notation in favor of decimal notation for something +% like -4<= K <= 15, with K the scientific exponent. +% +% At 1.4e I was still influenced by my experience with Maple and +% did for -4 <= K <= 5. Not very well thought anyhow (one may wish +% to use decimal notation when sending things to PostScript, so perhaps +% I should have kept with -5). +% +% But, the main problem is with trimming trailing zeros: although in +% interactive sessions, this has its logic, as soon as one does tables +% with numbers, dropping a trailing zero upsets alignments or creates +% visual holes compared to other lines and this is in the end very +% annoying. +% +% After much hesitation, I decided to slightly modifify only the former +% behaviour: trimming only if that removes at least 4 zeros. I had also +% experimented with another condition: trimmed mantissas should be at +% most 6 digits (for example) wide, else use no trimming. +% +% Threshold customizable via \xintPFloatMinTrimmed. % | % \begin{macrocode} +\def\xintPFloatE{e}% +\def\xintPFloatNoSciEmax{\xint_c_v}% 1e6 uses sci.not. +\def\xintPFloatNoSciEmin{-\xint_c_iv}% 1e-5 uses sci.not. +\def\xintPFloatIntSuffix{}% +\def\xintPFloatLengthOneSuffix{}% +\def\xintPFloatZero{0}% +\def\xintPFloatMinTrimmed{\xint_c_iv}% \def\xintPFloat {\romannumeral0\xintpfloat }% \def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint:}% -\def\xintPFloat_wopt +\def\xintPFloat_wopt[#1]#2% {% - \romannumeral0\expandafter\XINT_pfloat\romannumeral0\XINTinfloatS + \romannumeral0\expandafter\XINT_pfloat + \romannumeral0\XINTinfloatS[#1]{#2}#1.% }% \def\XINT_pfloat_chkopt #1% {% @@ -33797,10 +34281,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_pfloat_noopt #1\xint:% {% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% + \XINTdigits.% }% -\def\XINT_pfloat_opt [\xint:#1]% +\def\XINT_pfloat_opt [\xint:#1]#2% {% - \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]{#2}% + #1.% }% \def\XINT_pfloat#1]% {% @@ -33814,22 +34300,92 @@ on input line \noexpand\the\inputlineno.&&J}}#2% 0-\XINT_pfloat_pos \krof #1% }% -\def\XINT_pfloat_zero#1]{ 0.0}% +\def\XINT_pfloat_zero#1]#2.{\expanded{ \xintPFloatZero}}% \def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos}% -\def\XINT_pfloat_pos#1/1[#2]% +\def\XINT_pfloat_pos#1/1[#2]#3.% +{% + \expandafter\XINT_pfloat_aa\the\numexpr\xintLength{#1}.% + #3.#2.#1.% +}% +% \end{macrocode} +%\lverb|Needed for \xintFracToSci, which uses old pre 1.4k interface.| +% \begin{macrocode} +\def\XINT_pfloat_keeptrimmed_fork#1% +{% + \xint_UDzerominusfork + #1-\XINT_pfloat_keeptrimmed_zero + 0#1\XINT_pfloat_keeptrimmed_neg + 0-\XINT_pfloat_keeptrimmed_pos + \krof #1% +}% +\def\XINT_pfloat_keeptrimmed_zero#1]{\expanded{ \xintPFloatZero}}% +\def\XINT_pfloat_keeptrimmed_neg-{\expandafter-\romannumeral0\XINT_pfloat_keeptrimmed_pos}% +\def\XINT_pfloat_keeptrimmed_pos#1/1[#2]% +{% + \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.#2.#1.% +}% +% \end{macrocode} +%\lverb|& +%( #1 est la longueur de la mantisse trimmée +%: #2 est Digits ou P +%: Si #2-#1 < MinTrimmed, on remet les trailing zeros +%) +%| +% \begin{macrocode} +\def\XINT_pfloat_aa #1.#2.% +{% + \unless\ifnum\xintPFloatMinTrimmed>\numexpr#2-#1\relax + \xint_dothis\XINT_pfloat_a\fi + \ifnum#2>#1 \xint_dothis{\XINT_pfloat_i #2.}\fi + \xint_orthat\XINT_pfloat_a #1.% +}% +% \end{macrocode} +%\lverb|& +%( #2 est la longueur de la mantisse trimmée +%: #1 est P mais peut être encore sous la forme \XINTdigits +%: #3 est l'exposant non normalisé +%: #4 est la mantisse +%) +%| +% \begin{macrocode} +\def\XINT_pfloat_i #1.#2.#3.#4.% {% - \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.% - #2.#1.% + \expandafter\XINT_pfloat_j + \the\numexpr#3+#2-#1\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss{#1-#2}#4;.#1.% }% +% \end{macrocode} +%\lverb|& +%( #1 est le nouvel exposant non normalisé +%: #2 est la nouvelle mantisse à P chiffres +%: #3 est P (peut être sous forme \XINTdigits) +%) +%| +% \begin{macrocode} +\def\XINT_pfloat_j #1.#2.#3.{\XINT_pfloat_a#3.#1.#2.}% \def\XINT_pfloat_a #1.#2#3.% {% \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% #2#1.% }% +% \end{macrocode} +% \lverb|& +%( #1 est l'exposant scientifique K +%: #2 est le signe ou premier chiffre de l'exposant N pour mantisse trimmée +%: Il est suivi par la longueur de la mantisse trimmée +%) +% On va vers \XINT_float_P lorsque l'on n'utilise pas la notation +% scientifique, mais qu'on a besoin de chiffres non nuls fractionnaires, +% et vers \XINT_float_Ps si on n'en a pas besoin. +% +% On va vers \XINT_pfloat_N lorsque l'on n'utilise pas la notation +% scientifique et que l'exposant scientifique était strictement négatif. +%| +% \begin{macrocode} \def\XINT_pfloat_b #1.#2% {% - \ifnum #1>\xint_c_v \xint_dothis\XINT_pfloat_sci\fi - \ifnum #1<-\xint_c_iv \xint_dothis\XINT_pfloat_sci\fi + \ifnum \xintPFloatNoSciEmax<#1 \xint_dothis\XINT_pfloat_sci\fi + \ifnum \xintPFloatNoSciEmin>#1 \xint_dothis\XINT_pfloat_sci\fi \ifnum #1<\xint_c_ \xint_dothis\XINT_pfloat_N\fi \if-#2\xint_dothis\XINT_pfloat_P\fi \xint_orthat\XINT_pfloat_Ps @@ -33837,10 +34393,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \lverb|& -% #1 is the scientific exponent, #2 is the length of trimmed mantissa. +% #1 is the scientific exponent, #2 is the length of the trimmed mantissa. +% (may be the \XINTdigits token) % % \xintPFloatE can be replaced by any f-expandable macro with a dot-delimited -% argument. +% argument which produces a dot-delimited output. % | % \begin{macrocode} \def\XINT_pfloat_sci #1.#2.% @@ -33853,56 +34410,103 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \lverb|& % #1#2=\fi\XINT_pfloat_sci_a % -% 1-digit mantissa, hesitation between d.0eK or deK| +% 1-digit mantissa, hesitation between d.0eK or deK +% Finally at 1.4k, \xintPFloatLengthOneSuffix for customization. +% | +% \begin{macrocode} +\def\XINT_pfloat_sci_i #1#2#3.#4.{\expanded{#1 #4\xintPFloatLengthOneSuffix}#3}% +% \end{macrocode} +% \lverb|& +% #1=sci.exp. K, #2=mant. wd L, #3=mantissa +% +% For _N, #1 is at most -1, for _P, #1 is at least 0. For _P there +% will be fractional digits, and #1+1 digits before the mark. +% | % \begin{macrocode} -\edef\XINT_pfloat_sci_i #1#2#3.#4.{#1\space#4.0#3}% -\def\xintPFloatE{e}% \def\XINT_pfloat_N#1.#2.#3.% {% - \csname XINT_pfloat_N_\romannumeral-#1\endcsname #3% + \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#3% }% -\def\XINT_pfloat_N_i { 0.}% -\def\XINT_pfloat_N_ii { 0.0}% -\def\XINT_pfloat_N_iii{ 0.00}% -\def\XINT_pfloat_N_iv { 0.000}% +\def\XINT_pfloat_N_e 0{ 0.}% +% \end{macrocode} +% \lverb|& +% Abusive usage of internal \XINT_split_fromleft_a. +% It means using x = -1 - #1 in \xintDecSplit from xint.sty. +% We benefit also with the way \xintDecSplit is built upon +% \XINT_split_fromleft with a final clean-up which here +% we can shortcut (non \xint_bye. not \xint_bye..). +% | +% \begin{macrocode} \def\XINT_pfloat_P #1.#2.#3.% {% - \csname XINT_pfloat_P_\romannumeral#1\endcsname #3% + \expandafter\XINT_split_fromleft_a + \the\numexpr\xint_c_vii-#1.#3\xint_bye2345678\xint_bye.% }% -\def\XINT_pfloat_P_ #1{ #1.}% -\def\XINT_pfloat_P_i #1#2{ #1#2.}% -\def\XINT_pfloat_P_ii #1#2#3{ #1#2#3.}% -\def\XINT_pfloat_P_iii#1#2#3#4{ #1#2#3#4.}% -\def\XINT_pfloat_P_iv #1#2#3#4#5{ #1#2#3#4#5.}% -\def\XINT_pfloat_P_v #1#2#3#4#5#6{ #1#2#3#4#5#6.}% +% \end{macrocode} +% \lverb|& +% Here we have an integer so we only need to postfix mantissa #3 +% with #1+1-#2 zeros (#1=sci exp., #2=mantissa width). Less cumbersome +% to do that with \expanded. +% | +% \begin{macrocode} \def\XINT_pfloat_Ps #1.#2.#3.% {% - \csname XINT_pfloat_Ps_\romannumeral#1\endcsname #300000.% + \expanded{ #3% + \romannumeral\xintreplicate{#1+\xint_c_i-#2}{0}\xintPFloatIntSuffix}% +}% +% \end{macrocode} +% \subsection{\csh{xintFloatToDecimal}} +% \added{1.4k} +% \begin{macrocode} +\def\xintFloatToDecimal {\romannumeral0\xintfloattodecimal }% +\def\xintfloattodecimal #1{\XINT_floattodec_chkopt #1\xint:}% +\def\XINT_floattodec_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floattodec_opt + \else\expandafter\XINT_floattodec_noopt + \fi #1% +}% +\def\XINT_floattodec_noopt #1\xint:% +{% + \expandafter\XINT_floattodec\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% +}% +\def\XINT_floattodec_opt [\xint:#1]% +{% + \expandafter\XINT_floattodec\romannumeral0\XINTinfloatS[#1]% +}% +% \end{macrocode} +% \lverb|Tentation to try to use direct access to lower entry points +% from \xintREZ, but it dates back from very early days and uses old \Z +% delimiters (same remarks for the code jumping from \xintFracToSci +% to \xintrez)| +% \begin{macrocode} +\def\XINT_floattodec#1]% +{% + \expandafter\XINT_dectostr\romannumeral0\xintrez{#1]}% }% -\def\XINT_pfloat_Ps_ #1#2.{ #1.0}% -\def\XINT_pfloat_Ps_i #1#2#3.{ #1#2.0}% -\def\XINT_pfloat_Ps_ii #1#2#3#4.{ #1#2#3.0}% -\def\XINT_pfloat_Ps_iii#1#2#3#4#5.{ #1#2#3#4.0}% -\def\XINT_pfloat_Ps_iv #1#2#3#4#5#6.{ #1#2#3#4#5.0}% -\def\XINT_pfloat_Ps_v #1#2#3#4#5#6#7.{ #1#2#3#4#5#6.0}% % \end{macrocode} +% % \subsection{\csh{XINTinFloatFrac}} -% \lverb|1.09i, for frac function in \xintfloatexpr. This version computes +% \added{1.09i} +% +% \lverb|For frac function in \xintfloatexpr. This version computes % exactly from the input the fractional part and then only converts it % into a float with the asked-for number of digits. I will have to think -% it again some day, certainly. +% it again some day, certainly.| % +% \changed{1.1} +% \lverb|& % 1.1 removes optional argument for which there was anyhow no interface, for -% technical reasons having to do with \xintNewExpr. +% technical reasons having to do with \xintNewExpr.| % +% \changed{1.1a} +% \lverb|& % 1.1a renames the macro as \XINTinFloatFracdigits (from \XINTinFloatFrac) to % be synchronous with the \XINTinFloatSqrt and \XINTinFloat habits related to -% \xintNewExpr context and issues with macro names. -% -% Note to myself: I still have to rethink the whole thing about what is the best -% to do, the initial way of going through \xinttfrac was just a first -% implementation. +% \xintNewExpr context and issues with macro names.| % +% \changed{1.4e} +% \lverb|& % 1.4e renames it back to \XINTinFloatFrac because of all such similarly named % macros also using \XINTdigits forcedly. % | @@ -33960,8 +34564,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_b #1% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_FL_add_zero #1.#2{#2}%[[ \def\XINT_FL_add_b #1]#2.#3% @@ -33969,16 +34571,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_FL_add_c\romannumeral0\XINTinfloat[#2]{#3}#2.#1]% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_FL_add_c #1% {% \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_d #1% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_FL_add_d #1[#2]#3.#4[#5]% {% @@ -33988,8 +34586,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatSub}, \csh{XINTinFloatSub}} -% \lverb|First done 1.07. -% +% \added{1.07} +% \changed{1.2f} +% \lverb|& % Starting with 1.2f the arguments undergo an intial rounding to the target % precision P not P+2.| % @@ -34022,18 +34621,16 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatMul}, \csh{XINTinFloatMul}} -% \lverb|1.07. -% +% \added{1.07} +% \changed{1.2d} +% \lverb|& % Starting with 1.2f the arguments are rounded to the target precision P not -% P+2. -% +% P+2.| +% \changed{1.2g} +% \lverb|& % 1.2g handles the inputs via \XINTinFloatS which will be more efficient when % the precision is large and the input is for example a small constant like 2. -% -% 1.2k does a micro improvement to the way the macro passes over control -% to its output routine (former version used a higher level \xintE causing -% some extra un-needed processing with two calls to \XINT_infrac where -% one was amply enough).| +% | % \begin{macrocode} \def\xintFloatMul {\romannumeral0\xintfloatmul}% \def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint:}% @@ -34072,7 +34669,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_FL_mul_b #1[#2]#3[#4]{\xintiiMul{#3}{#1}/1[#4+#2]}% % \end{macrocode} % \subsection{\csh{xintFloatSqr}, \csh{XINTinFloatSqr}} -% \lverb|Added only at 1.4e, strangely \xintFloatSqr had never been defined so far. +% \added{1.4e} +% \lverb|Strangely \xintFloatSqr had never been defined so far. % % An \XINTinFloatSqr{#1} was defined in xintexpr.sty directly as % \XINTinFloatMul[\XINTdigits]{#1}{#1}, to support the sqr() function. The @@ -34111,6 +34709,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINTinFloatSqr_wopt[#1]#2{\XINTinFloatS[#1]{\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[#1]{#2}}}% % \end{macrocode} % \subsection{\csh{XINTinFloatInv}} +% \added{1.3e} % \lverb|Added belatedly at 1.3e, to support inv() function. We use Short % output, for rare inv(\xintexpr 1/3\relax) case. I need to think the whole % thing out at some later date.| @@ -34119,17 +34718,20 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINTinFloatInv_wopt[#1]#2{\XINTinFloatS[#1]{\xintInv{#2}}}% % \end{macrocode} % \subsection{\csh{xintFloatDiv}, \csh{XINTinFloatDiv}} -% \lverb|1.07. -% -% Starting with 1.2f the arguments are rounded to the target precision P not -% P+2. -% +% \added{1.07} +% \changed{1.2f} +% \lverb|Starting with 1.2f the arguments are rounded to the target precision P not +% P+2.| +% \changed{1.2g} +% \lverb|& % 1.2g handles the inputs via \XINTinFloatS which will be more efficient when % the precision is large and the input is for example a small constant like 2. % % The actual rounding of the quotient is handled via \xintfloat (or % \XINTinfloatS). -% +% | +% \changed{1.2k} +% \lverb|& % 1.2k does the same kind of improvement in \XINT_FL_div_b as for % multiplication: earlier code was unnecessarily high level. % | @@ -34187,13 +34789,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloatS[#3]{#4}/#1e#2% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_FL_div_b #1[#2]{#1e#2}% % \end{macrocode} % \subsection{\csh{xintFloatPow}, \csh{XINTinFloatPow}} -% \lverb|1.07: initial version. 1.09j has re-organized the core loop. +% \added{1.07} +% +% \lverb|1.09j has re-organized the core loop. % % 2015/12/07. I have hesitated to map ^ in expressions to \xintFloatPow rather % than \xintFloatPower. But for 1.234567890123456 to the power 2145678912 with @@ -34201,11 +34803,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % gain. % % This routine requires the exponent x to be compatible with \numexpr parsing. +% | % +% \changed{1.2f} +% \lverb|& % 1.2f has rewritten the code for better efficiency. Also, now the argument A % for A^x is first rounded to P digits before switching to the increased % working precision (which depends upon x). -% % | % \begin{macrocode} \def\xintFloatPow {\romannumeral0\xintfloatpow}% @@ -34243,8 +34847,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_flpow_BisZero .#1.#2#3{#3{1[0]}}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_checkB_b #1#2.#3.% {% @@ -34269,8 +34871,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_aa #1[#2]#3% {% @@ -34278,13 +34878,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral\XINT_rep #3\endcsname0.#1.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_ab #1.#2.#3.{\XINT_flpow_a #3#2[#1]}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_a #1% {% @@ -34302,16 +34898,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_b #1#2[#3]#4#5% {% \XINT_flpow_loopI #5.#3.#2.#4.{#1\ifodd #5 \xint_c_i\fi\fi}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_truncate #1.#2.#3.% {% @@ -34320,8 +34912,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #3.#2\xint_bye2345678\xint_bye..#1.#3.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_truncate_a #1.#2.#3.{#3+\xintLength{#2}.#1.}% \def\XINT_flpow_loopI #1.% @@ -34335,16 +34925,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #1.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_ItoIII\ifodd #1\fi #2.#3.#4.#5.#6% {% \expandafter\XINT_flpow_III\the\numexpr #6+\xint_c_.#3.#4.#5.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_loopI_even #1.#2.#3.%#4.% {% @@ -34393,8 +34979,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #1.#2.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_IItoIII\ifodd #1\fi #2.#3.#4.#5.#6.#7.#8% {% @@ -34435,17 +35019,18 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \krof #1% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpow_IIIend #1#2#3% {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}% % \end{macrocode} % \subsection{\csh{xintFloatPower}, \csh{XINTinFloatPower}} -% \lverb|1.07. The core loop has been re-organized in 1.09j for some slight +% \added{1.07} +% \lverb|The core loop has been re-organized in 1.09j for some slight % efficiency gain. The exponent B is given to \xintNum. The ^ in expressions % is mapped to this routine. -% +% | +% \changed{1.2f} +% \lverb|& % Same modifications as in \xintFloatPow for 1.2f. % % 1.2f \XINTinFloatPowerH (now moved to $xintlognameimp, and renamed). It @@ -34454,7 +35039,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % rounded to Digits before, not after the square root extraction, 1.2k kept 3 % guard digits for this last step. And the initial step was % changed to a rounding rather than truncating. -% +% | +% \changed{1.4e} +% \lverb|& % Until 1.4e this \XINTinFloatPowerH was the macro for a^b in expressions, % but of course it behaved strangely for b not an integer or an half-integer! % At 1.4e, the non-integer, non-half-integer exponents will be handled via @@ -34505,16 +35092,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpower_checkB_c #1.#2.% {% \expandafter\XINT_flpower_checkB_d\the\numexpr#1+#2.#1.#2.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpower_checkB_d #1.#2.#3.#4.#5#6% {% @@ -34522,8 +35105,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flpower_aa #1[#2]#3% {% @@ -34550,8 +35131,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_dothis{\expandafter\XINT_flpower_loopI_odd}\fi \xint_orthat{\expandafter\XINT_flpower_loopI_even}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \romannumeral0\XINT_half #1\xint_bye\xint_Bye345678\xint_bye @@ -34583,8 +35162,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_dothis{\expandafter\XINT_flpower_loopII_odd}\fi \xint_orthat{\expandafter\XINT_flpower_loopII_even}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \romannumeral0\XINT_half#1\xint_bye\xint_Bye345678\xint_bye *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax.% @@ -34617,16 +35194,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatFac}, \csh{XINTFloatFac}} -% \lverb|&1.2. -% -% Done at 1.2. -% -% At 1.3e \XINTinFloatFac uses \XINTinFloatS for output. -% -% 1.4e adds some overhead for individual evaluations in float context as it -% obeys the guard digits for the default target precision. It is a waste for -% individual evaluation of one factorial... -% | +% \added{1.2} % \begin{macrocode} \def\xintFloatFac {\romannumeral0\xintfloatfac}% \def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}% @@ -34710,7 +35278,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % than the earlier 5=13-8. Whatever happens, the value computed in % \XINT_FL_fac_increaseP is at least 8. There will always be an extra block. % -% Note: with Digits:=32; Maple gives for 200!:$bgroup$obeylines$obeyspaces$ttbfamily +% Note: with Digits:=32; Maple gives for 200!:$bgroup$obeylines$obeyspaces$ttfamily % > factorial(200.); % $indent 375 % $indent 0.78865786736479050355236321393218 10 @@ -34911,12 +35479,14 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatPFactorial}, \csh{XINTinFloatPFactorial}} -% \lverb|2015/11/29 for 1.2f. Partial factorial pfactorial(a,b)=(a+1)...b, -% only for non-negative integers with a<=b<10^8. -% -% 1.2h (2016/11/20) now avoids raising \xintError:OutOfRangePFac if the -% condition 0<=a<=b<10^8 is violated. Same as for \xintiiPFactorial. -% +% \added[2015/11/29]{1.2f} +% \lverb|Partial factorial pfactorial(a,b)=(a+1)...b, +% only for non-negative integers with a<=b<10^8.| +% \changed[2016/11/20]{1.2h} +% \lverb|Now avoids raising \xintError:OutOfRangePFac if the +% condition 0<=a<=b<10^8 is violated. Same as for \xintiiPFactorial.| +% \changed{1.4e} +% \lverb|& % 1.4e extends the precision in floating point context adding some overhead % but well.| % \begin{macrocode} @@ -35115,22 +35685,22 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatBinomial}, \csh{XINTinFloatBinomial}} -% \lverb|1.2f. We compute binomial(x,y) as pfac(x-y,x)/y!, where the numerator +% \added[2015/12/01]{1.2f} +% \lverb|We compute binomial(x,y) as pfac(x-y,x)/y!, where the numerator % and denominator are computed with a relative error at most 4.10^{-P-2}, then % rounded (once I have a float truncation, I will use truncation rather) to % P+3 digits, and finally the quotient is correctly rounded to P digits. This % will guarantee that the exact value X differs from the computed one Y by at -% most 0.6 ulp(Y). (2015/12/01). -% -% 2016/11/19 for 1.2h. As for \xintiiBinomial, hard to understand why last +% most 0.6 ulp(Y).| +% \changed[2016/11/19]{1.2h} +% \lverb|As for \xintiiBinomial, hard to understand why last % year I coded this to raise an error if y<0 or y>x ! The question of the % Gamma function is for another occasion, here x and y must be (small) % integers. % % 1.4e: same remarks as for factorial and partial factorial about added % overhead due to extra guard digits. -% -%| +% | % \begin{macrocode} \def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% \def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint:}% @@ -35199,7 +35769,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatSqrt}, \csh{XINTinFloatSqrt}} -% \lverb|First done for 1.08. +% \added{1.08} +% \changed{1.2f} +% \lverb|& % % The float version was developed at the same time as the integer one and even % a bit earlier. As a result the integer variant had some sub-optimal parts. @@ -35219,22 +35791,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % macros. % % Final note: with 1.2f the input is always first rounded to P significant -% places. -% -% 1.4e (2021/04/15) great hesitation about what to do regarding guard digits. -% This will spoil the guaranteed "correct-rounding" property for individual -% calculations... but is interesting for precision as soon as the square root -% is embedded into some larger calculation. Annoying. But there is \xintexpr -% which I can left configured to use strictly \xintDigits in contrast to -% \xintfloatexpr. Ah ok and there will always be sqrt(x,\xinttheDigits) syntax -% if one wants. And finally I keep sqrt() acting the same in expr and floatexpr. -% -% Attention that at 1.4e \XINTinFloatSqrt is defined to be used ONLY with -% optional argument. -% -% -% -% | +% places.| % \begin{macrocode} \def\xintFloatSqrt {\romannumeral0\xintfloatsqrt}% \def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}% @@ -35275,8 +35832,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {Square root of negative: -#1].}{}{ 0[0]}}% }% % \end{macrocode} -%\lverb|& -% | +% \begin{privatecodecomments} +% \end{privatecodecomments} % \begin{macrocode} \def\XINT_FL_sqrt_pos #1[#2]#3.% {% @@ -35285,8 +35842,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_orthat {+\xint_c_ii.#2.{}}#100.#3.% }% % \end{macrocode} -% \lverb|& -% | +% \begin{privatecodecomments} +% \end{privatecodecomments} % \begin{macrocode} \def\XINT_flsqrt #1.#2.% {% @@ -35294,8 +35851,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \the\numexpr #2/\xint_c_ii-(#1-\xint_c_i)/\xint_c_ii.#1.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_a #1.#2.#3#4.#5.% {% @@ -35304,8 +35859,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINT_sqrt_start #2.#4#3.#5.#2.#4#3.#5.#1.% }% % \end{macrocode} -% \lverb|& -% | +% % \begin{macrocode} \def\XINT_flsqrt_b #1.#2#3% {% @@ -35316,8 +35870,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\XINT_dbl#2\xint_bye2345678\xint_bye*\xint_c_ii\relax}}.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_c #1.#2.% {% @@ -35325,8 +35877,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \romannumeral0\XINT_split_fromleft#2.#1\xint_bye2345678\xint_bye..% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_d #1.#2#3.% {% @@ -35335,13 +35885,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #2#3.#1.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_finish #1#2.#3.#4.#5.#6.#7.#8{#8[#6]{#3#1[#7]}}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_f 5#1.% {\expandafter\XINT_flsqrt_g\romannumeral0\xintinum{#1}\relax.}% @@ -35350,16 +35896,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_flsqrt_h #1{\ifnum #1<\xint_c_iii\xint_dothis{\XINT_flsqrt_again}\fi \xint_orthat{\XINT_flsqrt_finish 5.}}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_again #1.#2.% {% \expandafter\XINT_flsqrt_again_a\the\numexpr #2+\xint_c_viii.% }% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_flsqrt_again_a #1.#2.#3.% {% @@ -35370,12 +35912,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatE}, \csh{XINTinFloatE}} -% \lverb|1.07: The fraction is the first argument contrarily to \xintTrunc and -% \xintRound. -% -% 1.2k had to rewrite this since there is no more a \XINT_float_a macro. -% -% Attention about \XINTinFloatE: it is for use by xintexpr.sty. +% \added{1.07} +% \lverb|The fraction is the first argument contrarily to \xintTrunc and +% \xintRound.| +% \lverb|& +% Attention to \XINTinFloatE: it is for use by xintexpr.sty. % With input 0 it produces on output an 0[N], not 0[0]. % | % \begin{macrocode} @@ -35412,8 +35953,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_floate_zero #1]#2.#3{ 0.e0}% \def\XINT_floate_neg-{\expandafter-\romannumeral0\XINT_floate_pos}% % \end{macrocode} -% \lverb|& -% | % \begin{macrocode} \def\XINT_floate_pos #1#2[#3]#4.#5% {% @@ -35427,7 +35966,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_infloate_end #1.#2{ #2[#1]}% % \end{macrocode} % \subsection{\csh{XINTinFloatMod}} -% \lverb|1.1. Pour emploi dans xintexpr. Code shortened at 1.2p.| +% \added{1.1} +% \lverb|Pour emploi dans xintexpr. Code shortened at 1.2p.| % \begin{macrocode} \def\XINTinFloatMod {\romannumeral0\XINTinfloatmod [\XINTdigits]}% \def\XINTinfloatmod [#1]#2#3% @@ -35438,7 +35978,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{XINTinFloatDivFloor}} -% \lverb|1.2p. Formerly // and /: in \xintfloatexpr used \xintDivFloor and +% \added{1.2p} +% \lverb|Formerly // and /: in \xintfloatexpr used \xintDivFloor and % \xintMod, hence did not round their operands to float precision beforehand.| % \begin{macrocode} \def\XINTinFloatDivFloor {\romannumeral0\XINTinfloatdivfloor [\XINTdigits]}% @@ -35450,7 +35991,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{XINTinFloatDivMod}} -% \lverb|1.2p. Pour emploi dans xintexpr, donc je ne prends pas la peine de +% \added{1.2p} +% \lverb|Pour emploi dans xintexpr, donc je ne prends pas la peine de % faire l'expansion du modulo, qui se produira dans le \csname. % % Hésitation sur le quotient, faut-il l'arrondir immédiatement ? @@ -35475,7 +36017,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_infloatdivmod #1#2#3{\expanded{{#1}{\XINTinFloat[#3]{#2}}}}% % \end{macrocode} % \subsection{\csh{xintifFloatInt}} -% \lverb|1.3a for ifint() function in \xintfloatexpr.| +% \added{1.3a} +% \lverb|For ifint() function in \xintfloatexpr.| % \begin{macrocode} \def\xintifFloatInt {\romannumeral0\xintiffloatint}% \def\xintiffloatint #1{\expandafter\XINT_iffloatint @@ -35488,14 +36031,16 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{xintFloatIsInt}} -% \lverb|1.3d for isint() function in \xintfloatexpr.| +% \added{1.3d} +% \lverb|For isint() function in \xintfloatexpr.| % \begin{macrocode} \def\xintFloatIsInt {\romannumeral0\xintfloatisint}% \def\xintfloatisint #1{\expandafter\XINT_iffloatint \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}10}% % \end{macrocode} % \subsection{\csh{xintFloatIntType}} -% \lverb|1.4e for fractional powers. Expands to \xint_c_mone if argument is not an +% \added{1.4e} +% \lverb|For fractional powers. Expands to \xint_c_mone if argument is not an % integer, to \xint_c_ if it is an even integer and to \xint_c_i if it is an % odd integer.| % \begin{macrocode} @@ -35515,15 +36060,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \subsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSdigits}} -% \lverb|For \xintNewExpr/\xintdeffloatfunc matters, mainly. -% -% | % \begin{macrocode} \def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% \def\XINTinFloatSdigits{\XINTinFloatS[\XINTdigits]}% % \end{macrocode} % \subsection{(WIP) \csh{XINTinRandomFloatS}, \csh{XINTinRandomFloatSdigits}} -% \lverb|1.3b. Support for random() function. +% \added{1.3b} +% \lverb|Support for random() function. % % Thus as it is a priori only for xintexpr usage, it expands inside \csname % context, but as we need to get rid of initial zeros we use \xintRandomDigits @@ -35547,8 +36090,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % ends up with trailing zeros. That did not feel right but I checked random() % in Python (which of course uses radix 2), and indeed this is what happens % there. -% -% % | % \begin{macrocode} \def\XINTinRandomFloatS{\romannumeral0\XINTinrandomfloatS}% @@ -35581,7 +36122,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_inrandomfloatS_zero#1]{ 0[0]}% % \end{macrocode} % \subsection{(WIP) \csh{XINTinRandomFloatSixteen}} -% \lverb|1.3b. Support for qrand() function.| +% \added{1.3b} +% \lverb|Support for qrand() function.| % \begin{macrocode} \def\XINTinRandomFloatSixteen% {% @@ -35668,7 +36210,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2021/07/13 v1.4j Expandable partial sums with xint package (JFB)]% + [2022/05/18 v1.4k Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -36176,7 +36718,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2021/07/13 v1.4j Expandable continued fractions with xint package (JFB)]% + [2022/05/18 v1.4k Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -37569,7 +38111,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2021/07/13 v1.4j Expandable expression parser (JFB)]% + [2022/05/18 v1.4k Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -37940,11 +38482,14 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % which now requires \xintfloatexprPrintOne[D]{x} usage, with first argument % in brackets. % -% | +% +% 1.4k has moved definition of \xintFracToSci to this macro file, so must +% delay \let\xintexprPrintOne\xintFracToSci to after it has been defined. +% | % \begin{macrocode} \protected\def\XINTexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintexprPrintOne}% -\let\xintexprPrintOne\xintFracToSci +% \let\xintexprPrintOne\xintFracToSci \protected\def\XINTiexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintiexprPrintOne}% \let\xintiexprPrintOne\xintDecToString @@ -38057,13 +38602,39 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % (and attention that \xintexpr\relax is now legal, and an empty ople can be % produced in output also from \xintexpr [17][1]\relax for example) % | +% \changed[2022/05/16]{1.4k} +% \lverb|The \xintieval and \xintfloateval optional bracketed argument can now +% be located outside the braces... took me years to finally make the step toward LaTeX +% users expectations for a decent interface.| % \begin{macrocode} +\let\xint_relax\relax \def\xinteval #1% {\expanded\expandafter\XINTexprprint\expandafter.\romannumeral0\xintbareeval#1\relax}% -\def\xintieval #1% - {\expanded\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr#1\relax}% -\def\xintfloateval #1% - {\expanded\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr#1\relax}% +\def\xintieval + {\expanded\expandafter\xint_ieval_chkopt\string}% +\def\xint_ieval_chkopt #1% +{% + \ifx [#1\expandafter\xint_ieval_opt + \else\expandafter\xint_ieval_noopt + \fi #1% +}% +\def\xint_ieval_opt [#1]#2% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr[#1]#2\relax}% +\def\xint_ieval_noopt #1{\expandafter\xint_ieval\expandafter{\iffalse}\fi}% +\def\xint_ieval#1% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr#1\relax}% +\def\xintfloateval {\expanded\expandafter\xint_floateval_chkopt\string}% +\def\xint_floateval_chkopt #1% +{% + \ifx [#1\expandafter\xint_floateval_opt + \else\expandafter\xint_floateval_noopt + \fi #1% +}% +\def\xint_floateval_opt [#1]#2% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr[#1]#2\relax}% +\def\xint_floateval_noopt #1{\expandafter\xint_floateval\expandafter{\iffalse}\fi}% +\def\xint_floateval#1% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr#1\relax}% \def\xintiieval #1% {\expanded\expandafter\XINTiiexprprint\expandafter.\romannumeral0\xintbareiieval#1\relax}% % \end{macrocode} @@ -38100,6 +38671,113 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}% \def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}% % \end{macrocode} +% \subsubsection{\csh{xintFracToSci}} +% \added{1.4} +% \changed{1.4e} +% \lverb|Refactored and much simplified +% +% It only needs to be x-expandable, and indeed the implementation here is only +% x-expandable. +% | +% \lverb|& +% +% Finally for 1.4e release I modify. This is breaking change for all +% \xinteval output in case of scientific notation: it will not be with an +% integer mantissa, but with regular scientific notation, using the same rules +% as \xintPFloat. +% +% Of course no float rounding! Also, as [0] will always or almost always be +% present from an \xinteval, we want then to use integer not scientific +% notation. But expression contained decimal fixed point input, or uses +% scientific functions, then probably the N will not be zero and this will +% trigger usage of scientific notation in output. +% +% Implementing these changes sort of ruin our previous efforts to minimize +% grabbing the argument, but well. So the rules now are +% +%( Input: A, A/B, A[N], A/B[N] +%: Output: A, A/B, A if N=0, A/B if N=0 +%: If N is not zero, scientific notation like \xintPFloat,& +% i.e. behaviour like \xintfloateval apart from the rounding& +% to significands of width Digits.& +% At 1.4k, trimming of zeros is always done, i.e.& +% the \xintPFloatMinTrimmed is ignored to keep behaviour.& +% unchanged. +%: The zero gives 0, except in A[N] and A/B[N] cases, it may give& +% 0.0 +%) +% | +% \changed{1.4k} +% Moved from \xintfracnameimp to \xintexprnameimp. +% \begin{macrocode} +\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToSci #1/#2#3[#4% +{% + \xint_gob_til_W #2\XINT_FracToSci_noslash\W + \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R + \XINT_FracToSci_slash_N #1/#2#3[#4% +}% +\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% +{% + \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R + \XINT_FracToSci_noslash_N #2[#3% +}% +\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% +{% + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1[#2]}% + \fi +}% +\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% +{% + #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue + #2\if\XINT_isOne{#3}1\else/#3\fi\fi +}% +\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% +{% + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi +}% +\let\xintexprPrintOne\xintFracToSci +% \end{macrocode} +% \subsubsection{\csh{xintFracToDecimal}} +% \added{1.4k} +% \begin{macrocode} +\def\xintFracToDecimal #1{\expandafter\XINT_FracToDecimal\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToDecimal #1/#2#3[#4% +{% + \xint_gob_til_W #2\XINT_FracToDecimal_noslash\W + \xint_gob_til_R #4\XINT_FracToDecimal_slash_noN\R + \XINT_FracToDecimal_slash_N #1/#2#3[#4% +}% +\def\XINT_FracToDecimal_noslash#1\XINT_FracToDecimal_slash_N #2[#3% +{% + \xint_gob_til_R #3\XINT_FracToDecimal_noslash_noN\R + \XINT_FracToDecimal_noslash_N #2[#3% +}% +\def\XINT_FracToDecimal_noslash_noN\R\XINT_FracToDecimal_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToDecimal_noslash_N #1[#2]/\W[\R% +{% + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1[#2]}% + \fi +}% +\def\XINT_FracToDecimal_slash_noN\R\XINT_FracToDecimal_slash_N #1#2/#3/\W[\R% +{% + #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue + #2\if\XINT_isOne{#3}1\else/#3\fi\fi +}% +\def\XINT_FracToDecimal_slash_N #1#2/#3[#4]/\W[\R% +{% + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi +}% +% \end{macrocode} % \subsubsection{Small bits we have to put somewhere} % \lverb|& % Some renaming and modifications here with release 1.2 to switch from @@ -41144,7 +41822,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % contains correctly nested parentheses} % % \lverb|Expands to \xint_c_mone in case a closing ) had no opening ( matching -% it, to \@ne if opening ) had no closing ) matching it, to \z@ if expression +% it, to \@ne if opening ( had no closing ) matching it, to \z@ if expression % was balanced. Call it as: % % \XINT_isbalanced_a \relax #1(\xint_bye)\xint_bye @@ -43376,8 +44054,19 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \subsubsection{\csh{xintdefufunc}, \csh{xintdefiiufunc}, % \csh{xintdeffloatufunc}} % -% \lverb|1.4| -% +% \lverb|Added at 1.4| +% \changed[2022/05/15]{1.4k} +% \lverb+The \xintexprSafeCatcodes was not paired correctly with +% \xintexprRestoreCatcodes which was in only one branch of \xint_defufunc_b, +% and as a result sanitization of catcodes was never reverted. That the +% bug remained unseen and in particular did not break compilation of +% user manual (where the | must be active), was a sort of unhappy miracle +% due to the | ending up recovering its active catcode from some ulterior +% \xintdefiifunc whose Safe/Restore behaved as described in the user manual, +% i.e. it did a restore to the state before the first unpaired Safe, and this +% miraculous recovery happened before breakage had happened, by sheer luck, +% or rather lack of luck, else I would have seen and solved +% the problem two years ago...+ % \begin{macrocode} \def\XINT_tmpa #1#2#3#4#5#6% {% @@ -43393,11 +44082,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \ifnum\xintLength:f:csv{\XINT_defufunc_tmpd}=\xint_c_i \expandafter#6% \else - \xintMessage {xintexpr}{ERROR} + \xintMessage {xintexpr}{ERROR} {Universal functions must be functions of one argument only, but the declaration of \XINT_defufunc_tmpa\space - has \xintLength:f:csv{\XINT_defufunc_tmpd} of them. Cancelled.}% - \xintexprRestoreCatcodes + has \xintLength:f:csv{\XINT_defufunc_tmpd} of them. Canceled.}% + \xintexprRestoreCatcodes \fi }% end of \xint_defufunc_b \def #6{% @@ -43416,6 +44105,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% with \ifxintglobaldefs global \fi meaning \expandafter\meaning \csname XINT_#2_userufunc_\XINT_defufunc_tmpa\endcsname}% \fi + \xintexprRestoreCatcodes }% end of \xint_defufunc_c }% \def\xintdefufunc {\xintexprSafeCatcodes\xintdefufunc_a}% @@ -44278,8 +44968,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % Up to and including 1.2c the definition was global. Starting with 1.2d it is % done locally. % -% Modified at 1.3c so that \XINT_NewFunc et al. do not execute the -% \xintexprSafeCatcodes, as it is now already done earlier by \xintdeffunc. +% The \xintexprSafeCatcodes inserted here by \xintNewExpr +% is not paired with an \xintexprRestoreCatcodes, +% but this happens within a scope limiting group so does not matter. +% At 1.3c, \XINT_NewFunc et al. do not even execute the +% \xintexprSafeCatcodes, as it gets already done by \xintdeffunc prior +% to arriving here. % % | % \begin{macrocode} @@ -44375,15 +45069,25 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode`% 14 \XINTsetcatcodes % clean up to avoid surprises if something changes % \end{macrocode} -% \subsubsection{\csh{ifxintexprsafecatcodes}, \csh{xintexprSafeCatcodes}, \csh{xintexprRestoreCatcodes}} +% \subsubsection{\csh{xintexprSafeCatcodes}, \csh{xintexprRestoreCatcodes}} % \changed[2018/06/17]{1.3c} % \lverb|Added \ifxintexprsafecatcodes to allow nesting| -% \begin{macrocode} -\newif\ifxintexprsafecatcodes -\let\xintexprRestoreCatcodes\empty +% \changed[2022/05/15]{1.4k} +% \lverb|The "allow nesting" from the 2018 comment was strange, because +% the behaviour, as correctly documented in user manual, was that +% in case of a series of \xintexprSafeCatcodes, the \xintexprRestoreCatcodes +% would set catcodes to what they were before the *first* sanitization. +% But as \xintdefvar and \xintdeffunc used such a pair this meant +% that they would incomprehensibly for user reset catcodes to what +% they were before a possible user \xintexprSafeCatcodes located before... +% very lame situation. Anyway. I finally +% fix at 1.4k that by removing the silly \ifxintexprsafecatcodes thing +% and replace it by some stack-like method, avoiding extra macros +% thanks to the help of \unexpanded.| +% \begin{macrocode} +\def\xintexprRestoreCatcodes{}% \def\xintexprSafeCatcodes {% - \unless\ifxintexprsafecatcodes \edef\xintexprRestoreCatcodes {% \endlinechar=\the\endlinechar \catcode59=\the\catcode59 % ; @@ -44409,11 +45113,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode44=\the\catcode44 % , \catcode61=\the\catcode61 % = \catcode96=\the\catcode96 % ` - \catcode32=\the\catcode32\relax % space - \noexpand\xintexprsafecatcodesfalse + \catcode32=\the\catcode32 % space + \def\noexpand\xintexprRestoreCatcodes{\unexpanded\expandafter{\xintexprRestoreCatcodes}}% }% - \fi - \xintexprsafecatcodestrue \endlinechar=13 % \catcode59=12 % ; \catcode34=12 % " @@ -44587,10 +45289,10 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/07/13 v1.4j}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/18 v1.4k}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2021/07/13 v1.4j Trigonometrical functions for xintexpr (JFB)]% +[2022/05/18 v1.4k Trigonometrical functions for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{Ensure used letters are dummy letters} @@ -45907,10 +46609,10 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@log\endcsname{2021/07/13 v1.4j}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/18 v1.4k}% \XINT_providespackage \ProvidesPackage{xintlog}% -[2021/07/13 v1.4j Logarithms and exponentials for xintexpr (JFB)]% +[2022/05/18 v1.4k Logarithms and exponentials for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{\csh{xintreloadxintlog}} @@ -46491,11 +47193,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % function, those with D+10 digits are used to compute log10() function. This % is done with % an elevated precision for two reasons: -% (- handling of inputs near 1, -% :- in order for a^b = pow10(b*log10(a)) to keep accuracy& +%( - handling of inputs near 1, +%: - in order for a^b = pow10(b*log10(a)) to keep accuracy& % even with large exponents, say in absolute value up to 1e7,& % degradation beginning to show-up at 1e8. -% ) +%) % | % \begin{macrocode} \def\XINT_tmpa{1[0]}% @@ -47946,8 +48648,8 @@ xint.sty:205 xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:272 -xintexpr.sty:453 -xintfrac.sty:511 +xintexpr.sty:465 +xintfrac.sty:522 xintgcd.sty:41 xintkernel.sty:17 xintlog.sty:150 @@ -47956,15 +48658,15 @@ xinttools.sty:157 xinttrig.sty:65 \fi % grep -o "^{%" xint*sty | wc -l -\def\totala{ 2155} +\def\totala{ 2178} \iffalse % grep -c -e "^}%" xint*sty xint.sty:204 xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:269 -xintexpr.sty:436 -xintfrac.sty:515 +xintexpr.sty:448 +xintfrac.sty:527 xintgcd.sty:43 xintkernel.sty:17 xintlog.sty:151 @@ -47973,7 +48675,7 @@ xinttools.sty:156 xinttrig.sty:64 \fi % grep -o "^}%" xint*sty | wc -l -\def\totalb{ 2138} +\def\totalb{ 2162} \cleardoublepage \section{Cumulative line count} @@ -47997,8 +48699,8 @@ xinttrig.sty:64 \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -\CheckSum {38590}% 1.4j -% 38591 pour 1.4i, 38427 pour 1.4h +\CheckSum {38925}% 1.4j +% 38590 pour 1.4j, 38591 pour 1.4i, 38427 pour 1.4h % 38423 pour 1.4g, 38212 pour 1.4f, 38813 pour 1.4e, 35184 pour 1.4d % 35109 pour 1.4c, 35103 pour 1.4b, 34648 pour 1.4a, 34575 pour 1.4 % 33497 pour 1.3f, 33274 pour 1.3e, 31601 pour 1.3d, 31122 pour 1.3c diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty index 01e0fb1b1a7..800b3fbf5c8 100644 --- a/Master/texmf-dist/tex/generic/xint/xint.sty +++ b/Master/texmf-dist/tex/generic/xint/xint.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xint: Expandable operations on big integers %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) \XINT_providespackage \ProvidesPackage{xint}% - [2021/07/13 v1.4j Expandable operations on big integers (JFB)]% + [2022/05/18 v1.4k Expandable operations on big integers (JFB)]% \long\def\xint_firstofthree #1#2#3{#1}% \long\def\xint_secondofthree #1#2#3{#2}% \long\def\xint_thirdofthree #1#2#3{#3}% diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty index 05ac782f8b1..243b7c325aa 100644 --- a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty +++ b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintbinhex: Expandable binary and hexadecimal conversions %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2021/07/13 v1.4j Expandable binary and hexadecimal conversions (JFB)]% + [2022/05/18 v1.4k Expandable binary and hexadecimal conversions (JFB)]% \newcount\xint_c_ii^xv \xint_c_ii^xv 32768 \newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536 \def\XINT_tmpa #1{\ifx\relax#1\else diff --git a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty index 1893763130f..e538575f50f 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2021/07/13 v1.4j Expandable continued fractions with xint package (JFB)]% + [2022/05/18 v1.4k Expandable continued fractions with xint package (JFB)]% \def\xintCFrac {\romannumeral0\xintcfrac }% \def\xintcfrac #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintcore.sty b/Master/texmf-dist/tex/generic/xint/xintcore.sty index 982e345e6ea..a11d046dec7 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcore.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcore.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintcore: Expandable arithmetic on big integers %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcore}% - [2021/07/13 v1.4j Expandable arithmetic on big integers (JFB)]% + [2022/05/18 v1.4k Expandable arithmetic on big integers (JFB)]% \csname XINT_Clamped_istrapped\endcsname \csname XINT_ConversionSyntax_istrapped\endcsname \csname XINT_DivisionByZero_istrapped\endcsname diff --git a/Master/texmf-dist/tex/generic/xint/xintexpr.sty b/Master/texmf-dist/tex/generic/xint/xintexpr.sty index 8f2f4e5ac61..84db61a81a1 100644 --- a/Master/texmf-dist/tex/generic/xint/xintexpr.sty +++ b/Master/texmf-dist/tex/generic/xint/xintexpr.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintexpr: Expandable expression parser %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -82,7 +82,7 @@ \XINTsetupcatcodes% \XINT_providespackage \ProvidesPackage{xintexpr}% - [2021/07/13 v1.4j Expandable expression parser (JFB)]% + [2022/05/18 v1.4k Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -318,7 +318,6 @@ \def\XINT_flexpr_wrap {\XINTfstop\XINTflexprprint}% \protected\def\XINTexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintexprPrintOne}% -\let\xintexprPrintOne\xintFracToSci \protected\def\XINTiexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintiexprPrintOne}% \let\xintiexprPrintOne\xintDecToString @@ -367,12 +366,34 @@ \expanded\XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTinFloatSdigits_braced}% }% \def\XINTinFloatSdigits_braced#1{{\XINTinFloatS[\XINTdigits]{#1}}}% +\let\xint_relax\relax \def\xinteval #1% {\expanded\expandafter\XINTexprprint\expandafter.\romannumeral0\xintbareeval#1\relax}% -\def\xintieval #1% - {\expanded\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr#1\relax}% -\def\xintfloateval #1% - {\expanded\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr#1\relax}% +\def\xintieval + {\expanded\expandafter\xint_ieval_chkopt\string}% +\def\xint_ieval_chkopt #1% +{% + \ifx [#1\expandafter\xint_ieval_opt + \else\expandafter\xint_ieval_noopt + \fi #1% +}% +\def\xint_ieval_opt [#1]#2% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr[#1]#2\relax}% +\def\xint_ieval_noopt #1{\expandafter\xint_ieval\expandafter{\iffalse}\fi}% +\def\xint_ieval#1% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintiexpr#1\relax}% +\def\xintfloateval {\expanded\expandafter\xint_floateval_chkopt\string}% +\def\xint_floateval_chkopt #1% +{% + \ifx [#1\expandafter\xint_floateval_opt + \else\expandafter\xint_floateval_noopt + \fi #1% +}% +\def\xint_floateval_opt [#1]#2% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr[#1]#2\relax}% +\def\xint_floateval_noopt #1{\expandafter\xint_floateval\expandafter{\iffalse}\fi}% +\def\xint_floateval#1% + {\expandafter\xint_gobble_i\romannumeral`&&@\xintfloatexpr#1\relax}% \def\xintiieval #1% {\expanded\expandafter\XINTiiexprprint\expandafter.\romannumeral0\xintbareiieval#1\relax}% \def\xintboolexpr @@ -391,6 +412,69 @@ \def\xintifsgnexpr #1{\romannumeral0\xintiiifsgn {\xinttheexpr #1\relax}}% \def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}% \def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}% +\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToSci #1/#2#3[#4% +{% + \xint_gob_til_W #2\XINT_FracToSci_noslash\W + \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R + \XINT_FracToSci_slash_N #1/#2#3[#4% +}% +\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% +{% + \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R + \XINT_FracToSci_noslash_N #2[#3% +}% +\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% +{% + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1[#2]}% + \fi +}% +\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% +{% + #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue + #2\if\XINT_isOne{#3}1\else/#3\fi\fi +}% +\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% +{% + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi +}% +\let\xintexprPrintOne\xintFracToSci +\def\xintFracToDecimal #1{\expandafter\XINT_FracToDecimal\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToDecimal #1/#2#3[#4% +{% + \xint_gob_til_W #2\XINT_FracToDecimal_noslash\W + \xint_gob_til_R #4\XINT_FracToDecimal_slash_noN\R + \XINT_FracToDecimal_slash_N #1/#2#3[#4% +}% +\def\XINT_FracToDecimal_noslash#1\XINT_FracToDecimal_slash_N #2[#3% +{% + \xint_gob_til_R #3\XINT_FracToDecimal_noslash_noN\R + \XINT_FracToDecimal_noslash_N #2[#3% +}% +\def\XINT_FracToDecimal_noslash_noN\R\XINT_FracToDecimal_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToDecimal_noslash_N #1[#2]/\W[\R% +{% + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1[#2]}% + \fi +}% +\def\XINT_FracToDecimal_slash_noN\R\XINT_FracToDecimal_slash_N #1#2/#3/\W[\R% +{% + #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue + #2\if\XINT_isOne{#3}1\else/#3\fi\fi +}% +\def\XINT_FracToDecimal_slash_N #1#2/#3[#4]/\W[\R% +{% + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi +}% \def\XINT_embrace#1{{#1}}% \def\xint_gob_til_! #1!{}% ! with catcode 11 \def\xintError:noopening @@ -3632,11 +3716,11 @@ \ifnum\xintLength:f:csv{\XINT_defufunc_tmpd}=\xint_c_i \expandafter#6% \else - \xintMessage {xintexpr}{ERROR} + \xintMessage {xintexpr}{ERROR} {Universal functions must be functions of one argument only, but the declaration of \XINT_defufunc_tmpa\space - has \xintLength:f:csv{\XINT_defufunc_tmpd} of them. Cancelled.}% - \xintexprRestoreCatcodes + has \xintLength:f:csv{\XINT_defufunc_tmpd} of them. Canceled.}% + \xintexprRestoreCatcodes \fi }% end of \xint_defufunc_b \def #6{% @@ -3655,6 +3739,7 @@ with \ifxintglobaldefs global \fi meaning \expandafter\meaning \csname XINT_#2_userufunc_\XINT_defufunc_tmpa\endcsname}% \fi + \xintexprRestoreCatcodes }% end of \xint_defufunc_c }% \def\xintdefufunc {\xintexprSafeCatcodes\xintdefufunc_a}% @@ -4435,11 +4520,9 @@ }@ \catcode`% 14 \XINTsetcatcodes % clean up to avoid surprises if something changes -\newif\ifxintexprsafecatcodes -\let\xintexprRestoreCatcodes\empty +\def\xintexprRestoreCatcodes{}% \def\xintexprSafeCatcodes {% - \unless\ifxintexprsafecatcodes \edef\xintexprRestoreCatcodes {% \endlinechar=\the\endlinechar \catcode59=\the\catcode59 % ; @@ -4465,11 +4548,9 @@ \catcode44=\the\catcode44 % , \catcode61=\the\catcode61 % = \catcode96=\the\catcode96 % ` - \catcode32=\the\catcode32\relax % space - \noexpand\xintexprsafecatcodesfalse + \catcode32=\the\catcode32 % space + \def\noexpand\xintexprRestoreCatcodes{\unexpanded\expandafter{\xintexprRestoreCatcodes}}% }% - \fi - \xintexprsafecatcodestrue \endlinechar=13 % \catcode59=12 % ; \catcode34=12 % " diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty index d5bb34ac647..00de2592152 100644 --- a/Master/texmf-dist/tex/generic/xint/xintfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintfrac.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintfrac: Expandable operations on fractions %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintfrac}% - [2021/07/13 v1.4j Expandable operations on fractions (JFB)]% + [2022/05/18 v1.4k Expandable operations on fractions (JFB)]% \def\XINT_cntSgnFork #1% {% \ifcase #1\expandafter\xint_secondofthree @@ -458,37 +458,6 @@ \def\XINT_spraw #1[#2#3]{\xint_gob_til_W #2\XINT_spraw_a\W\XINT_spraw_p #1[#2#3]}% \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% -\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToSci #1/#2#3[#4% -{% - \xint_gob_til_W #2\XINT_FracToSci_noslash\W - \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R - \XINT_FracToSci_slash_N #1/#2#3[#4% -}% -\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R - \XINT_FracToSci_noslash_N #2[#3% -}% -\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% -{% - \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1[#2]}% - \fi -}% -\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% -{% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\if\XINT_isOne{#3}1\else/#3\fi\fi -}% -\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% -{% - \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1#2[#4]}% - \fi - \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi -}% \def\xintRawWithZeros {\romannumeral0\xintrawwithzeros }% \def\xintrawwithzeros {% @@ -2127,6 +2096,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \mathchardef\XINT_digits=\numexpr#1\relax \let\XINTdigits=\XINT_digits }% +\def\xintFloatZero{0.0e0}% 1.4k breaking change. Replaces hard-coded 0.e0 \def\xintFloat {\romannumeral0\xintfloat }% \def\xintfloat #1{\XINT_float_chkopt #1\xint:}% \def\XINT_float_chkopt #1% @@ -2157,7 +2127,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% 0-\XINT_float_pos \krof #1% }%[ -\def\XINT_float_zero #1]#2.{ 0.e0}% +\def\XINT_float_zero #1]#2.{\expanded{ \xintFloatZero}}% \def\XINT_float_neg-{\expandafter-\romannumeral0\XINT_float_pos}% \def\XINT_float_pos #1#2[#3]#4.% {% @@ -2182,18 +2152,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_infloatS_clean #1% {\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}% \def\XINT_infloatS_clean_a !#1.{ }% -\def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}% -\def\XINTfloatilogten [#1]#2% - {\expandafter\XINT_floatilogten\romannumeral0\XINT_infloat[#1]{#2}#1.}% -\def\XINTFloatiLogTendigits{\the\numexpr\XINTfloatilogten[\XINTdigits]}% -\def\XINT_floatilogten #1{% - \if #10\xint_dothis\XINT_floatilogten_z\fi - \if #1!\xint_dothis\XINT_floatilogten_a\fi - \xint_orthat\XINT_floatilogten_b #1% -}% -\def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% -\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% \def\XINT_infloat [#1]#2% {% \expandafter\XINT_infloat_a\the\numexpr #1\expandafter.% @@ -2377,11 +2335,89 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_infloat_ZZ\the\numexpr#4+\xint_c_i.#3.% }% \def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}% +\def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}% +\def\XINTfloatilogten [#1]#2% + {\expandafter\XINT_floatilogten\romannumeral0\XINT_infloat[#1]{#2}#1.}% +\def\XINTFloatiLogTendigits{\the\numexpr\XINTfloatilogten[\XINTdigits]}% +\def\XINT_floatilogten #1{% + \if #10\xint_dothis\XINT_floatilogten_z\fi + \if #1!\xint_dothis\XINT_floatilogten_a\fi + \xint_orthat\XINT_floatilogten_b #1% +}% +\def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% +\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% +\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% +\def\xintFloatSciExp {\the\numexpr\xintfloatsciexp }% +\def\xintpfloatsciexp #1{\XINT_floatsciexp_chkopt #1\xint:}% +\def\XINT_floatsciexp_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatsciexp_opt + \else\expandafter\XINT_floatsciexp_noopt + \fi #1% +}% +\def\XINT_floatsciexp_noopt #1\xint:% +{% + \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[\XINTdigits]{#1}% + \XINTdigits.% +}% +\def\XINT_floatsciexp_opt [\xint:#1]#2% +{% + \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[#1]{#2}#1.% +}% +\def\XINT_floatsciexp #1{% + \if #10\xint_dothis\XINT_floatsciexp_z\fi + \if #1!\xint_dothis\XINT_floatsciexp_a\fi + \xint_orthat\XINT_floatsciexp_b #1% +}% +\def\XINT_floatsciexp_z 0[0]#1.{0\relax}% +\def\XINT_floatsciexp_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% +\def\XINT_floatsciexp_b #1[#2]#3.{#2+#3-1\relax}% +\def\xintFloatSignificand {\romannumeral0\xintfloatsignificand}% +\def\xintfloatsignificand #1{\XINT_floatsgf_chkopt #1\xint:}% +\def\XINT_floatsgf_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatsgf_opt + \else\expandafter\XINT_floatsgf_noopt + \fi #1% +}% +\def\XINT_floatsgf_noopt #1\xint:% +{% + \expandafter\XINT_floatsgf_post + \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% +}% +\def\XINT_floatsgf_opt [\xint:#1]% +{% + \expandafter\XINT_floatsgf_opt_a\the\numexpr #1.% +}% +\def\XINT_floatsgf_opt_a #1.#2% +{% + \expandafter\XINT_floatsgf_post + \romannumeral0\XINTinfloat[#1]{#2}#1.% +}% +\def\XINT_floatsgf_post #1% +{% + \xint_UDzerominusfork + #1-\XINT_floatsgf_zero + 0#1\XINT_floatsgf_neg + 0-\XINT_floatsgf_pos + \krof #1% +}%[ +\def\XINT_floatsgf_zero #1]#2.{\XINT_dsx_addzeros{#2};}% +\def\XINT_floatsgf_neg-{\XINT_floatsgf_pos}% +\def\XINT_floatsgf_pos #1[#2]#3.{ #1}% +\def\xintPFloatE{e}% +\def\xintPFloatNoSciEmax{\xint_c_v}% 1e6 uses sci.not. +\def\xintPFloatNoSciEmin{-\xint_c_iv}% 1e-5 uses sci.not. +\def\xintPFloatIntSuffix{}% +\def\xintPFloatLengthOneSuffix{}% +\def\xintPFloatZero{0}% +\def\xintPFloatMinTrimmed{\xint_c_iv}% \def\xintPFloat {\romannumeral0\xintpfloat }% \def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint:}% -\def\xintPFloat_wopt +\def\xintPFloat_wopt[#1]#2% {% - \romannumeral0\expandafter\XINT_pfloat\romannumeral0\XINTinfloatS + \romannumeral0\expandafter\XINT_pfloat + \romannumeral0\XINTinfloatS[#1]{#2}#1.% }% \def\XINT_pfloat_chkopt #1% {% @@ -2392,10 +2428,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_pfloat_noopt #1\xint:% {% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% + \XINTdigits.% }% -\def\XINT_pfloat_opt [\xint:#1]% +\def\XINT_pfloat_opt [\xint:#1]#2% {% - \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]{#2}% + #1.% }% \def\XINT_pfloat#1]% {% @@ -2409,13 +2447,41 @@ on input line \noexpand\the\inputlineno.&&J}}#2% 0-\XINT_pfloat_pos \krof #1% }% -\def\XINT_pfloat_zero#1]{ 0.0}% +\def\XINT_pfloat_zero#1]#2.{\expanded{ \xintPFloatZero}}% \def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos}% -\def\XINT_pfloat_pos#1/1[#2]% +\def\XINT_pfloat_pos#1/1[#2]#3.% {% - \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.% - #2.#1.% + \expandafter\XINT_pfloat_aa\the\numexpr\xintLength{#1}.% + #3.#2.#1.% }% +\def\XINT_pfloat_keeptrimmed_fork#1% +{% + \xint_UDzerominusfork + #1-\XINT_pfloat_keeptrimmed_zero + 0#1\XINT_pfloat_keeptrimmed_neg + 0-\XINT_pfloat_keeptrimmed_pos + \krof #1% +}% +\def\XINT_pfloat_keeptrimmed_zero#1]{\expanded{ \xintPFloatZero}}% +\def\XINT_pfloat_keeptrimmed_neg-{\expandafter-\romannumeral0\XINT_pfloat_keeptrimmed_pos}% +\def\XINT_pfloat_keeptrimmed_pos#1/1[#2]% +{% + \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.#2.#1.% +}% +\def\XINT_pfloat_aa #1.#2.% +{% + \unless\ifnum\xintPFloatMinTrimmed>\numexpr#2-#1\relax + \xint_dothis\XINT_pfloat_a\fi + \ifnum#2>#1 \xint_dothis{\XINT_pfloat_i #2.}\fi + \xint_orthat\XINT_pfloat_a #1.% +}% +\def\XINT_pfloat_i #1.#2.#3.#4.% +{% + \expandafter\XINT_pfloat_j + \the\numexpr#3+#2-#1\expandafter.% + \romannumeral0\XINT_dsx_addzerosnofuss{#1-#2}#4;.#1.% +}% +\def\XINT_pfloat_j #1.#2.#3.{\XINT_pfloat_a#3.#1.#2.}% \def\XINT_pfloat_a #1.#2#3.% {% \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% @@ -2423,8 +2489,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_pfloat_b #1.#2% {% - \ifnum #1>\xint_c_v \xint_dothis\XINT_pfloat_sci\fi - \ifnum #1<-\xint_c_iv \xint_dothis\XINT_pfloat_sci\fi + \ifnum \xintPFloatNoSciEmax<#1 \xint_dothis\XINT_pfloat_sci\fi + \ifnum \xintPFloatNoSciEmin>#1 \xint_dothis\XINT_pfloat_sci\fi \ifnum #1<\xint_c_ \xint_dothis\XINT_pfloat_N\fi \if-#2\xint_dothis\XINT_pfloat_P\fi \xint_orthat\XINT_pfloat_Ps @@ -2436,36 +2502,42 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_pfloat_sci_a\romannumeral`&&@\xintPFloatE #1.% }% \def\XINT_pfloat_sci_a #1.#2#3.{ #2.#3#1}% -\edef\XINT_pfloat_sci_i #1#2#3.#4.{#1\space#4.0#3}% -\def\xintPFloatE{e}% +\def\XINT_pfloat_sci_i #1#2#3.#4.{\expanded{#1 #4\xintPFloatLengthOneSuffix}#3}% \def\XINT_pfloat_N#1.#2.#3.% {% - \csname XINT_pfloat_N_\romannumeral-#1\endcsname #3% + \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#3% }% -\def\XINT_pfloat_N_i { 0.}% -\def\XINT_pfloat_N_ii { 0.0}% -\def\XINT_pfloat_N_iii{ 0.00}% -\def\XINT_pfloat_N_iv { 0.000}% +\def\XINT_pfloat_N_e 0{ 0.}% \def\XINT_pfloat_P #1.#2.#3.% {% - \csname XINT_pfloat_P_\romannumeral#1\endcsname #3% + \expandafter\XINT_split_fromleft_a + \the\numexpr\xint_c_vii-#1.#3\xint_bye2345678\xint_bye.% }% -\def\XINT_pfloat_P_ #1{ #1.}% -\def\XINT_pfloat_P_i #1#2{ #1#2.}% -\def\XINT_pfloat_P_ii #1#2#3{ #1#2#3.}% -\def\XINT_pfloat_P_iii#1#2#3#4{ #1#2#3#4.}% -\def\XINT_pfloat_P_iv #1#2#3#4#5{ #1#2#3#4#5.}% -\def\XINT_pfloat_P_v #1#2#3#4#5#6{ #1#2#3#4#5#6.}% \def\XINT_pfloat_Ps #1.#2.#3.% {% - \csname XINT_pfloat_Ps_\romannumeral#1\endcsname #300000.% + \expanded{ #3% + \romannumeral\xintreplicate{#1+\xint_c_i-#2}{0}\xintPFloatIntSuffix}% +}% +\def\xintFloatToDecimal {\romannumeral0\xintfloattodecimal }% +\def\xintfloattodecimal #1{\XINT_floattodec_chkopt #1\xint:}% +\def\XINT_floattodec_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floattodec_opt + \else\expandafter\XINT_floattodec_noopt + \fi #1% +}% +\def\XINT_floattodec_noopt #1\xint:% +{% + \expandafter\XINT_floattodec\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% +}% +\def\XINT_floattodec_opt [\xint:#1]% +{% + \expandafter\XINT_floattodec\romannumeral0\XINTinfloatS[#1]% +}% +\def\XINT_floattodec#1]% +{% + \expandafter\XINT_dectostr\romannumeral0\xintrez{#1]}% }% -\def\XINT_pfloat_Ps_ #1#2.{ #1.0}% -\def\XINT_pfloat_Ps_i #1#2#3.{ #1#2.0}% -\def\XINT_pfloat_Ps_ii #1#2#3#4.{ #1#2#3.0}% -\def\XINT_pfloat_Ps_iii#1#2#3#4#5.{ #1#2#3#4.0}% -\def\XINT_pfloat_Ps_iv #1#2#3#4#5#6.{ #1#2#3#4#5.0}% -\def\XINT_pfloat_Ps_v #1#2#3#4#5#6#7.{ #1#2#3#4#5#6.0}% \def\XINTinFloatFrac {\romannumeral0\XINTinfloatfrac}% \def\XINTinfloatfrac #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty index fc7051f3724..3570a8f1eb8 100644 --- a/Master/texmf-dist/tex/generic/xint/xintgcd.sty +++ b/Master/texmf-dist/tex/generic/xint/xintgcd.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintgcd: Euclidean algorithm with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -77,7 +77,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintgcd}% - [2021/07/13 v1.4j Euclide algorithm with xint package (JFB)]% + [2022/05/18 v1.4k Euclide algorithm with xint package (JFB)]% \def\xintBezout {\romannumeral0\xintbezout }% \def\xintbezout #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty index 027c3b77562..3e6c0afa591 100644 --- a/Master/texmf-dist/tex/generic/xint/xintkernel.sty +++ b/Master/texmf-dist/tex/generic/xint/xintkernel.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintkernel: Paraphernalia for the xint packages %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -159,7 +159,7 @@ \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2021/07/13 v1.4j Paraphernalia for the xint packages (JFB)]% + [2022/05/18 v1.4k Paraphernalia for the xint packages (JFB)]% \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 diff --git a/Master/texmf-dist/tex/generic/xint/xintlog.sty b/Master/texmf-dist/tex/generic/xint/xintlog.sty index bc6d3039b08..c5751af1217 100644 --- a/Master/texmf-dist/tex/generic/xint/xintlog.sty +++ b/Master/texmf-dist/tex/generic/xint/xintlog.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintlog: Logarithms and exponentials for xintexpr %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -68,10 +68,10 @@ \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@log\endcsname{2021/07/13 v1.4j}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/18 v1.4k}% \XINT_providespackage \ProvidesPackage{xintlog}% -[2021/07/13 v1.4j Logarithms and exponentials for xintexpr (JFB)]% +[2022/05/18 v1.4k Logarithms and exponentials for xintexpr (JFB)]% }% \def\xintreloadxintlog{\input xintlog.sty }% \xintexprSafeCatcodes\catcode`_ 11 diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty index ad236f03790..8fa98b8c382 100644 --- a/Master/texmf-dist/tex/generic/xint/xintseries.sty +++ b/Master/texmf-dist/tex/generic/xint/xintseries.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintseries: Expandable partial sums with xint package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintseries}% - [2021/07/13 v1.4j Expandable partial sums with xint package (JFB)]% + [2022/05/18 v1.4k Expandable partial sums with xint package (JFB)]% \def\xintSeries {\romannumeral0\xintseries }% \def\xintseries #1#2% {% diff --git a/Master/texmf-dist/tex/generic/xint/xinttools.sty b/Master/texmf-dist/tex/generic/xint/xinttools.sty index 73a5f513892..eb6f898b355 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttools.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttools.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xinttools: Expandable and non-expandable utilities %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xinttools}% - [2021/07/13 v1.4j Expandable and non-expandable utilities (JFB)]% + [2022/05/18 v1.4k Expandable and non-expandable utilities (JFB)]% \newtoks\XINT_toks \xint_firstofone{\let\XINT_sptoken= } %<- space here! \def\xintgodef {\global\xintodef }% diff --git a/Master/texmf-dist/tex/generic/xint/xinttrig.sty b/Master/texmf-dist/tex/generic/xint/xinttrig.sty index 1269d48fca0..ae312937e25 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttrig.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttrig.sty @@ -21,8 +21,8 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4j 2021/07/13 -%% Copyright (C) 2013-2021 by Jean-Francois Burnol +%% The xint bundle 1.4k 2022/05/18 +%% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xinttrig: Trigonometry for the xintexpr package %% --------------------------------------------------------------- \begingroup\catcode61\catcode48\catcode32=10\relax% @@ -69,10 +69,10 @@ \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/07/13 v1.4j}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/18 v1.4k}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2021/07/13 v1.4j Trigonometrical functions for xintexpr (JFB)]% +[2022/05/18 v1.4k Trigonometrical functions for xintexpr (JFB)]% }% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}% \def\xintreloadxinttrig{\input xinttrig.sty }% |