diff options
17 files changed, 7496 insertions, 2639 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html index 20b940dad7c..ca88de72368 100644 --- a/Master/texmf-dist/doc/generic/xint/CHANGES.html +++ b/Master/texmf-dist/doc/generic/xint/CHANGES.html @@ -4,7 +4,7 @@ <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.4d" /> + <meta name="author" content="xint 1.4e" /> <title>CHANGE LOG</title> <style type="text/css"> code{white-space: pre-wrap;} @@ -25,51 +25,56 @@ <body> <header> <h1 class="title">CHANGE LOG</h1> -<p class="author">xint 1.4d</p> -<p class="date">2021/03/29</p> +<p class="author">xint 1.4e</p> +<p class="date">2021/05/05</p> </header> <nav id="TOC"> <ul> -<li><a href="#d-20210329"><code>1.4d (2021/03/29)</code></a><ul> +<li><a href="#e-20210505"><code>1.4e (2021/05/05)</code></a><ul> <li><a href="#breaking-changes">Breaking changes</a></li> +<li><a href="#new-features">New features</a></li> <li><a href="#bug-fixes">Bug fixes</a></li> </ul></li> -<li><a href="#c-20210220"><code>1.4c (2021/02/20)</code></a><ul> +<li><a href="#d-20210329"><code>1.4d (2021/03/29)</code></a><ul> +<li><a href="#breaking-changes-1">Breaking changes</a></li> <li><a href="#bug-fixes-1">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">New features</a></li> +<li><a href="#c-20210220"><code>1.4c (2021/02/20)</code></a><ul> <li><a href="#bug-fixes-2">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-1">Breaking changes</a></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-1">New features</a></li> <li><a href="#bug-fixes-3">Bug fixes</a></li> </ul></li> -<li><a href="#section"><code>1.4 (2020/01/31)</code></a><ul> +<li><a href="#a-20200219"><code>1.4a (2020/02/19)</code></a><ul> <li><a href="#breaking-changes-2">Breaking changes</a></li> -<li><a href="#improvements-and-new-features">Improvements and new features</a></li> +<li><a href="#new-features-2">New features</a></li> <li><a href="#bug-fixes-4">Bug fixes</a></li> +</ul></li> +<li><a href="#section"><code>1.4 (2020/01/31)</code></a><ul> +<li><a href="#breaking-changes-3">Breaking changes</a></li> +<li><a href="#improvements-and-new-features">Improvements and new features</a></li> +<li><a href="#bug-fixes-5">Bug fixes</a></li> <li><a href="#todo">TODO</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-5">Bug fixes</a></li> +<li><a href="#bug-fixes-6">Bug fixes</a></li> </ul></li> <li><a href="#e-20190405"><code>1.3e (2019/04/05)</code></a><ul> -<li><a href="#breaking-changes-3">Breaking changes</a></li> +<li><a href="#breaking-changes-4">Breaking changes</a></li> <li><a href="#improvements-and-new-features-2">Improvements and new features</a></li> -<li><a href="#bug-fixes-6">Bug fixes</a></li> +<li><a href="#bug-fixes-7">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-4">Breaking changes</a></li> +<li><a href="#breaking-changes-5">Breaking changes</a></li> <li><a href="#improvements-and-new-features-3">Improvements and new features</a></li> -<li><a href="#bug-fixes-7">Bug fixes</a></li> +<li><a href="#bug-fixes-8">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-8">Bug fixes</a></li> +<li><a href="#bug-fixes-9">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> @@ -77,85 +82,85 @@ <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-9">Bug fixes</a></li> +<li><a href="#bug-fixes-10">Bug fixes</a></li> </ul></li> <li><a href="#section-1"><code>1.3 (2018/03/01)</code></a><ul> -<li><a href="#breaking-changes-5">Breaking changes</a></li> +<li><a href="#breaking-changes-6">Breaking changes</a></li> <li><a href="#improvements-and-new-features-7">Improvements and new features</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-10">Bug fixes</a></li> +<li><a href="#bug-fixes-11">Bug fixes</a></li> </ul></li> <li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul> -<li><a href="#breaking-changes-6">Breaking changes</a></li> +<li><a href="#breaking-changes-7">Breaking changes</a></li> <li><a href="#improvements-and-new-features-9">Improvements and new features</a></li> -<li><a href="#bug-fixes-11">Bug fixes</a></li> +<li><a href="#bug-fixes-12">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-7">Breaking changes</a></li> +<li><a href="#breaking-changes-8">Breaking changes</a></li> <li><a href="#deprecated">Deprecated</a></li> </ul></li> <li><a href="#n-20170806"><code>1.2n (2017/08/06)</code></a><ul> -<li><a href="#breaking-changes-8">Breaking changes</a></li> +<li><a href="#breaking-changes-9">Breaking changes</a></li> <li><a href="#improvements-and-new-features-10">Improvements and new features</a></li> </ul></li> <li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul> -<li><a href="#breaking-changes-9">Breaking changes</a></li> +<li><a href="#breaking-changes-10">Breaking changes</a></li> <li><a href="#improvements-and-new-features-11">Improvements and new features</a></li> -<li><a href="#bug-fixes-12">Bug fixes</a></li> +<li><a href="#bug-fixes-13">Bug fixes</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-13">Bug fixes</a></li> +<li><a href="#bug-fixes-14">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-10">Breaking changes</a></li> +<li><a href="#breaking-changes-11">Breaking changes</a></li> <li><a href="#improvements-and-new-features-13">Improvements and new features</a></li> -<li><a href="#bug-fixes-14">Bug fixes</a></li> +<li><a href="#bug-fixes-15">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-15">Bug fixes</a></li> +<li><a href="#bug-fixes-16">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-11">Breaking changes</a></li> +<li><a href="#breaking-changes-12">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-16">Bug fixes</a></li> +<li><a href="#bug-fixes-17">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-17">Bug fixes</a></li> +<li><a href="#bug-fixes-18">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-12">Breaking changes</a></li> +<li><a href="#breaking-changes-13">Breaking changes</a></li> <li><a href="#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-13">Breaking changes</a></li> +<li><a href="#breaking-changes-14">Breaking changes</a></li> <li><a href="#improvements-and-new-features-18">Improvements and new features</a></li> -<li><a href="#bug-fixes-18">Bug fixes</a></li> +<li><a href="#bug-fixes-19">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-19">Bug fixes</a></li> +<li><a href="#bug-fixes-20">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-20">Bug fixes</a></li> +<li><a href="#bug-fixes-21">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-21">Bug fixes</a></li> +<li><a href="#bug-fixes-22">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-22">Bug fixes</a></li> +<li><a href="#bug-fixes-23">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-23">Bug fixes</a></li> +<li><a href="#bug-fixes-24">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> @@ -165,11 +170,11 @@ <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-14">Breaking changes</a></li> +<li><a href="#breaking-changes-15">Breaking changes</a></li> <li><a href="#removed-4">Removed</a></li> <li><a href="#deprecated-1">Deprecated</a></li> <li><a href="#improvements-and-new-features-24">Improvements and new features</a></li> -<li><a href="#bug-fixes-24">Bug fixes</a></li> +<li><a href="#bug-fixes-25">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> @@ -197,25 +202,53 @@ <li><a href="#section-10"><code>1.0 (2013/03/28)</code></a></li> </ul> </nav> -<pre><code>Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29) +<pre><code>Source: xint.dtx 1.4e 2021/05/05 (doc 2021/05/05) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> -<h2 id="d-20210329"><code>1.4d (2021/03/29)</code></h2> +<h2 id="e-20210505"><code>1.4e (2021/05/05)</code></h2> +<p>This section might be incomplete at time of release, it will be extended if need be after the author gets some rest.</p> <h3 id="breaking-changes">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><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 now expects to be used with either one or two arguments, the first one being within brackets not braces. It defaults to <code>\xintPFloat</code>.</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.</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 <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> behave differently. 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>xintexpr</strong>: messages sent under <code>\xintverbosetrue</code> regime to the log file do not enclose the variable names in straight double quotes <code>"..."</code> anymore.</p></li> +</ul> +<h3 id="new-features">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 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></p></li> </ul> <h3 id="bug-fixes">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> +</ul> +<h2 id="d-20210329"><code>1.4d (2021/03/29)</code></h2> +<h3 id="breaking-changes-1">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> +</ul> +<h3 id="bug-fixes-1">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> </ul> <h2 id="c-20210220"><code>1.4c (2021/02/20)</code></h2> -<h3 id="bug-fixes-1">Bug fixes</h3> +<h3 id="bug-fixes-2">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> </ul> @@ -227,36 +260,36 @@ License: LPPL 1.3c</code></pre> <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">New features</h3> +<h3 id="new-features-1">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> </ul> -<h3 id="bug-fixes-2">Bug fixes</h3> +<h3 id="bug-fixes-3">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> </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-1">Breaking changes</h3> +<h3 id="breaking-changes-2">Breaking changes</h3> <ul> <li>The macros implementing customization of <code>\xintthealign</code> have modified meanings and names.</li> </ul> -<h3 id="new-features-1">New features</h3> +<h3 id="new-features-2">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> </ul> -<h3 id="bug-fixes-3">Bug fixes</h3> +<h3 id="bug-fixes-4">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> </ul> <h2 id="section"><code>1.4 (2020/01/31)</code></h2> -<h3 id="breaking-changes-2">Breaking changes</h3> +<h3 id="breaking-changes-3">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> @@ -302,7 +335,7 @@ License: LPPL 1.3c</code></pre> <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-4">Bug fixes</h3> +<h3 id="bug-fixes-5">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> @@ -318,13 +351,13 @@ License: LPPL 1.3c</code></pre> <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-5">Bug fixes</h3> +<h3 id="bug-fixes-6">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> </ul> <h2 id="e-20190405"><code>1.3e (2019/04/05)</code></h2> -<h3 id="breaking-changes-3">Breaking changes</h3> +<h3 id="breaking-changes-4">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> @@ -338,12 +371,12 @@ License: LPPL 1.3c</code></pre> <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-6">Bug fixes</h3> +<h3 id="bug-fixes-7">Bug fixes</h3> <ul> <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-4">Breaking changes</h3> +<h3 id="breaking-changes-5">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> @@ -357,7 +390,7 @@ License: LPPL 1.3c</code></pre> <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-7">Bug fixes</h3> +<h3 id="bug-fixes-8">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> </ul> @@ -370,7 +403,7 @@ License: LPPL 1.3c</code></pre> <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-8">Bug fixes</h3> +<h3 id="bug-fixes-9">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> </ul> @@ -396,12 +429,12 @@ License: LPPL 1.3c</code></pre> <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-9">Bug fixes</h3> +<h3 id="bug-fixes-10">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> </ul> <h2 id="section-1"><code>1.3 (2018/03/01)</code></h2> -<h3 id="breaking-changes-5">Breaking changes</h3> +<h3 id="breaking-changes-6">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> @@ -419,12 +452,12 @@ License: LPPL 1.3c</code></pre> <ul> <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-10">Bug fixes</h3> +<h3 id="bug-fixes-11">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> </ul> <h2 id="p-20171205"><code>1.2p (2017/12/05)</code></h2> -<h3 id="breaking-changes-6">Breaking changes</h3> +<h3 id="breaking-changes-7">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> @@ -438,7 +471,7 @@ License: LPPL 1.3c</code></pre> <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-11">Bug fixes</h3> +<h3 id="bug-fixes-12">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> @@ -446,7 +479,7 @@ License: LPPL 1.3c</code></pre> <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-7">Breaking changes</h3> +<h3 id="breaking-changes-8">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> </ul> @@ -462,7 +495,7 @@ License: LPPL 1.3c</code></pre> <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-8">Breaking changes</h3> +<h3 id="breaking-changes-9">Breaking changes</h3> <ul> <li><strong>xintbinhex</strong> does not load package <strong>xintcore</strong> anymore, but only <strong>xintkernel</strong>.</li> </ul> @@ -472,7 +505,7 @@ License: LPPL 1.3c</code></pre> <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-9">Breaking changes</h3> +<h3 id="breaking-changes-10">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> @@ -481,7 +514,7 @@ License: LPPL 1.3c</code></pre> <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> </ul> -<h3 id="bug-fixes-12">Bug fixes</h3> +<h3 id="bug-fixes-13">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 PDF bookmarks were messed up.</p></li> @@ -502,14 +535,14 @@ License: LPPL 1.3c</code></pre> <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-13">Bug fixes</h3> +<h3 id="bug-fixes-14">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> </ul> <h2 id="k-20170106"><code>1.2k (2017/01/06)</code></h2> -<h3 id="breaking-changes-10">Breaking changes</h3> +<h3 id="breaking-changes-11">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> @@ -521,7 +554,7 @@ License: LPPL 1.3c</code></pre> <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-14">Bug fixes</h3> +<h3 id="bug-fixes-15">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> @@ -537,12 +570,12 @@ License: LPPL 1.3c</code></pre> </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> </ul> -<h3 id="bug-fixes-15">Bug fixes</h3> +<h3 id="bug-fixes-16">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> </ul> <h2 id="i-20161213"><code>1.2i (2016/12/13)</code></h2> -<h3 id="breaking-changes-11">Breaking changes</h3> +<h3 id="breaking-changes-12">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> </ul> @@ -569,7 +602,7 @@ License: LPPL 1.3c</code></pre> <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-16">Bug fixes</h3> +<h3 id="bug-fixes-17">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> </ul> @@ -579,7 +612,7 @@ License: LPPL 1.3c</code></pre> <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-17">Bug fixes</h3> +<h3 id="bug-fixes-18">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> @@ -587,7 +620,7 @@ License: LPPL 1.3c</code></pre> <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-12">Breaking changes</h3> +<h3 id="breaking-changes-13">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> @@ -601,7 +634,7 @@ License: LPPL 1.3c</code></pre> <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-13">Breaking changes</h3> +<h3 id="breaking-changes-14">Breaking changes</h3> <ul> <li>no more <code>\xintFac</code> macro but <code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li> </ul> @@ -619,7 +652,7 @@ License: LPPL 1.3c</code></pre> <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-18">Bug fixes</h3> +<h3 id="bug-fixes-19">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> @@ -633,7 +666,7 @@ License: LPPL 1.3c</code></pre> <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-19">Bug fixes</h3> +<h3 id="bug-fixes-20">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> @@ -646,7 +679,7 @@ License: LPPL 1.3c</code></pre> <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-20">Bug fixes</h3> +<h3 id="bug-fixes-21">Bug fixes</h3> <ul> <li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li> </ul> @@ -656,12 +689,12 @@ License: LPPL 1.3c</code></pre> <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-21">Bug fixes</h3> +<h3 id="bug-fixes-22">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> </ul> <h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2> -<h3 id="bug-fixes-22">Bug fixes</h3> +<h3 id="bug-fixes-23">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> </ul> @@ -672,7 +705,7 @@ License: LPPL 1.3c</code></pre> <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-23">Bug fixes</h3> +<h3 id="bug-fixes-24">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> </ul> @@ -715,7 +748,7 @@ License: LPPL 1.3c</code></pre> <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-14">Breaking changes</h3> +<h3 id="breaking-changes-15">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> @@ -773,7 +806,7 @@ License: LPPL 1.3c</code></pre> <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-24">Bug fixes</h3> +<h3 id="bug-fixes-25">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> diff --git a/Master/texmf-dist/doc/generic/xint/README.md b/Master/texmf-dist/doc/generic/xint/README.md index a9dcafa44a0..306213047c4 100644 --- a/Master/texmf-dist/doc/generic/xint/README.md +++ b/Master/texmf-dist/doc/generic/xint/README.md @@ -1,14 +1,15 @@ % README -% xint 1.4d -% 2021/03/29 +% xint 1.4e +% 2021/05/05 - Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29) + Source: xint.dtx 1.4e 2021/05/05 (doc 2021/05/05) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c -Aim and usage -============= + +Description +=========== It is possible to use the package both with Plain (`\input xintexpr.sty`) or with the LaTeX macro format (`\usepackage{xintexpr}`). @@ -16,45 +17,39 @@ or with the LaTeX macro format (`\usepackage{xintexpr}`). The basic aim is provide *expandable* computations on (arbitrarily big) integers, fractions, and floating point numbers (at a user chosen precision). The four operations and the square-root extraction achieve -so-called *correct rounding* for the given arbitrary precision. - -The syntax knows dummy variables, as in this example: - - \xinteval{reduce(add(x/(x+7), x = 1000..1010))} - -which expands to: - - 108959959329292321880648657/9974444716475301992902544 - -Trigonometrical functions are available: - - \xintDigits*:=48\relax - - \xintfloateval{[-2] sind(37)} - -expands to: - - 0.6018150231520482799179770004414898414256377098 - -The [-2] at start of the `\xintfloateval` argument means to round the -result to 2 digits less than the float precision. - -Release `1.4` adds support for nested structures. For example: - - \xintthealign\xintexpr ndseq(1/(i+j), i=1..5; j=1..5)\relax - -will print on the page (this is customizable, e.g. to use a `pmatrix` -environment): - - [[ 1/2, 1/3, 1/4, 1/5, 1/6 ], - [ 1/3, 1/4, 1/5, 1/6, 1/7 ], - [ 1/4, 1/5, 1/6, 1/7, 1/8 ], - [ 1/5, 1/6, 1/7, 1/8, 1/9 ], - [ 1/6, 1/7, 1/8, 1/9, 1/10 ]] - -It is possible to declare "universal functions" (à la NumPy) which will -act itemwise on all leaves of such "arrays". More features are planned -such as providing an interface to algebra of matrices in this framework. +the *correct rounding* for the given arbitrary precision. Exponential +(natural and to the base ten), logarithm (also to the base 10), +fractional powers, direct and inverse trigonometrical functions are +available up to 62 digits of precision. The syntax supports dummy +variables (to generate sequences of values) and nested structures. +Support for user-declared functions and variables is implemented. + +Usage on the command line +========================= + +One can use `xintexpr` as an interactive calculator on the command line. +See the [xintsession](http://ctan.org/pkg/xintsession) package. + + *2^100; + (@_1) 1267650600228229401496703205376 + *cos(1); + (@_2) 0.5403023058681397 + *&fp32 + (./xintlog.sty) (./xinttrig.sty) fp32 mode (log and trig reloaded) + *cos(1); + (@_3) 0.54030230586813971740093660744298 + *3^1000; + (@_4) 1.3220708194808066368904552597521e477 + *&exact + exact mode (floating point evaluations use 32 digits) + *3^1000; + (@_5) 1322070819480806636890455259752144365965422032752148167664920368226828 + 5973467048995407783138506080619639097776968725823559509545821006189118653427252 + 5795367402762022519832080387801477422896484127439040011758861804112894781562309 + 4438061566173054086674490506178125480344405547054397038895817465368254916136220 + 8302685637785822902284163983078878969185564040848989376093732421718463599386955 + 1676501894058810906042608967143886410281435038564874716583201061436613217310276 + 8902855220001 Installation ============ diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf Binary files differindex 0e99479d7c9..8837d727740 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 35ac85b1b04..11ca08941e9 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 6b5ff7588c8..72b1fb1c008 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -3,27 +3,27 @@ % Extract all files via "etex xint.dtx" and do "make help" % or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <29-03-2021 at 11:06:25 CEST>} +\def\xintdtxtimestamp {Time-stamp: <05-05-2021 at 15:26:12 CEST>} %</dtx> %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2021/03/29} -\def\xintbndldate{2021/03/29} -\def\xintbndlversion {1.4d} +\def\xintdocdate {2021/05/05} +\def\xintbndldate{2021/05/05} +\def\xintbndlversion {1.4e} %</drv> %<readme>% README %<changes>% CHANGE LOG -%<readme|changes>% xint 1.4d -%<readme|changes>% 2021/03/29 +%<readme|changes>% xint 1.4e +%<readme|changes>% 2021/05/05 %<readme|changes> -%<readme|changes> Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29) +%<readme|changes> Source: xint.dtx 1.4e 2021/05/05 (doc 2021/05/05) %<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.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %<xintkernel>%% xintkernel: Paraphernalia for the xint packages %<xinttools>%% xinttools: Expandable and non-expandable utilities @@ -43,8 +43,9 @@ \bgroup\catcode2 0 \catcode`\\ 12 ^^Biffalse %</dtx> %<*readme>-------------------------------------------------------- -Aim and usage -============= + +Description +=========== It is possible to use the package both with Plain (`\input xintexpr.sty`) or with the LaTeX macro format (`\usepackage{xintexpr}`). @@ -52,45 +53,39 @@ or with the LaTeX macro format (`\usepackage{xintexpr}`). The basic aim is provide *expandable* computations on (arbitrarily big) integers, fractions, and floating point numbers (at a user chosen precision). The four operations and the square-root extraction achieve -so-called *correct rounding* for the given arbitrary precision. - -The syntax knows dummy variables, as in this example: - - \xinteval{reduce(add(x/(x+7), x = 1000..1010))} - -which expands to: - - 108959959329292321880648657/9974444716475301992902544 - -Trigonometrical functions are available: - - \xintDigits*:=48\relax - - \xintfloateval{[-2] sind(37)} - -expands to: - - 0.6018150231520482799179770004414898414256377098 - -The [-2] at start of the `\xintfloateval` argument means to round the -result to 2 digits less than the float precision. - -Release `1.4` adds support for nested structures. For example: - - \xintthealign\xintexpr ndseq(1/(i+j), i=1..5; j=1..5)\relax - -will print on the page (this is customizable, e.g. to use a `pmatrix` -environment): - - [[ 1/2, 1/3, 1/4, 1/5, 1/6 ], - [ 1/3, 1/4, 1/5, 1/6, 1/7 ], - [ 1/4, 1/5, 1/6, 1/7, 1/8 ], - [ 1/5, 1/6, 1/7, 1/8, 1/9 ], - [ 1/6, 1/7, 1/8, 1/9, 1/10 ]] - -It is possible to declare "universal functions" (à la NumPy) which will -act itemwise on all leaves of such "arrays". More features are planned -such as providing an interface to algebra of matrices in this framework. +the *correct rounding* for the given arbitrary precision. Exponential +(natural and to the base ten), logarithm (also to the base 10), +fractional powers, direct and inverse trigonometrical functions are +available up to 62 digits of precision. The syntax supports dummy +variables (to generate sequences of values) and nested structures. +Support for user-declared functions and variables is implemented. + +Usage on the command line +========================= + +One can use `xintexpr` as an interactive calculator on the command line. +See the [xintsession](http://ctan.org/pkg/xintsession) package. + + *2^100; + (@_1) 1267650600228229401496703205376 + *cos(1); + (@_2) 0.5403023058681397 + *&fp32 + (./xintlog.sty) (./xinttrig.sty) fp32 mode (log and trig reloaded) + *cos(1); + (@_3) 0.54030230586813971740093660744298 + *3^1000; + (@_4) 1.3220708194808066368904552597521e477 + *&exact + exact mode (floating point evaluations use 32 digits) + *3^1000; + (@_5) 1322070819480806636890455259752144365965422032752148167664920368226828 + 5973467048995407783138506080619639097776968725823559509545821006189118653427252 + 5795367402762022519832080387801477422896484127439040011758861804112894781562309 + 4438061566173054086674490506178125480344405547054397038895817465368254916136220 + 8302685637785822902284163983078878969185564040848989376093732421718463599386955 + 1676501894058810906042608967143886410281435038564874716583201061436613217310276 + 8902855220001 Installation ============ @@ -161,6 +156,93 @@ See `xint.pdf` for contact information. %</readme>-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.4e (2021/05/05)` +---- + +This section might be incomplete at time of release, it will be +extended if need be after the author gets some rest. + +### Breaking changes + + - **xintlog**: `\poormanloghack` now a no-op. + + - **xinttrig**: loading the package does not define left-over variables + holding the values of the inverse factorials used in the sine and + cosine series. + + - **xintexpr**: the output format of `\xinteval`, which uses + `\xintFracToSci,` 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 `d.d...` with always at least one digit + after the decimal mark (possibly `0`) and trailing zeros are trimmed + out. This is the same output format as used for `\xintfloateval`, + apart of course from the fact that the mantissa lengths are not + limited. + + - **xintexpr**: the output format of `\xintfloateval`, which uses + `\xintPFloat`, changed. The `\xintfloatexprPrintOne` macro now + expects to be used with either one or two arguments, the first one + being within brackets not braces. It defaults to `\xintPFloat`. + + - **xintexpr**: when using `\xintieval{[D]...}` optional `[D]` with a + negative `D`, which triggers quantization to a positive power of ten, + the output (if not the zero value) will be an integer with `N=abs(D)` + explicit trailing zeros, not an integer mantissa followed by `eN`. + + - **xintexpr**: `\xinteval` will not compute powers `a^N` exactly if + `N` in absolute value is at least the (rounded) quotient of `10000` + by the number of digits of `a`; it will then use the + logarithm/exponential (in base 10) approach, according to the + prevailing Digits setting. + + - **xintexpr**: `\xintdeffloatvar` now always rounds the assigned value + to the target precision. Formerly, inputs actually involving no + float operations, such as for example `\xintexpr1/20!\relax` (in + contrast to `1/20!`), 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. + + - **xintfrac**:`\xintPFloat` and `\xintFracToSci` behave + differently. The macro `\xintFracToSciE` does not exist anymore, as + `\xintFracToSci` in the case of scientific exponents hands over the + process to `\xintPFloat` (without the rounding to Digits, of course). + + - **xintexpr**: messages sent under `\xintverbosetrue` regime to the + log file do not enclose the variable names in straight double quotes + `"..."` anymore. + +### New features + + - **xintlog**: now working up to `62` digits. The legacy faster + `poormanlog`-based macros are kept for computations with Digits up to + `8`. Fractional powers are now available both in `xinteval` and + `xintfloateval`, per default. + + - **xinttrig**: now working up to `62` digits and with increased + accuracy. Special faster mode at `8` digits or less. + + - **xintexpr**: the constraints on the `\xintexprPrintOne` replacement + macro, which defaults to `\xintFracToSci`, have been much simplified. + + - **xintexpr**: `\xintiexprPrintOne` (defaults to `\xintDecToString`) + + - **xintfrac**: `\xintPFloatE` 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 `e`. + + - **xintfrac**: `\xintDecToStringREZ` + +### Bug fixes + + - **xintfrac**, **xintexpr**: it was not possible to use + `\xinttheDigits` in the right hand side of an `\xintDigits` + assignment. For example: `\xintDigits*:=\numexpr\xinttheDigits+4;`. + This is now allowed, and the same applies to the macro interface, + for example `\xintSetDigits*{\xinttheDigits+4}`. + + `1.4d (2021/03/29)` ---- @@ -169,9 +251,13 @@ See `xint.pdf` for contact information. - `quo()` and `rem()` in `\xintiiexpr/\xintiieval` renamed to `iquo()` and `irem()`. - - the output of `gcd()` and `lcm()` as applied to fractions is now + - The output of `gcd()` and `lcm()` as applied to fractions is now always in lowest terms. + - The log message to report a variable creation (if `\xintverbosetrue`) + does not use (double) quotes anymore around the name. By the way, + quotes were never used for function names. + ### Bug fixes - Ever since `1.3` the `quo()` and `rem()` functions in `\xintexpr` @@ -2660,6 +2746,7 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; \DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}}%δ \DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}}%ξ \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}}%π + \DeclareUnicodeCharacter{2260}{\ensuremath{\neq}}%≠ \fi \usepackage{multicol} @@ -3848,6 +3935,7 @@ pdfpagemode=UseNone,% \node [block, below of=xint] (frac) {\xintfracname}; \node [block, below of=frac, yshift=-.5cm] (expr) {\xintexprname}; \node [block, below right of=expr, yshift=-.5cm, xshift=2.25cm] (polexpr) {\ctanpackage{polexpr}}; + \node [block, below of=polexpr] (session) {rlwrap etex \ctanpackage{xintsession}}; \node [block, below of=expr, yshift=-.5cm] (trig) {\xinttrigname}; \node [block, left of=trig] (log) {\xintlogname}; \node [block, left of=log, xshift=-1cm] (poormanlog) {\ctanpackage{poormanlog}}; @@ -3868,6 +3956,10 @@ pdfpagemode=UseNone,% \path [line,{Stealth[length=5mm]}-{Stealth[length=5mm]}] (expr) -- (log); \path [line,-{Stealth[length=5mm]}] (poormanlog) -- (log); \path [line,-{Stealth[length=5mm]}] (expr) -- (polexpr); + \path [line,-{Stealth[length=5mm]}] (expr) -- (session); + \path [line,-{Stealth[length=5mm]}] (polexpr) -- (session); + \path [line,-{Stealth[length=5mm]}] (trig.south) to [out=-90,in=180] (session.west); + \path [line,-{Stealth[length=5mm]}] (log.south) to [out=-90,in=180] (session.west); \path [line,-{Stealth[length=5mm]}] (frac) to [out=0,in=90] (series.north); \path [line,-{Stealth[length=5mm]}] (frac) to [out=0,in=90] (cfrac.north); \path [line,dashed,-{Stealth[length=5mm]}] (binhex.south) -- (expr); @@ -3921,14 +4013,18 @@ pdfpagemode=UseNone,% \etocsetnexttocdepth{section} \localtableofcontents -\section {Start here} +\section {Usage} \begin{itemize} \item To use with |etex|, |pdftex|, ..., i.e. with \TeX{} engines activating the e\TeX{} extensions: \begin{everbatim} \input xintexpr.sty -\xinteval{sqrt(13, 60)}% get it with 60 digits (correctly rounded) +\xintfloateval{sqrt(13), cos(1), exp(13.3)}% uses 16 digits per default +\xintDigits*:=32;% reload log and trig libraries +\xintfloateval{sqrt(13), cos(1), exp(13.3)}% now with 32 digits +\xinteval{2^1000}% exact computations +\xinteval{reduce(add(1/i, i=1..50))}% dummy variables \end{everbatim} \item To use with the \LaTeX{} macro layer (|latex|, |pdflatex|, ...): \begin{everbatim} @@ -3940,34 +4036,58 @@ pdfpagemode=UseNone,% \end{itemize} \xintexprname is a package to do expandable computations, either exactly -(i.e.\@ with fractions) or in -the sense of floating point numbers at an arbitrary (reasonable% -% -\footnote{Trigonometrical functions are currently supported only up to about - \dtt{58} decimal digits, and generally speaking expansion starts taking - really too much time at about \dtt{500} digits. It looks as if \dtt{100} - digits is a reasonable upper limit for floating point (this is already a lot - to fit on one single line of text) and future development of the package - will not attempt to support floating point calculations efficiently beyond - that limit.}% -) precision. It supports user definition of variables and functions. Its -interface allows multiple comma separated expressions and nested structures: -\begin{everbatim*} -\xinteval{1, 2, [3, [4, 5]], 6} -\end{everbatim*}is impressive. No? - - +(i.e.\@ with fractions) with arbitrarily big inputs, or in the sense of +floating point numbers (logarithm, exponential, sine, cosine, ...) up to 62 +digits. -\medskip -I am thinking about providing a console interface (using |rlwrap etex| as -sadly the e-\TeX{} binaries are not linked with the |readline| library) which -would mimick sessions with Maple or Python. +The syntax to modify the precision used for floating point evaluations is +\begin{everbatim} +\xintDigits*:= <Number>; +\end{everbatim} +Use the |*|, else the scientific libraries will not be reloaded. See +\csbxint{Digits}. The current precision is available as \csbxint{theDigits}, +but in this documentation I might be using simply |Digits| to refer to it. -\medskip -For a quick impression of the package abilities, check (not yet, else you will -never come back here) the tables of its built-in -\hyperref[tab:precedences]{operators} and \hyperref[tab:functions]{functions}. +The tables of the built-in +\hyperref[tab:precedences]{operators} and \hyperref[tab:functions]{functions} +will give a quick overview of the available syntax. +The simplest way to test it is to\footnote{I am assuming here Mac OS or Linux, +adapt to your environment} work interactively on the command line +(this feature is available since April 2021): +\begin{everbatim} +rlwrap etex xintsession +[...hit RET once...] + Magic words: `&pause' (or `;'), `&help', `&bye', and toggles + `&exact', `&fp', `&fp16', `&fp24', `&fp32', `&int', `&pol'. + Starting in exact mode (floating point evaluations use 16 digits) +(Please type a command or say `\end') +*2^100; +(@_1) 1267650600228229401496703205376 +*cos(1); +(@_2) 0.5403023058681397 +*&fp32 +(./xintlog.sty) (./xinttrig.sty) fp32 mode (log and trig reloaded) +*cos(1); +(@_3) 0.54030230586813971740093660744298 +*3^1000; +(@_4) 1.3220708194808066368904552597521e477 +*&exact +exact mode (floating point evaluations use 32 digits) +*3^1000; +(@_5) 1322070819480806636890455259752144365965422032752148167664920368226828 +5973467048995407783138506080619639097776968725823559509545821006189118653427252 +5795367402762022519832080387801477422896484127439040011758861804112894781562309 +4438061566173054086674490506178125480344405547054397038895817465368254916136220 +8302685637785822902284163983078878969185564040848989376093732421718463599386955 +1676501894058810906042608967143886410281435038564874716583201061436613217310276 +8902855220001 +*&bye +Did I say something wrong? +Session transcript written on xintsession-210505_11h05.tex +No pages of output. +Transcript written on xintsession.log. +\end{everbatim} \medskip @@ -3985,54 +4105,107 @@ quality of the document). Reports welcome.% \footnote{Thanks to Jürgen Gilg for keeping the author motivated and helping proof-read the documentation.} -\subsection{Known bugs/features at \texttt{1.4d}} +\subsection{Improved support for logarithm, exponential, sine, etc... at + the \texttt{1.4e} release of \texttt{2021/05/05}} -\begin{description} -\item[if(100>0,(100,125),(100,128)) breaks my code:] -% - This is a feature. This is a syntax error, as the comma serves to contatenate - "oples" (see \autoref{oples}), so it is parsed to behave as -\begin{everbatim} - if(100>0,100,125,100,128) -\end{everbatim} - which is an error as \func{if} requires exactly three arguments, not - five. Use: -\begin{everbatim} - if(100>0,[100,125],[100,128]) -\end{everbatim} - which will expand to the "tuple" |[100,125]|. -\item[{\detokenize{\xintdeffunc foo(x):= gcd((x>0)?{[x,125]}{[x,128]});} - creates a broken function:}] -% - Bug. Normally \func{gcd} (and other - multi-arguments functions) work both with open lists of arguments or - bracketed lists ("nutples") and the above syntax would work perfectly fine - in numerical context. But the presence of the \oper{?} breaks in - \csbxint{deffunc} context the flexibility of \func{gcd}. +They are now supported up to \dtt{62} digits and achieve correct rounding at least +in \dtt{99\%} of cases (better than that, in fact, it depends a bit on the +setting of Digits), when Digits is at least \dtt{9}. +See \xintlogname and \xinttrigname. - Currently working alternatives: +For Digits up to \dtt{8}, a special more approximate implementation is used, +and the functions achieve the ``correct rounding'' (particularly at |Digits=8 +or 7|) less often, but are significantly faster than working with \dtt{9} +digits or more. The precision is largely +enough for plots: \begin{everbatim} -\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128])); -\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128)); -\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128])); -\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128}); -\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)}; -\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])}; +\xintDigits*:=8;% do floating point computations at only 8 digits of precision \end{everbatim} - The same problem will arise with an \oper{??} nested inside \func{gcd} or - similar functions, in an \csbxint{deffunc}. -\end{description} +For some more information on the limitations at Digits set to \dtt{8} or less +relative to the logarithm and exponential in particular, refer to the comments +in |sourcexint.pdf| at the start of the \xintlogname chapter. -If the list stops here, it is probably only because I have not tested enough -yet. But it is already mentioned in the \csbxint{deffunc} documentation that -it can not parse currently the entirety of the available purely numerical -syntax, some documented limitations apply. + +\subsection{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 +it is needed to move forward; and as the \TeX\ world does not have a +``pinning'' mechanism like Python's world, the distinction between minor and +major releases is a bit rhetorical. So |1.4e| behaves like a major release. +It is not one because a complete rework of the foundations of floating point +support is needed... + +|1.4e| changes the output format used by \csbxint{eval}, \csbxint{ieval}, and +\csbxint{floateval} (in short all is modified!). + +\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. +\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. + + Notice though that fractions are still not automatically reduced to lowest + terms even on output. I hesitated about this, but when for example the + computation is a large power of an already known to be irreducible fraction, + 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}. + + 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 + of ten) the output does not use scientific notation but is an integer ending + with explicit zeros. + + Nothing was changed to output for the case of a positive |[D]| (i.e.\@ + rounding to |D| figures after decimal point). One now only needs to + configure the new \csbxint{iexprPrintOne} to be \csbxint{DecToStringREZ} in + order for trailing zeros in decimal expansions to get trimmed rather than + there being always exactly |D| figures after decimal point. +\item Fractional powers are now allowed in \csbxint{eval}; powers with integer + exponents are still computed exactly of course, except that if the integer + exponent is \dtt{10000} or more, or if it is is + evaluated that the output will contain more than (about) \dtt{10000} digits + (separately for the numerator and denominator), + then the floating-point branch is taken forcedly. More details on fractional + powers are available in \xintlogname. +\item \csa{poormanloghack} is now a no-op; to use the logarithm, + exponential, and powers based on \ctanpackage{poormanlog}, set Digits to at + most \dtt{8}. Don't forget the |*| in the |\xintDigits*:=8;| syntax. + \item The \csbxint{floatexprPrintOne} macro interface has changed, it is now + to be used with (an expandable) macro either allowing or requiring the + rounding precision to be present as |[P]|, not |{P}|. Its default + is the user level \csbxint{PFloat} whose behaviour has changed. +\end{itemize} + +\begin{framed} + STARTING FROM HERE THE DOCUMENTATION MAY NOT BE UP-TO-DATE AT |1.4e| + RELEASE, IT MAY CONTAIN OBSOLETE INFORMATION +\end{framed} \subsection{Features added since the \texttt{1.4} release} For bugfixes and possibly more details check |CHANGES.html|: \centeredline{|texdoc --list xint|} \begin{itemize} + \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. + %\NewWith{1.4e} + + \item \csbxint{iexprPrintOne} was added, with default + \csbxint{DecToString}.\NewWith{1.4e} + + \item \csbxint{DecToStringREZ} was added.%\NewWith{1.4e} + \item The function \func{zip}. \item The function \func{flat}. @@ -4040,7 +4213,8 @@ For bugfixes and possibly more details check |CHANGES.html|: \item Chaining of \hyperlink{\detokenize{prec-10}}{comparison operators} à la Python (no short-circuit, though) and |l3fp|. - \item \csbxint{PFloatE} to specify like \csbxint{FracToSciE} does for + \item \csbxint{PFloatE} to specify like \csbxint{FracToSciE} (now defunct at + |1.4e|) does for \csbxint{eval} since |1.4| the separator to use between mantissa and exponent in the output of \csbxint{floateval} output. @@ -4053,10 +4227,6 @@ For bugfixes and possibly more details check |CHANGES.html|: the output uses fixed point notation with decimal digits and with |D=0| the output is an integer with no decimal separator; with |D<0| scientific notation is used% -% -\footnote{This was introduced at |1.4a| but due to a bug the |e| was by error of - catcode 12, and \csbxint{FracToSciE} had no effect on it. Fixed at \texttt{1.4b}}% -% ). \item The same applies to the functions \func{trunc} and \func{round}. And @@ -4066,7 +4236,6 @@ For bugfixes and possibly more details check |CHANGES.html|: \item Support by \func{add} and \func{mul} for \keyword{omit}, \keyword{abort} and \func{break}.% % -\footnote{Feature supposedly added at |1.4| but broken there.} \end{itemize} @@ -4117,6 +4286,49 @@ author a few decades to finish absorbing Python/NumPy. \end{itemize} \end{framed} +\subsection{Known bugs/features (last updated at \texttt{1.4d})} + +\begin{description} +\item[if(100>0,(100,125),(100,128)) breaks my code:] +% + This is a feature. This is a syntax error, as the comma serves to contatenate + "oples" (see \autoref{oples}), so it is parsed to behave as +\begin{everbatim} + if(100>0,100,125,100,128) +\end{everbatim} + which is an error as \func{if} requires exactly three arguments, not + five. Use: +\begin{everbatim} + if(100>0,[100,125],[100,128]) +\end{everbatim} + which will expand to the "tuple" |[100,125]|. +\item[{\detokenize{\xintdeffunc foo(x):= gcd((x>0)?{[x,125]}{[x,128]});} + creates a broken function:}] +% + Bug. Normally \func{gcd} (and other + multi-arguments functions) work both with open lists of arguments or + bracketed lists ("nutples") and the above syntax would work perfectly fine + in numerical context. But the presence of the \oper{?} breaks in + \csbxint{deffunc} context the flexibility of \func{gcd}. + + Currently working alternatives: +\begin{everbatim} +\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128])); +\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128)); +\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128])); +\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128}); +\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)}; +\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])}; +\end{everbatim} + The same problem will arise with an \oper{??} nested inside \func{gcd} or + similar functions, in an \csbxint{deffunc}. +\end{description} + +If the list stops here, it is probably only because I have not tested enough +yet. But it is already mentioned in the \csbxint{deffunc} documentation that +it can not parse currently the entirety of the available purely numerical +syntax, some documented limitations apply. + \subsection{License and installation instructions} \label{ssec:install} @@ -4462,20 +4674,6 @@ the output be formatted with such separators. Formatting of numeric output is apart from some minimal facilities such as \csbxint{Frac}, \csbxint{DecToString}, \csbxint{PRaw}, \csbxint{FracToSci} or \csbxint{PFloat} left to user macros or third-party packages% -% -\footnote{For example I hesitated whether to let \csbxint{FracToSciE} be - actually a macro with one mandatory argument as this would give a hook to - customize formatting the scientific exponent. But then, why not also wrap - the mantissa or the denominator in hook macros? and should the |/| or the - decimal separator also be customizable? It was reasonable to provide a way - to use |E| in place of |e| for the scientific part, as |E| is accepted input - in \csbxint{eval} or \csbxint{floateval}. - % It is already possible for the no-argument macro \csbxint{FracToSciE} to - % probe the sign of the exponent and for example insert a |+| if desired, - % although there is no way (the exponent having no known delimiter) for it to - % act globally on the exponent. - It looked however better to leave additional - formatting to external utilities.}. \begin{everbatim*} \xinteval{123_456_789_012^5} \end{everbatim*} @@ -4744,19 +4942,22 @@ l.c.m.=\xintthealign\xintiiexpr ndmap(lcm, 1..12; 1..10)\relax \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:\kern-2pt +\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 -\def\xintFracToSciE{e} +\let\xintiexprPrintOne\xintDecToString \def\xintiiexprPrintOne #1{#1} -\def\xintfloatexprPrintOne#1#2{\xintPFloat[#1]{#2}} +\let\xintfloatexprPrintOne\xintPFloat \def\xintPFloatE{e} \def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} \end{everbatim} @@ -4766,15 +4967,23 @@ 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} must understand both the raw \xintfracname format |A/B[N]| -and the decimal format |A.ddddd..dd|.% +\csbxint{PFloat} should understand the raw \xintfracname format |A/B[N]|, with +the |/B| and |[N]| parts being optional.% % -\footnote{Furthermore \csbxint{ieval}|{[D]...}| with a \emph{negative} |D| - (feature added at |1.4a|) relies on the \csbxint{exprPrintOne} ability to - react to a catcode 12 |e| (it is always used with detokenized - input). \csbxint{FracToSci} has this ability and uses catcode 11 |e| in - output (or rather whatever \csbxint{FracToSciE} expands to).} +\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. @@ -5101,7 +5310,6 @@ precedence, use parentheses for disambiguation. \xintifboolexpr{1<=2!=3<4>1}{true}{\error}, \xintifboolexpr{1<=2>=3<4>1}{\error}{false} \end{everbatim*} - \precdesc{8} \begin{description} \operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if @@ -5226,7 +5434,7 @@ atan2, atan2d, binomial, bool, ceil, cos, cosd, cot, cotd, cotg, csc, cscd, divmod, even, exp, -factorial, first, flat, float, float\string_, floor, frac, gcd, +factorial, first, flat, float, float\string_dgt, floor, frac, gcd, if, ifint, ifone, ifsgn, ilog10, iquo, irem, isint, isone, iter, iterr, inv, last, lcm, len, log, log10, max, min, mod, mul, ndmap, ndseq, ndfillraw, @@ -5510,11 +5718,13 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax length equal to the float precision). For example |qfloat(2[20])| would keep internally the input format. - \funcdesc{float\string_} is like \func{float} but does not accept the latter - second optional argument.\NewWith{1.4} This is provided as a utility to - speed-up things in some contexts, particularly when converting function - definitions done via \csbxint{deffunc} (see explanations there) to - functions usable in \csbxint{floateval}. + \funcdesc{float\string_dgt} is like \func{float} and avoids \func{float}'s + check whether it used with its second optional argument. This is useful + in the context of converting function definitions done via + \csbxint{deffunc} (see explanations there) to functions usable in + \csbxint{floateval}.\NewWith{1.4} + + Breaking change at |1.4e|: formerly the name was |float_()|.\CHANGED{1.4e} \funcdesc{nuple} is currently same as |[...]|.\DNU{(1.4)} Reserved for possible alternative meaning in future. @@ -5724,7 +5934,6 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax a random integer |A <= x < B|. As in Python it is an «empty range» error in first case if |A| is zero or negative and in second case if |B <= A|. - Attention that the arguments are first converted to integers using \csbxint{Num} (i.e. truncated towards zero). @@ -5808,7 +6017,8 @@ mod(11/7,1/13)- (11/7)/:(1/13), (11/7)//(1/13)\relax\newline precision. The quotient is like in the other parsers an exact integer. It will be rounded as soon as it is used in further operations, or via the global output routine of |\xintfloatexpr|. \emph{Those examples behave as in |1.3f| - because assignments to multiple variables tacitly unpack if this is necessary.} + because assignments to multiple variables tacitly unpack if this is + necessary.} \begin{everbatim*} \xintdefvar Q, R := divmod(3.7, 1.2);% \xinttheexpr Q, R, 1.2Q + R\relax\newline @@ -5820,7 +6030,6 @@ mod(11/7,1/13)- (11/7)/:(1/13), (11/7)//(1/13)\relax\newline \xinttheiiexpr Q\relax\ (we see it has more than 16 digits)\par \xintunassignvar{Q}\xintunassignvar{R}% \end{everbatim*} - Again: |f//g| or the first item output by |divmod(f, g)| is an integer |q| which when computed inside |\xintfloatexpr..\relax| is not yet rounded to the prevailing float precision; the second item |f-q*g| is the rounding to @@ -6755,21 +6964,40 @@ freely either with \csa{xintexpr} or \csa{xintfloatexpr} but not with \csa{xintiiexpr}, and variables defined via \csa{xintdefiivar} can be used in all parsers. -When defining a variable with \csa{xintdeffloatvar}, it is important to know -that the rounding to \csbxint{theDigits} digits of precision happens inside -\csa{xintfloatexpr} only if an operation is executed. Thus, for a declaration -using no operations (and \emph{only} for them), the value is recorded with all -its digits preserved. If \csbxint{theDigits} changes afterwards, the variable -will be rounded to that precision only at time of use. +When defining a variable with \csa{xintdeffloatvar}\CHANGED{1.4e} it (or +generally speaking its numerical leaves) is rounded to \csbxint{theDigits} +precision. So the variable holds the same value as would be printed via +\csbxint{floateval} for the same computation. + +Prior to |1.4e|, this was the case only if the variable definition actually +involved some computation. + +The \csbxint{floatexpr}|..\relax| wrapper by itself induces no rounding. If +it is encountered in the typesetting flow, the print-out will be rounded to +\csbxint{theDigits} precision, but this is an effet of behaving like +\csbxint{floateval} in this context. But in itself, rounding happens only if +the expression involves operations; it will then be to the extended precision +decided by the extra guard digits (default: 2).\NewWith{1.4e} \begin{everbatim*} +% Since 1.4e, \xintdeffloatvar always rounds (to \xinttheDigits) \xintdeffloatvar e:=2.7182818284590452353602874713526624977572470936999595749669676;% -\xintexpr e\relax\newline % shows the recorded value -\xintfloatexpr e\relax\newline % typesetter rounds on output -\xintexpr \xintfloatexpr e\relax\relax\newline % here we see all digits again -\xintexpr \xintfloatexpr [16]e\relax\relax\newline % this forces rounding -\xintexpr \xintfloatexpr 0+e\relax\relax\newline % rounding here done by addition -\xintexpr float(e)\relax\newline % one more way to force rounding -\xintifboolfloatexpr{e == e+0}{\error}{Different! Comparisons do not pre-round.}\par +1) \xintexpr e\relax\newline % shows the recorded value: it is rounded +\xintunassignvar{e} +2) \xintfloatexpr % when used in typesetting flow, acts like \xintfloateval: + 2.7182818284590452353602874713526624977572470936999595749669676 +\relax\newline % the print-out is rounded. +3) \xintexpr + \xintfloatexpr + 2.7182818284590452353602874713526624977572470936999595749669676 + \relax +\relax\newline % but we can see via the \xintexpr wrapper all the digits were there +% rounding can be forced using an extra 0+, the float() function, or the [D] option. +% tidbit: comparison operators do not pre-round, so 1.2345678 is not same as (1.2345678+0) +% in low precision. +\begingroup\xintDigits:=4;% with 2 guard digits, this makes 4+2=6 digits from "0+" rounding +4) \xintifboolfloatexpr{1.2345678 == 1.2345678+0} + {\error}{Different! Comparisons do not pre-round.}\par +\endgroup \end{everbatim*} % not so exciting example @@ -6789,29 +7017,33 @@ will be rounded to that precision only at time of use. % \xintthefloatexpr e, e^1000, e^1000000\relax (e rounded to 16 digits first)\par % \end{everbatim*} -With \csbxint{verbosetrue} the values of the assigned variables will be written -to the log. For example like this (the line numbers here are artificial): +After issuing \csbxint{verbosetrue} the values of defined variables are +written out to the log (and terminal). As in this example: \begin{everbatim} Package xintexpr Info: (on line 1) - Variable "myPi" defined with value {3141592653589793238462643[-24]}. + Variable myPi defined with value {3141592653589793238462643[-24]}. Package xintexpr Info: (on line 2) - Variable "x_1" defined with value {10}. + Variable x_1 defined with value {10}. Package xintexpr Info: (on line 2) - Variable "x_2" defined with value {20}. + Variable x_2 defined with value {20}. Package xintexpr Info: (on line 2) - Variable "x_3" defined with value {30}. + Variable x_3 defined with value {30}. Package xintexpr Info: (on line 3) - Variable "List" defined with value {0}{1}{3}{6}{10}{15}{21}{28}{36}{45}{55} + Variable List defined with value {0}{1}{3}{6}{10}{15}{21}{28}{36}{45}{55} . Package xintexpr Info: (on line 4) - Variable "Nuple" defined with value {{0}{1}{9}{36}{100}{225}{441}{784}{1296 + Variable Nuple defined with value {{0}{1}{9}{36}{100}{225}{441}{784}{1296 }{2025}{3025}}. Package xintexpr Info: (on line 5) - Variable "FourthPowers" defined with value {{0}{1}{81}{1296}{10000}{50625}{ + Variable FourthPowers defined with value {{0}{1}{81}{1296}{10000}{50625}{ 194481}{614656}{1679616}{4100625}{9150625}}. \end{everbatim} -Prior to |1.4| individual (scalar) values would not have been printed to the -log with the braces. +Prior to |1.4e| variable names\CHANGED{1.4e} were printed within straight +double quotes to the log. But this was not the case for function definitions, +so now quotes have been removed. + +The braces one can see around the numerical values date back to the |1.4| +release. \subsubsection{\csh{xintunassignvar}} @@ -6826,7 +7058,7 @@ different,\IMPORTANT{} as it is synonymous with \csbxint{newdummy}\marg{letter}: the (catcode 11) \meta{letter} recovers or acquires meaning as a dummy variable in the current scope. \begin{everbatim*} -\xintFor #1 in {e_1, e_2, e_3, e_4, e} \do {\xintunassignvar {#1}} +\xintunassignvar{e}% % overwriting a dummy letter \xintdefvar i := 3;% \xinttheiiexpr add(i, i = 1..10)\relax\ ("i" has the fixed value 3)\newline @@ -6959,14 +7191,15 @@ have gained experience in using this interface...): if one wants the expansion to execute in a parser independent way, one can transfer a function with scalar values like this: \begin{everbatim} -\xintdeffloatfunc foo(x) := float_(\xintexpr foo(x)\relax); +\xintdeffloatfunc foo(x) := float_dgt(\xintexpr foo(x)\relax); \end{everbatim} - The \func{float\string_} wrapper\NewWith{1.4} is in order for the float - variant to produce an already-rounded value, possibly speeding-up usage if - used as input for other functions. Notice the final underscore in the name; - it is not mandatory but \func{float} here would mean adding a check for - optional argument hence silly overhead, as this check can only be done at - time of use (as |\xintexpr...\relax| may a priori produce an |ople|). + The \func{float\string_dgt} wrapper\NewWith{1.4} (which was renamed at + |1.4e|) is in order for the float variant to produce an already-rounded + value, possibly speeding-up usage if used as input for other + functions. Using \func{float} here would work the same but the produced + function would incorporate a routine to check (at time of use, because at + time of definition it is impossible to tell what will be the case) if it is + applied to one or two arguments. \item And in the reverse direction one can do: \begin{everbatim} @@ -6979,7 +7212,7 @@ have gained experience in using this interface...): operators to the macros doing the exact operations, not the floating point ones. - The \func{float} above is not mandatory but recommended. The macro + The inner \func{float} above is not mandatory but recommended: the macro associated to the user float function |bar(x)| may use many times its argument |x| and does not worry about rounding it, because its expectation is that it is already rounded; but in \csbxint{expr} that value could very @@ -6990,10 +7223,15 @@ have gained experience in using this interface...): can also use \func{sfloat}, this would serve to nothing for the |19/13| case but would possibly for a short integer input involved in multiplications. - Here it is not needed to use \func{float\string_}, because it will be + Here it is not needed to use \func{float\string_dgt}, because it will be identified at time of definition that \func{float} is used without optional argument. + An external \func{float\string_dgt} could be added but is not a priori + necessary, except perhaps if the |bar()| function has been defined at a low + level using support macros producing output with garbage extra digits, which + usually would be rounded out in input to other float functions. + \end{itemize} @@ -7479,57 +7717,58 @@ The sole macro is \csbxint{reloadxinttrig}. This package was first included in release |1.3e| (|2019/04/05|) of \xintexprname. It is automatically loaded by \xintexprname. +At |1.4e| (|2021/05/05|) the accuracy was significantly increased:\CHANGED{1.4e} formerly +the high-level user interface used to define the functions did not allow +operating with guard digits, so the last two digits were most of the time off +(at least the last digit). Now, some internal changes have fixed this problem +and the accuracy is high. Also it was extended up to \dtt{62} digits.\NewWith{1.4e} + +At \dtt{8} digits a special, faster, mode is used, which is less accurate. But faster. + \textbf{Acknowledgements:} I finally decided to release some such functions under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Söll}, let them both be thanked here. \subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig} -The library is loaded automatically by \xintexprname, thus with the default -value of \csbxint{theDigits} which is \dtt{16}. But it can handle a precision -of up to about \fbox{\dtt{60}} digits (make this \dtt{59} at most for the -inverse functions). For this, execute for example \csbxint{SetDigits*}|{48}|. +The library is loaded automatically by \xintexprname at start-up. It is then +configured for \dtt{16} digits. To work for example with \dtt{48} digits, +execute \csbxint{SetDigits*}|{48}| or \csbxint{Digits*}|:=48;| or +\csbxint{Digits}|:=48;| followed by \csbxint{reloadxinttrig} (but in the latter +case the logarithm, exponential, and power functions will not be updated). -\begin{framed} - Since |1.3f|, the starred variants \csbxint{Digits*}|:=P;| and - \csbxint{SetDigits*}\marg{num. expression} execute \csbxint{reloadxinttrig} - to let the package re-configure itself. +The |*| is mandatory to reload the library, don't forget it.\IMPORTANTf{} - The non-starred variants do not execute \csbxint{reloadxinttrig} (to avoid - adding artificial overhead to existing documents).\IMPORTANTf{} -\end{framed} -Absence of guard digits (whether in the used hard-coded constants or in -passing over values from one auxiliary function to the next) due to high level -(user) interface used for the programming means that the produced values are -definitely expected to be wrong in the last digit or last two digits. I should -actually give some estimate of the actual maximal error in |ulps| unit, but I -have not done the complete analysis for lack of time. - -Final computation results should thus probably be printed via -\csbxint{floateval}|{[-2]....}| in order to strip off (with rounding) the last -two digits, if one does not like seeing those non-meaningful figures in the -last one or two positions (I don't say those last two figures are -\emph{systematically} off). For example, to achieve \dtt{16} digits of -precision one should work with a precision of 18 digits (being careful to have -issued \csbxint{reloadxinttrig}) and round results using -\csbxint{floateval}|{[-2]....}|. - -Another approach is to use \csbxint{ieval}|{[D]...}| for conversion to -a fixed point format. - -In future, lower level coding will probably replace the high-level interface, -or at least the macros produced by the high-level interface will be hacked -into to tell the float macros to work at a somewhat elevated precision. +% Absence of guard digits (whether in the used hard-coded constants or in +% passing over values from one auxiliary function to the next) due to high level +% (user) interface used for the programming means that the produced values are +% definitely expected to be wrong in the last digit or last two digits. I should +% actually give some estimate of the actual maximal error in |ulps| unit, but I +% have not done the complete analysis for lack of time. + +% Final computation results should thus probably be printed via +% \csbxint{floateval}|{[-2]....}| in order to strip off (with rounding) the last +% two digits, if one does not like seeing those non-meaningful figures in the +% last one or two positions (I don't say those last two figures are +% \emph{systematically} off). For example, to achieve \dtt{16} digits of +% precision one should work with a precision of 18 digits (being careful to have +% issued \csbxint{reloadxinttrig}) and round results using +% \csbxint{floateval}|{[-2]....}|. + +% Another approach is to use \csbxint{ieval}|{[D]...}| for conversion to +% a fixed point format. + +% In future, lower level coding will probably replace the high-level interface, +% or at least the macros produced by the high-level interface will be hacked +% into to tell the float macros to work at a somewhat elevated precision. \subsection{Constants} -They are the correct rounding to \csbxint{theDigits} precision of the -mathematically exact ones. Their values get incorporated into the -trigonometrical functions at the time of their definitions during loading or -reloading of the package. They are left free to use, or modified, or -\csbxint{unassignvar}'d, as this will have no impact whatsoever on the -functions. +Their values (with more digits) get incorporated into the trigonometrical +functions at the time of their definitions during loading or reloading of the +package. They are left free to use, or modified, or \csbxint{unassignvar}'d, +as this will have no impact whatsoever on the functions. \begin{description} \vardesc{twoPi} what could that be? @@ -7538,21 +7777,10 @@ functions. \vardesc{Piover2} \vardesc{oneRadian} this is one radian in degrees: $180/\pi$ \vardesc{oneDegree} this is one degree in radian: $\pi/180$ -\vardesc{invfact2} this is $1/2!$ -\vardesc{invfact3} this is $1/3!$ -\item[\dots] -\vardesc{invfact44} this is $1/44!$ \end{description} -For a (very) slight optimization of usage, it is recommended to convert them -to macro form, for example: -\begin{everbatim*} -\edef\oneDegree{\xintfloatexpr oneDegree\relax} -\xintfloateval{sin(37\oneDegree)}\newline -\xintfloateval{sind(37)}\newline -\end{everbatim*} -By the way, the above value differs by |1ulp| from correct rounding of exact -one (which looks \dtt{...520482}79917...), see \autoref{ssec:trignotes}. +Breaking change at |1.4e|:\CHANGED{1.4e} formerly some variables were +defined to hold the inverse factorials. Not anymore. \subsection{Functions} @@ -7631,42 +7859,18 @@ not really needed. It is a oneliner to add them: \begin{everbatim} \xintdeffloatfunc radians(x) := x * oneDegree; \xintdeffloatfunc degrees(x) := x * oneRadian; -\xintdefefunc radians(x) := float_(x * oneDegree); -\xintdefefunc degrees(x) := float_(x * oneRadian); +\xintdeffunc radians(x) := float_dgt(x * oneDegree); +\xintdeffunc degrees(x) := float_dgt(x * oneRadian); \end{everbatim} -The \csbxint{expr}-variants above do an exact multiplication. The -\func{float\string_} explicit rounding is a bit superfluous as anyhow trigonometrical -functions do this initial rounding of their arguments. - -The conversion factors above are without guard digits. Probably better to work -overall with an elevated precision and print final results at a lower -precision. +The \func{float\string_dgt} does a float rounding to \csbxint{theDigits} +precision (recall that |*| is mapped to exact multiplication in +\csbxint{deffunc}). \subsection{Important implementation notes} \label{ssec:trignotes} \begin{itemize} -\item The package is almost entirely implemented using the high level user - interface of \xintexprname, using - \csbxint{deffloatefunc} (merged with \csbxint{deffloatfunc} at |1.4|) (and \csbxint{deffloatvar}), the main two exceptions - being for: - \begin{enumerate}[nolistsep] - \item the range reduction for the |sind()| and |cosd()| functions which - required for optimized efficiency the coding at some more core level. - \item some changes at core level added at |1.3e| to - facilitate the transfer of the defined functions from the float parser to - the exact parser. - \end{enumerate} - Also, to avoid problems if the package is reloaded at a time the user has - used some letter variables as assigned variables, |1.3e| added - \csbxint{ensuredummy} and \csbxint{restorevariable}. -\item It is not possible from this interface to (easily) let the computation - proceed with a temporarily elevated precision (``guard digits''). Expect - thus some errors in the last places; basically one should use the optional - rounding argument of either \csbxint{floateval} or \csbxint{ieval} to reduce - the number of digits of printed values by about two digits, if one - hopes to get correct rounding (most of the time). \item Currently, \xintname is lacking some dedicated internal representation of floats which means that most operations re-parse the digit tokens of their arguments to count them\dots\ this does not contribute to efficiency (you @@ -7674,73 +7878,72 @@ precision. macros look like and get an idea of how many times some rather silly re-counting of mantissa lengths will get done!) \item One should not overwrite some function names which are employed as - auxiliaries: |sin_aux|, |cos_aux|, |sin_|, |cos_|, |sind_|, |cosd_|, - |asin_l|\dots others\dots |asin_a|, |asind_a|, |atan_a|, |atand_a|, - |atan_b|, |atand_b|. If you redefine any one of them, you break the - whole thing. + auxiliaries; refer to |sourcexint.pdf|. \item Floats with large exponents are integers and are multiple of \dtt{1000}; hence modulo \dtt{360} all such ``angles'' are multiple of \dtt{40} degrees. Needless to say that considering usage of the |sind()| and |cosd()| functions with such large float numbers is meaningless. -\item Regarding |sin()| and |cos()|, \xinttrigname converts their argument to - degrees by multiplication by (pre-rounded) $180/\pi$, then does range - reduction modulo $360$ and finally goes back to radians in the appropriate - octants to use usual Taylor series (roughly said). For large floats, the - output value will thus be one of |sind(40n)|, |cosd(40n)|, |n=0..8|. If the - unit in the last place of original variable was for example \dtt{1e9} the - final result means nothing at all: the unit in the last place interval - extends above possibly astronomical numbers of intervals of length $2\pi$. - - This intrinsic problem is not a by-product of conversion problems to and - from degrees, it is an in-built inadequacy of the concept of floating point - numbers to provide meaning to evaluating trigonometrical functions. The - argument should be treated as a uniformly distributed random variable modulo - $2\pi$, and the sine and cosine values should be random variables realizing - the value distribution of these mathematical functions. Clearly this adds - some (rather severe) implementation complications such as deciding how to - make the transition to randomness. Too lazy for that. - - Opting for a random value also raises the question of how to deal with - multiple such evaluations at the same argument in a single expression. I - would argue again that as it is evil to consider meaningless quantities, it - is not a problem if new compilations give different results, or even single - compilation gives different results in various parts of the same formula, - that's the whole point of randomness! As said already, I got too lazy to - consider seriously implementing such a non-standard philosophy, despite its - compelling soundness. -\item Did I say the implementation was done at very high level (for the most - part), hence has ample room for optimization? This is particularly the case - for the handling of small inputs by functions such as sine or arcsine. +\item See |sourcexint.pdf| for some comments on limitations of the range + reduction implementation. +% \item Regarding |sin()| and |cos()|, \xinttrigname converts their argument to +% degrees by multiplication by (pre-rounded) $180/\pi$, then does range +% reduction modulo $360$ and finally goes back to radians in the appropriate +% octants to use usual Taylor series (roughly said). For large floats, the +% output value will thus be one of |sind(40n)|, |cosd(40n)|, |n=0..8|. If the +% unit in the last place of original variable was for example \dtt{1e9} the +% final result means nothing at all: the unit in the last place interval +% extends above possibly astronomical numbers of intervals of length $2\pi$. + +% This intrinsic problem is not a by-product of conversion problems to and +% from degrees, it is an in-built inadequacy of the concept of floating point +% numbers to provide meaning to evaluating trigonometrical functions. The +% argument should be treated as a uniformly distributed random variable modulo +% $2\pi$, and the sine and cosine values should be random variables realizing +% the value distribution of these mathematical functions. Clearly this adds +% some (rather severe) implementation complications such as deciding how to +% make the transition to randomness. Too lazy for that. + +% Opting for a random value also raises the question of how to deal with +% multiple such evaluations at the same argument in a single expression. I +% would argue again that as it is evil to consider meaningless quantities, it +% is not a problem if new compilations give different results, or even single +% compilation gives different results in various parts of the same formula, +% that's the whole point of randomness! As said already, I got too lazy to +% consider seriously implementing such a non-standard philosophy, despite its +% compelling soundness. +% \item Did I say the implementation was done at very high level (for the most +% part), hence has ample room for optimization? This is particularly the case +% for the handling of small inputs by functions such as sine or arcsine. \end{itemize} \subsection{Some example evaluations} \noindent \begin{everbatim*} -\xintDigits* := 50\relax % target 48 digits via 2 guard digits -$sind(17)\approx\xintfloateval{[-2] sind(17)}$\newline -$cosd(17)\approx\xintfloateval{[-2] cosd(17)}$\newline -$tand(17)\approx\xintfloateval{[-2] tand(17)}$\newline -$sind(43)\approx\xintfloateval{[-2] sind(43)}$\newline -$cosd(43)\approx\xintfloateval{[-2] cosd(43)}$\newline -$tand(43)\approx\xintfloateval{[-2] tand(43)}$\newline -$asind(0.3)\approx\xintfloateval{[-2] asind(0.3)}$\newline -$acosd(0.3)\approx\xintfloateval{[-2] acosd(0.3)}$\newline -$atand(3)\approx\xintfloateval{[-2] atand(3)}$\newline -$tan(atan(7))\approx\xintfloateval{[-2] tan(atan(7))}$\newline -$asind(sind(25))\approx\xintfloateval{[-2] asind(sind(25))}$\par\medskip -\noindent\xintDigits* := 26\relax % target 24 digits via 2 guard digits -$sind(17)\approx\xintfloateval{[-2] sind(17)}$\newline -$cosd(17)\approx\xintfloateval{[-2] cosd(17)}$\newline -$tand(17)\approx\xintfloateval{[-2] tand(17)}$\newline -$sind(43)\approx\xintfloateval{[-2] sind(43)}$\newline -$cosd(43)\approx\xintfloateval{[-2] cosd(43)}$\newline -$tand(43)\approx\xintfloateval{[-2] tand(43)}$\newline -$asind(0.3)\approx\xintfloateval{[-2] asind(0.3)}$\newline -$acosd(0.3)\approx\xintfloateval{[-2] acosd(0.3)}$\newline -$atand(3)\approx\xintfloateval{[-2] atand(3)}$\newline -$tan(atan(7))\approx\xintfloateval{[-2] tan(atan(7))}$\newline -$asind(sind(25))\approx\xintfloateval{[-2] asind(sind(25))}$\par +\xintDigits* := 48\relax +$sind(17)\approx\xintfloateval{sind(17)}$\newline +$cosd(17)\approx\xintfloateval{cosd(17)}$\newline +$tand(17)\approx\xintfloateval{tand(17)}$\newline +$sind(43)\approx\xintfloateval{sind(43)}$\newline +$cosd(43)\approx\xintfloateval{cosd(43)}$\newline +$tand(43)\approx\xintfloateval{tand(43)}$\newline +$asind(0.3)\approx\xintfloateval{asind(0.3)}$\newline +$acosd(0.3)\approx\xintfloateval{acosd(0.3)}$\newline +$atand(3)\approx\xintfloateval{atand(3)}$\newline +$tan(atan(7))\approx\xintfloateval{tan(atan(7))}$\newline +$asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par\medskip +\noindent\xintDigits* := 24\relax +$sind(17)\approx\xintfloateval{sind(17)}$\newline +$cosd(17)\approx\xintfloateval{cosd(17)}$\newline +$tand(17)\approx\xintfloateval{tand(17)}$\newline +$sind(43)\approx\xintfloateval{sind(43)}$\newline +$cosd(43)\approx\xintfloateval{cosd(43)}$\newline +$tand(43)\approx\xintfloateval{tand(43)}$\newline +$asind(0.3)\approx\xintfloateval{asind(0.3)}$\newline +$acosd(0.3)\approx\xintfloateval{acosd(0.3)}$\newline +$atand(3)\approx\xintfloateval{atand(3)}$\newline +$tan(atan(7))\approx\xintfloateval{tan(atan(7))}$\newline +$asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par \xintDigits* := 16\relax \end{everbatim*} @@ -7760,68 +7963,137 @@ with \xintexprname. This package was first included in release |1.3e| (|2019/04/05|) of \xintexprname. It is automatically loaded by \xintexprname. -Currently, the functions \func{log10}, \func{pow10}, \func{log}, \func{exp}, -and \func{pow} use at their core two fast expandable macros handling base 10 -logarithms and powers for mantissas of 9 digit tokens. They are -defined by package \ctanpackage{poormanlog} which is -automatically imported. The error is believed to be at most \dtt{2ulp} (see -its |README|). The package \ctanpackage{poormanlog} -has no dependencies and can be imported by any other \TeX\ macro file. +At release |1.4e| (|2021/05/05|) it was substantially extended.\CHANGED{1.4e} +Formerly, the functions \func{log10}, \func{pow10}, \func{log}, \func{exp}, +and \func{pow} used at their core \ctanpackage{poormanlog} which is +automatically imported, this limited the precision to about \dtt{8} accurate +digits, but was fast. -Although the precision is thus limited to about \dtt{8} or \dtt{9} digits this -is amply enough for plots. +With |1.4e|, the |Digits| range is extended up to \dtt{62} +digits. \ctanpackage{poormanlog} is still used as boot-strap for logarithms, +it is not used at all for exponentials. + +At |Digits| set to \dtt{8} or less, the old faster but less accurate macros +based on \ctanpackage{poormanlog} are used. \localtableofcontents -\subsection{\csh{poormanloghack}} -\label{ssec:poormanloghack} +\subsection{\csh{xintreloadxintlog}}\label{xintreloadxintlog} -\begin{description} -\item[\string\poormanloghack\string{**\string}] use it to let the |**| operator be remapped to the - \func{pow} function. -\item[\string\poormanloghack\string{\string^\string}] use it to let the |^| operator be remapped to the - \func{pow} function. -\end{description} -If used, they obey \TeX\ scoping as usual. +The library is loaded automatically by \xintexprname at start-up. +It is then configured for \dtt{16} digits. To work for example with +\dtt{48} digits, execute \csbxint{SetDigits*}|{48}| or \csbxint{Digits*}|:=48;| or +\csbxint{Digits}|:=48;| followed by \csbxint{reloadxintlog} (but in the latter case +the trigonometric functions will not be updated). + +The |*| is mandatory to reload the library, don't forget it.\IMPORTANTf{} + +\subsection{Powers in \texttt{\cs{xinteval}} and \texttt{\cs{xintfloateval}}} + +For powers |a^b| or |a**b| in \csbxint{floateval} the following rules apply: +\begin{enumerate}[noitemsep] +\item a check is made if exponent is integer or half-integer, +\item if this is the case legacy \csbxint{FloatPower} (combined with + \csbxint{FloatSqrt} for half-integer case) + are used to evaluate the power (and |a| can be negative if exponent is + integer), +\item else the power is computed as |pow10(b*log10(a))| (but keeping some + extra digits in intermediate evaluations; in particular |b| is not + float-rounded, but |a| is). +\end{enumerate} +The reason is that the log/exp approach would lose accuracy for very big +exponents, for example as in this computation: \begin{everbatim*} -\begingroup -\poormanloghack{**}\xintfloateval{[8]1.234**5.678}\newline -\poormanloghack{^}\xintfloateval{[8]1.234^5.678}\par -\endgroup +\xintfloateval{1.00000001^184884258895036416}\newline +\xintDigits:=48;%\xintreloadxintlog % not done as log10/pow10 will not be used +\xintfloateval{1.00000001^(12^16)}\newline +\xintDigits:=62;%\xintreloadxintlog % not done as log10/pow10 will not be used +\xintfloateval{1.00000001^(12^16)} +\xintDigits:=16;% \end{everbatim*} -Notice that in \csbxint{floateval} those (equivalent) operators already -natively handle half-integer exponents. Once remapped to the \func{pow} -function they will become less precise than the original ones for half-integer -and integer exponents. +Notes: +\begin{itemize}[noitemsep] +\item in first case we replaced |12^16| by its value, which has \dtt{18} + digits, to avoid it being produced rounded to \dtt{16} digits, +\item as the example shows, the exponent is not pre-rounded (else the first + result would not match the second one at \dtt{48} digits), +\item in second case parentheses are used because so far |^| is + left-associative, but it is planned to let it be right-associative at next + major release, +\item computing the value via |log10()| and |pow10()| support macros would + lead to a less precise value, the last four or five digits in the last + computation would be wrong, due to immensity of exponent: roughly the + package is designed to maintain high accuracy with exponents up to say \dtt{1e10} + but see |sourcexint.pdf| for perhaps accurate comments + (I doubt it, as I have no time for that at this stage). +\end{itemize} + +In \csbxint{eval}, this is about the same but for one difference: integer +exponents will lead to exact computations, as long as: +\begin{itemize} +\item the exponent absolute value is at most \dtt{9999}, +\item it is evaluated a priori, based on the length of the input, that the + output will have at most \dtt{10000} digits (or only a bit more), separately + for numerator and denominator. +\end{itemize} +The check for integralness of exponent is not on its mathematical value +but on its internal representation, for speed. So |6/3| is not recognized as +being an integer exponent in \csbxint{eval}; but in \csbxint{floateval}, the +|6/3| will have been computed and recognized as |2|. Also |2.00| or |200e-2| +is recognized as an integer in both parsers. Similar remarks apply to +half-integer case. + +For |Digits| at most \dtt{8}, this is different: both in \csbxint{eval} and +\csbxint{floateval}, the logarithm/exponential path will apply always, except +for the integer case in \csbxint{eval} which of course still proceeds via exact +evaluations. + +To compute higher powers than |2^9999| or |9^9999| or |99^5000| or |999^3333|, +etc..., use \csbxint{iieval}. See \csbxint{iiPow} for related comments if +you don't want to melt your CPU. + + +\subsubsection{\csh{poormanloghack}} +\label{ssec:poormanloghack} + +It is now a no-op, and will be removed at next major release. \subsection{Functions} -All those functions achieve only about \dtt{8} or \dtt{9} digits of precision. -Notice in particular that the digits beyond the ninth printed by \func{log} -have no significance (here we suppose |1<x<10|), but I did not add the -rounding overhead as it is expected anyhow that the final result will be -appropriately rounded. Notice however that \func{log10} should be seen as -going from floating point to fixed point (in the sense of the number of -fractional digits) and \func{pow10} from fixed point to floating point. +% All those functions achieve only about \dtt{8} or \dtt{9} digits of precision. +% Notice in particular that the digits beyond the ninth printed by \func{log} +% have no significance (here we suppose |1<x<10|), but I did not add the +% rounding overhead as it is expected anyhow that the final result will be +% appropriately rounded. Notice however that \func{log10} should be seen as +% going from floating point to fixed point (in the sense of the number of +% fractional digits) and \func{pow10} from fixed point to floating point. \begin{description} \funcdesc{log10} logarithm in base 10 + \funcdesc{pow10} fractional powers of 10 -\funcdesc{log} natural logarithm via |log10(x)*2.3025850923| formula; only the -first 8 or 9 digits of the output are significant... -\funcdesc{exp} exponential function via |pow10(x*0.434294481903)| formula -\funcdesc[x, y]{pow} computes $x^y$ via the formula |pow10(y*log10(x))| + +\funcdesc{log} natural logarithm + +\funcdesc{exp} exponential function + +\funcdesc[x, y]{pow} computes $x^y$ via the formula |pow10(y*log10(x))|, for +|y| neither an integer nor an half-integer; else its uses either exact +evaluation in \csbxint{eval} for integer exponents (see \csbxint{Pow} for +additional information) or the old \csbxint{FloatPower} and +\csbxint{FloatSqrt} macros in \csbxint{floateval} for integer or half-integer +exponents. \end{description} \begin{everbatim*} -\xintfloateval{[9] log(2), exp(1), pow(2,0.5)} +\xintfloateval{log(2), exp(1), 2^(1/3)} \end{everbatim*} -Notice that the last digit of |log(2)| is not the correctly rounded one... I -did say 9 \textbf{or} 8 digits or precision... The documentation of -\ctanpackage{poormanlog} mentions an error of up -to 2 units in the ninth digit when computing |log10(x)| for |1<x<10| and -|10^x| for |0<x<1|. +% Notice that the last digit of |log(2)| is not the correctly rounded one... I +% did say 9 \textbf{or} 8 digits or precision... The documentation of +% \ctanpackage{poormanlog} mentions an error of up +% to 2 units in the ninth digit when computing |log10(x)| for |1<x<10| and +% |10^x| for |0<x<1|. \clearpage \let\xintlognameUp\undefined @@ -10714,59 +10986,112 @@ 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}, \csh{xintFracToSciE}}\label{xintFracToSci} -\label{xintFracToSciE} +\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 not really part of public interface. It is -a macro used by \csbxint{expr} and \csbxint{iexpr} for output. - -\noindent It\xtype{} is expandable but not \fexpan dable. +\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} -It has specific rules regarding the input format: it expects it argument -(after \fexpan ding it) to \emph{already} be either in raw \xintfracname -format |A/B[N]| (with optional denominator and |[N]| parts) or in decimal -format |A.ddd...ddd|. It does not accept scientific notation as input (or -rather, the |e| in input must be of catcode 12). +\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: +\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|: + \begin{itemize}[noitemsep] + \item if |N| is non-negative, the output is an integer with |N| trailing + zeros, + \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). + \end{itemize} +\end{itemize} +Please note the following: +\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. -Its output uses scientific notation (dropping unit demoninator or zero -exponent -- but not (as alas I have to tell the whole truth) in case input was -itself in scientific notation), except for decimal numbers. The latter pass -through ``as is''. \begin{everbatim*} -\xintFracToSci {\xintRaw{123e10/321e10}}, -\xintFracToSci {\xintRaw{123e9/321e10}}, -\xintFracToSci {\xintIrr{861/123}}, -\xintFracToSci {\xintTrunc{12}{1/3}} +\xintDecToStringREZ{0}, \xintDecToStringREZ{1/2}, \xintDecToStringREZ{0.5000}\newline +\xintDecToStringREZ{1.23456789e5}, \xintDecToStringREZ {1.23456789e-3}\newline +\xintDecToStringREZ{12345e-1}, \xintDecToStringREZ {12345e-2}, \xintDecToStringREZ{12345e-3}\newline +\xintDecToStringREZ{12345e-4}, \xintDecToStringREZ {12345e-5}, \xintDecToStringREZ{12345e-6}\newline +\xintDecToStringREZ{1.234567890000e12}, \xintDecToStringREZ{1.23456000e-5/10}\newline +\xintDecToStringREZ{70/14} % is not reduced to lowest terms \end{everbatim*} -Not being \fexpan dable it can not be used as argument to the other package -macros without being wrapped in |\expanded{...}|. - -\noindent\csa{xintFracToSciE}\NewWith{1.4} says what to use for the scientific -notation, its default definition is -\begin{everbatim} -\def\xintFracToSciE{e} -\end{everbatim} - - \subsection{\csh{xintDecToString}}\label{xintDecToString} -This is\etype{\Ff} a macro tailored for printing decimal numbers. It does not -trim trailing zeros, use |\xintDecToString{\xintREZ{<foo>}}| for that. +\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}. + +It follows the same rules as \csbxint{DecToStringREZ} except that it does not +remove trailing zeros, in fact \csbxint{DecToStringREZ}|{f}| is defined as +\csbxint{DecToString}|{|\csbxint{REZ}|{f}}|. \begin{everbatim*} -\xintDecToString {123456789e5}\newline -\xintDecToString {123456789e-5}\newline -\xintDecToString {12345e-10}\newline -\xintDecToString {12345e-10/123}\newline % leaves the denominator as is -\xintDecToString {1234567890000e-6}\newline % does not trim trailing zeros -\xintDecToString {\xintREZ{1234567890000e-6}}\par % does trim trailing zeros +\xintDecToString{0}, \xintDecToString{1/2}, \xintDecToString{0.5000}\newline +\xintDecToString{1.23456789e5}, \xintDecToString {1.23456789e-3}\newline +\xintDecToString{12345e-1}, \xintDecToString {12345e-2}, \xintDecToString{12345e-3}\newline +\xintDecToString{12345e-4}, \xintDecToString {12345e-5}, \xintDecToString{12345e-6}\newline +\xintDecToString{1.234567890000e12}, \xintDecToString{1.23456000e-5/10}\newline +\xintDecToString{70/14} \end{everbatim*} -Consider it an unstable macro, what it does exactly is yet to be decided. It -is a backport from \href{http://ctan.org/pkg/polexpr}{polexpr}'s -|\PolDecToString|, which has now been made an alias to it. + +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). +\begin{everbatim} +\let\xintexprPrintOne\xintDecToString +\end{everbatim} + +Any replacement 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]|. +\end{itemize} \subsection{\csh{xintTrunc}}\label{xintTrunc} @@ -11334,17 +11659,36 @@ Computes the square\etype{\Ff} of one fraction. \subsection{\csh{xintPow}}\label{xintPow} \csa{xintPow}{|{f}{x}|}:\etype{\Ff\Numf} computes |f^x| with |f| a fraction and -|x| possibly also, but |x| will first get truncated to a (positive or negative) -integer. +|x| possibly also. + +This is the support macro for |a^b| in \csbxint{eval}. +At |1.4e| the macro was extended to allow non-integer exponents (previously +this was the case too, but the non-integer exponent was truncated to an +integer...). +\CHANGED{1.4e} + +A check is done whether the exponent is integer, but this check is not on the +value but on the format. So |4/2| will not be recognized as integer; however +|2.0| will be. + +If the exponent is considered an integer it is then checked if it is less than +\dtt{10000} (in absolute value) and if the output would contain less than +\dtt{10000} digits (separately for numerator and denominator) and only then is +the power computed exactly. + +A check is also done whether the exponent is half-integer. Again this check is +not one the value but on the format, so |2.5| is an half integer, as is +|25e-1|, or |2.50| but |5/2| is not considered an half-integer. If the +exponent is half-integer the power is computed by combining suitably +\csbxint{FloatPower} with a square-root extraction. + +If the exponent is neither an integer nor an half-integer, the power is +computed using logarithm and exponential based approach. + +For relevant details see the code comments of the \xintlogname library in +|sourcexint.pdf|. -The exponent |x| must obey the TeX-bound, but this limit is theoretical, as -\TeX's memory or expansion settings get saturated quite earlier: it is -explained in the documentation of \csbxint{iiPow} that the maximal power of -$2$ computable by \xintname is |2^131072| which has \dtt{39457} digits. -Actually, the pratical range is even smaller due to execution times. -The output will always be in the form |A/B[n]| (even if the exponent -vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}). Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to @@ -11619,23 +11963,42 @@ transitive in the number of kept digits. -\subsection{\csh{xintPFloat}, \csh{xintPFloatE}} +\subsection{\csh{xintPFloat}} \label{xintPFloat} \label{xintPFloatE} |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like \csbxint{Float} but -``pretty-prints'' the output. The macro applies one simple rule: |x.yz...eN| -will drop scientific notation in favor of pure decimal notation if |-5<=N<=5| -(last time I checked Maple® proceeded this way). +``pretty-prints'' the output. -Currently trailing zeros are not trimmed. And if the input vanishes the output -will be \dtt{\xintPFloat{0}} with a decimal mark. Final decision however on -how zero value should be printed is yet to arrive... +This macro was added at |1.1| as a (very primitive) "prettifying printer" for +floating point number, and was basically influenced by Maple. -\csbxint{floateval} applies (via the default definition of -\csbxint{floatexprPrintOne}) this macro to each non-empty leaf of the output -ople. This is done in an |\expanded| context, but the macro is already \fexpan -dable. +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} + +At |1.4e|, there is breaking change\CHANGED{1.4e}. The new rules are: +\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. +\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. \csa{xintPFloatE}\NewWith{1.4b} was added to allow customizing the symbol used on output for separating the significand from the exponent, if @@ -11644,49 +12007,51 @@ this definition: \begin{everbatim} \def\xintPFloatE{e} \end{everbatim} -See in this context \csbxint{FracToSciE} which brings the analogous -customizability to \csbxint{eval}. +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). \begin{everbatim*} -\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% -\string\xintDigits\ at \xinttheDigits +\begin{multicols}2 +\def\test #1{#1${}\to{}$\xintPFloat{#1}}\string\xintDigits\ at \xinttheDigits \begin{itemize}[nosep] \item \test {0} -\item \test {1.234e-7} -\item \test {1.234e-6} -\item \test {1.234e-5} -\item \test {1.234e-4} -\item \test {1.234e-3} -\item \test {1.234e-2} -\item \test {1.234e-1} +\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} -\def\xintPFloatE{E}% test custom separator. Should impact \xintfloateval as well +Change of scientific separator to |E|.\def\xintPFloatE{E}% \begin{itemize}[nosep] -\item \test {1.234e0} -\item \test {1.234e1} -\item \test {1.234e2} -\item \test {1.234e3} -\item \test {1.234e4} -\item \test {1.234e5} -\item \test {1.234e6} -\item \test {1.234e7} +\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} -\endgroup +\end{multicols} \end{everbatim*} -\subsection{\csh{xintFloatE}}\label{xintFloatE} +% \subsection{\csh{xintFloatE}}\label{xintFloatE} +% %! {\small New with |1.097|.} -|\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input -|f| by $10^x$, and -converts it to float format according to the optional first argument or current -value of |\xinttheDigits|. -\begin{everbatim*} -\xintFloatE {1.23e37}{53} -\end{everbatim*} +% |\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input +% |f| by $10^x$, and +% converts it to float format according to the optional first argument or current +% value of |\xinttheDigits|. +% \begin{everbatim*} +% \xintFloatE {1.23e37}{53} +% \end{everbatim*} -There is since |1.4b| an unfortunate proximity in name with \csbxint{PFloatE} -despite the two things having absolutely nothing in common. +% There is since |1.4b| an unfortunate proximity in name with \csbxint{PFloatE} +% despite the two things having absolutely nothing in common. \subsection{\csh{xintFloatAdd}}\label{xintFloatAdd} @@ -11773,73 +12138,79 @@ The argument |f| is first rounded to |P| significant places to give |f'|. The output |Z| is then such that the exact |f'^g| differs from |Z| by an absolute error less than |0.52 ulp(Z)|. -This is the macro which is used for the |^| (or |**|) infix operators in -|\xintthefloatexpr...\relax|. In this context (but not directly with the -macro,) half-integer exponents are allowed. This is handled via an integer power -followed by a square-root extraction. The exponent is first rounded to nearest -integer or half-integer so that the computation never raises errors (except -naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies -with half-integer exponents too. +This is the support macro which is used for the |^| (or |**|) infix operators +in \csbxint{floateval}, but \emph{ONLY for integer or half-integer + exponents}.\CHANGED{1.4e} +Half-integer exponents combine this macro with a square-root extraction. +For some related details see \xintlogname. +The macro itself was \emph{NOT} modified at |1.4e| (contrarily to what +happened with \csbxint{Pow}). -Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always -gets rounded to |P| or \csbxint{theDigits} digits. The distance from |f^g| to -|Z| can be much worse if |g| is very large. Roughly, when |g| is negligible -compared to |10^P|, we get an extra difference of up to about |50g ulp(Z)| -which completely dwarfs the |0.52 ulp(Z)|. Thus, if |f| has strictly more than -|P| digits, then the computation must be done with an elevated working -precision |P'|. For example with |g=1000| we should use |P'=P+6| to achieve a -total error at worst slightly bigger than |0.55 ulp(Z)| after the final -rounding from |P'| to |P| digits to get |Z|. -Examples:% -% -\footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} - package.} -% -\begin{everbatim*} -\np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 -\np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline -\end{everbatim*}% -$2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what -counts is the exponent of the result which, while dangerously close to -$2^{31}$ is not quite there yet. -With expressions: -\begin{everbatim*} -{\xintDigits:=48\relax \np{\xintthefloatexpr 1.1547^(2^35)\relax}} -\end{everbatim*} +When used directly it first rounds the exponent to nearest integer or +half-integer so that the computation never raises errors (except naturally for +negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies with +half-integer exponents too. Notice that this is a bound on the distance from +|f'^g| to |Z|, as |f| always gets rounded to |P| or \csbxint{theDigits} +digits. The distance from |f^g| to |Z| can be much worse if |g| is very +large. Roughly, when |g| is negligible compared to |10^P|, we get an extra +difference of up to about |50g ulp(Z)| which completely dwarfs the |0.52 +ulp(Z)|. Thus, if |f| has strictly more than |P| digits, then the computation +must be done with an elevated working precision |P'|. For example with +|g=1000| we should use |P'=P+6| to achieve a total error at worst slightly +bigger than |0.55 ulp(Z)| after the final rounding from |P'| to |P| digits to +get |Z|. -There is a subtlety here that the |2^35| will be evaluated as a floating point -number but fortunately it only has \dtt{11} digits, hence the final evaluation -is done with a correct exponent. It would have been safer, and also more -efficient to code the above rather as: -\begin{everbatim} -\xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax -\end{everbatim} +% Examples:% +% % +% \footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} +% package.} +% % +% \begin{everbatim*} +% \np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 +% \np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline +% \end{everbatim*}% +% $2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what +% counts is the exponent of the result which, while dangerously close to +% $2^{31}$ is not quite there yet. + +% With expressions: +% \begin{everbatim*} +% {\xintDigits:=48\relax \np{\xintthefloatexpr 1.1547^(2^35)\relax}} +% \end{everbatim*} -Here is an example with -|12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). -\begin{everbatim*} -{\xintDigits:=12\relax \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline -\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline -{\xintDigits:=27\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline -{\xintDigits:=48\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} -\end{everbatim*} +% There is a subtlety here that the |2^35| will be evaluated as a floating point +% number but fortunately it only has \dtt{11} digits, hence the final evaluation +% is done with a correct exponent. It would have been safer, and also more +% efficient to code the above rather as: +% \begin{everbatim} +% \xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax +% \end{everbatim} -There is an important difference between |\xintFloatPower[Q]{X}{Y}| and -|\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done -with |Q| digits or precision,% -% -\footnote{if |X| and |Y| themselves stand for some -floating point macros with arguments, their respective evaluations obey the -precision |\xinttheDigits| or as set optionally in the macro calls -themselves.} -% -whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the -expression proceeds with |\xinttheDigits| digits of precision, and the final -result is then rounded to |Q| digits: thus this makes real sense only if used -with |Q<\xinttheDigits|. +% Here is an example with +% |12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). +% \begin{everbatim*} +% {\xintDigits:=12\relax \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline +% \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline +% {\xintDigits:=27\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline +% {\xintDigits:=48\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} +% \end{everbatim*} + +% There is an important difference between |\xintFloatPower[Q]{X}{Y}| and +% |\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done +% with |Q| digits or precision,% +% % +% \footnote{if |X| and |Y| themselves stand for some +% floating point macros with arguments, their respective evaluations obey the +% precision |\xinttheDigits| or as set optionally in the macro calls +% themselves.} +% % +% whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the +% expression proceeds with |\xinttheDigits| digits of precision, and the final +% result is then rounded to |Q| digits: thus this makes real sense only if used +% with |Q<\xinttheDigits|. \subsection{\csh{xintFloatSqrt}}\label{xintFloatSqrt} @@ -18211,6 +18582,10 @@ Please refer to |CHANGES.html| for a (very) detailed history. \url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}} \begin{itemize} +\item Release |1.4e| of |2021/05/05|: logarithms and exponentials up to 62 + digits, trigonometry still mainly done at high level but with guard digits + so all digits up to the last one included can be trusted for faithful + rounding and high probability of correct rounding. \item Release |1.4| of |2020/01/31|: \xintexprnameimp overhaul to use |\expanded| based expansion control. Many new features, in particular support for input and output of nested structures. Breaking changes, main @@ -18301,7 +18676,7 @@ math shift catcode. %\let<*xintkernel>\gardesinactifs %</dtx>^^A-------------------------------------------------------- %<*xintkernel>^^A------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintkernelnameUp\endcsname % \section {Package \xintkernelnameimp implementation} % \RaisedLabel{sec:kernelimp} @@ -18368,13 +18743,15 @@ math shift catcode. \fi \ifx\z\relax\else\expandafter\z\fi% % \end{macrocode} -% \subsubsection{\csh{XINT_setcatcodes}, \csh{XINT_storecatcodes}, -% \csh{XINT_restorecatcodes_endinput}} +% \subsubsection{\csh{XINTrestorecatcodes}, \csh{XINTsetcatcodes}, +% \csh{XINTrestorecatcodesendinput}} +% \lverb|Renamed at 1.4e without underscores, in connexion with +% easying up reloading process for xintlog.sty and xinttrig.sty.| % \begin{macrocode} \def\PrepareCatcodes {% \endgroup - \def\XINT_restorecatcodes + \def\XINTrestorecatcodes {% takes care of all, to allow more economical code in modules \catcode0=\the\catcode0 % \catcode59=\the\catcode59 % ; xintexpr @@ -18388,7 +18765,7 @@ math shift catcode. \catcode33=\the\catcode33 % ! xintexpr \catcode93=\the\catcode93 % ] -, xintfrac, xintseries, xintcfrac \catcode91=\the\catcode91 % [ -, xintfrac, xintseries, xintcfrac - \catcode36=\the\catcode36 % $ xintgcd only + \catcode36=\the\catcode36 % $ xintgcd only $ \catcode94=\the\catcode94 % ^ \catcode96=\the\catcode96 % ` \catcode47=\the\catcode47 % / @@ -18411,11 +18788,11 @@ math shift catcode. \catcode32=\the\catcode32 % \catcode61=\the\catcode61\relax % = }% - \edef\XINT_restorecatcodes_endinput + \edef\XINTrestorecatcodesendinput {% - \XINT_restorecatcodes\noexpand\endinput % + \XINTrestorecatcodes\noexpand\endinput % }% - \def\XINT_setcatcodes + \def\XINTsetcatcodes {% \catcode61=12 % = \catcode32=10 % space @@ -18453,18 +18830,20 @@ math shift catcode. \catcode0=12 % for \romannumeral`&&@ trick \catcode1=3 % for ultra-safe séparateur &&A }% - \XINT_setcatcodes + \let\XINT_setcatcodes\XINTsetcatcodes + \let\XINT_restorecatcodes\XINTrestorecatcodes + \XINTsetcatcodes }% \PrepareCatcodes % \end{macrocode} % Other modules could possibly be loaded under a different catcode regime. % \begin{macrocode} \def\XINTsetupcatcodes {% for use by other modules - \edef\XINT_restorecatcodes_endinput + \edef\XINTrestorecatcodesendinput {% - \XINT_restorecatcodes\noexpand\endinput % + \XINTrestorecatcodes\noexpand\endinput % }% - \XINT_setcatcodes + \XINTsetcatcodes }% % \end{macrocode} % \subsection{Package identification} @@ -18486,7 +18865,7 @@ math shift catcode. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2021/03/29 v1.4d Paraphernalia for the xint packages (JFB)]% + [2021/05/05 v1.4e Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -18611,7 +18990,7 @@ math shift catcode. \long\def\xint_gob_til_xint:#1\xint:{}% \long\def\xint_gob_til_^#1^{}% \def\xint_bracedstopper{\xint:}% -\long\def\xint_gob_til_exclam #1!{}% documenter le catcode de ! ici +\long\def\xint_gob_til_exclam #1!{}% This ! has catcode 12 \long\def\xint_gob_til_sc #1;{}% % \end{macrocode} % \subsection{\csh{xint_afterfi}} @@ -19196,7 +19575,7 @@ math shift catcode. % \end{macrocode} % \begin{macrocode} \lowercase{\endgroup\XINT_expandableerror$\xint/\let\xint/\xint_undefined}% $ -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintkernel} % \cleardoublepage\let\xintkernelnameUp\undefined @@ -19205,7 +19584,7 @@ math shift catcode. %\let<*xinttools>\gardesinactifs %</xintkernel>^^A------------------------------------------------- %<*xinttools>^^A-------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xinttoolsnameUp\endcsname % \section{Package \xinttoolsnameimp implementation} % \RaisedLabel{sec:toolsimp} @@ -19273,7 +19652,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2021/03/29 v1.4d Expandable and non-expandable utilities (JFB)]% + [2021/05/05 v1.4e 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.| @@ -21532,7 +21911,7 @@ math shift catcode. \let\xintCSVFirstItem\xintFirstItem:f:csv \let\xintCSVLastItem \xintLastItem:f:csv \let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xinttools} % \cleardoublepage\let\xinttoolsnameUp\undefined @@ -21541,7 +21920,7 @@ math shift catcode. %\let<*xintcore>\gardesinactifs %</xinttools>^^A-------------------------------------------------- %<*xintcore>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintcorenameUp\endcsname % \section{Package \xintcorenameimp implementation} % \RaisedLabel{sec:coreimp} @@ -21617,7 +21996,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2021/03/29 v1.4d Expandable arithmetic on big integers (JFB)]% + [2021/05/05 v1.4e 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 @@ -24853,7 +25232,7 @@ math shift catcode. (load xintfrac or use \@backslashchar xintii\xint_gobble_iv#1!)\MessageBreak}% {}% }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintcore} % \cleardoublepage\let\xintcorenameUp\undefined @@ -24862,7 +25241,7 @@ math shift catcode. %\let<*xint>\gardesinactifs %</xintcore>^^A--------------------------------------------------- %<*xint>^^A------------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintnameUp\endcsname % \section{Package \xintnameimp implementation} % \RaisedLabel{sec:xintimp} @@ -24926,7 +25305,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2021/03/29 v1.4d Expandable operations on big integers (JFB)]% + [2021/05/05 v1.4e Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -27418,7 +27797,7 @@ math shift catcode. {No uniformdeviate at engine level, returning 0.} 0% }% \fi -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xint} % \cleardoublepage\let\xintnameUp\undefined @@ -27427,7 +27806,7 @@ math shift catcode. %\let<*xintbinhex>\gardesinactifs %</xint>^^A------------------------------------------------------- %<*xintbinhex>^^A------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintbinhexnameUp\endcsname % \section{Package \xintbinhexnameimp implementation} % \RaisedLabel{sec:binheximp} @@ -27504,7 +27883,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2021/03/29 v1.4d Expandable binary and hexadecimal conversions (JFB)]% + [2021/05/05 v1.4e Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb|1.2n switches to \csname-governed expansion at various places.| @@ -28069,7 +28448,7 @@ math shift catcode. }% \def\XINT_chtb_N {\expandafter-\romannumeral0\XINT_chtb_main }% \def\XINT_chtb_main {\csname space\csname\XINT_htb_loop}% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintbinhex} % \cleardoublepage\let\xintbinhexnameUp\undefined @@ -28078,7 +28457,7 @@ math shift catcode. %\let<*xintgcd>\gardesinactifs %</xintbinhex>^^A------------------------------------------------- %<*xintgcd>^^A---------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintgcdnameUp\endcsname % \section{Package \xintgcdnameimp implementation} % \RaisedLabel{sec:gcdimp} @@ -28176,7 +28555,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2021/03/29 v1.4d Euclide algorithm with xint package (JFB)]% + [2021/05/05 v1.4e Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintBezout}} % \lverb|& @@ -28701,7 +29080,7 @@ math shift catcode. \par \endgroup }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintgcd} % \cleardoublepage\let\xintgcdnameUp\undefined @@ -28710,7 +29089,7 @@ math shift catcode. %\let<*xintfrac>\gardesinactifs %</xintgcd>^^A---------------------------------------------------- %<*xintfrac>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintfracnameUp\endcsname % \section{Package \xintfracnameimp implementation} % \RaisedLabel{sec:fracimp} @@ -28776,7 +29155,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2021/03/29 v1.4d Expandable operations on fractions (JFB)]% + [2021/05/05 v1.4e 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 @@ -29271,7 +29650,7 @@ math shift catcode. % \end{macrocode} % \subsection{\csh{xintiLogTen}} % \lverb|& -% New at 1.3e +% New at 1.3e. The exponent a, such that 10^a<= abs(x) < 10^(a+1). % | % \begin{macrocode} \def\xintiLogTen {\the\numexpr\xintilogten}% @@ -29336,18 +29715,13 @@ math shift catcode. }% % \end{macrocode} % \subsection{\csh{xintSPRaw}} -% \lverb|This private macro was for usage by \xinttheexpr. It got moved here +% \lverb|This private macro was for internal usage by \xinttheexpr. +% It got moved here % at 1.4 and is not used anymore by the package. % -% Attention that \xintSPRaw assumed that if the number has no [N] -% part it did not have a fraction part /B either. Indeed this was -% the case always with 1.3f: parsing of an integer by \xintexpr -% does not add the [0] as the code is shared with \xintiiexpr, -% and when there was /B \xintexpr always added postfix [0]; even qfrac() -% parses via \xintRaw; and reduce() internally used \xintIrr -% which outputs A/B but it added [0]. +% It checks if input has a [N] part, if yes uses \xintPRaw, else +% simply lets the input pass through as is. % | -% % \begin{macrocode} \def\xintSPRaw {\romannumeral0\xintspraw }% \def\xintspraw #1{\expandafter\XINT_spraw\romannumeral`&&@#1[\W]}% @@ -29355,97 +29729,94 @@ math shift catcode. \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% % \end{macrocode} -% \subsection{\csh{xintFracToSci}, \csh{xintFracToSciE}} -% \lverb|1.4 +% \subsection{\csh{xintFracToSci}} +% \lverb|1.4, refactored and much simplified at 1.4e. % -% This is the new macro used in place of \xintSPRaw (which basically was -% \xintPRaw) by \xintexpr typesetter. Attention that it is also used by -% \xintiexpr with inputs having being already converted to decimal form, hence -% must understand this input form. This means it must for example not think -% 0.123 is 0 because it starts with 0. +% It only needs to be x-expandable, and indeed the implementation here is only +% x-expandable. % -% And indeed the code here lets 0.123 go through as is. Identification of 0 as -% first digit is done only in case of A[N], A/B, and A/B[N] formats. +% (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. % -% As reduce() does not anymore append the [0] at 1.4, \xintFracToSci has -% indeed to recognize A, A[N], A/B and A/B[N] but does not have to parse -% multiple plus or minus signs or scientific part etc like \xintRaw does -% (delegating to \XINT_infrac like all other xintfrac macros). It has to -% identify say 0/5 (although I don't think that can arise) and -0 is never -% occuring. +% 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: % -% The difference with \xintSPRaw is that it outputs AeN/B. It will not print -% the /B if B=1 and eN if N is zero. -% -% If input is empty \xintFracToSci output is also empty, whereas \xintRaw -% produces 0/1[0] out of empty. But \XINTexprprint anyhow has it own special -% routine for empty input. +%( 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 +%) % -% 1.4b extends the macro to intercept scientific notation and thus allow -% customizability of the «e» via \xintFracToSciE. Without this \xintieval with -% a negative optional argument uses «e» in output with no possibility to -% modify it. +% 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 +%) % -% The expansion context from \xinttheexpr, \xinttheiexpr, \xinteval, -% \xintieval is the scope of one \expanded. +% As a result of these last minute 1.4e changes, the \xintFracToSciE is +% removed. % -% Attention indeed that this macro is not f-expandable only x-expandable. % | % % \begin{macrocode} -\edef\xintFracToSci #1% - {\unexpanded{\expandafter\XINT_FracToSci\romannumeral`&&@}#1\string e% - \unexpanded{\Z/\W[\R]}}% +\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% \def\XINT_FracToSci #1/#2#3[#4% {% - \xint_gob_til_W #2\XINT_FracToSci_no\W - \xint_gob_til_R #4\XINT_FracToSci_yesno\R - \XINT_FracToSci_yesyes #1/#2#3[#4% -}% -\def\XINT_FracToSci_no #1\XINT_FracToSci_yesyes #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToSci_nono\R - \XINT_FracToSci_noyes #2[#3% + \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% }% -\edef\XINT_tmpa{##1\string e##2}% -\def\XINT_tmpb{\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes}% -\expandafter -\XINT_tmpb\XINT_tmpa +\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% {% - #1\xint_gob_til_Z #2\XINT_FracToSci_nonono\Z - \XINT_FracToSci_nonoyes #2% + \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R + \XINT_FracToSci_noslash_N #2[#3% }% -\edef\XINT_tmpa{##1\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_nonoyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]{\xintFracToSciE#1}% -\def\XINT_FracToSci_nonono\Z\XINT_FracToSci_nonoyes\Z/\W[\R]{}% -\edef\XINT_tmpa{##1##2[##3]\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_noyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% +\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% {% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\ifnum #3=\xint_c_\else\xintFracToSciE#3\fi\fi + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1[#2]}% + \fi }% -\edef\XINT_tmpa{##1##2/##3\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% +\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 }% -\edef\XINT_tmpa{##1##2/##3[##4]\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_yesyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% +\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% {% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\ifnum #4=\xint_c_\else\xintFracToSciE#4\fi - \if\XINT_isOne{#3}1\else/#3\fi\fi + \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\xintFracToSciE{e}% % \end{macrocode} % \subsection{\csh{xintRawWithZeros}} % \lverb|& @@ -29497,6 +29868,12 @@ math shift catcode. \xint_orthat{\xintiie{#1}{#3}/#2}% }% % \end{macrocode} +% \subsection{\csh{xintDecToStringREZ}} +% \lverb|1.4e. 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 % decimal exponent. Also sub-efficient if big positive decimal exponent.| @@ -30115,7 +30492,9 @@ math shift catcode. % And the rounding is now done in 1.2 style (with much delay, sorry), like of % the rewritten \xintInc and \xintDec. % -% At 1.4a, first argument can be negative. This is handled at \XINT_trunc_G.| +% At 1.4a, first argument can be negative. This is handled at \XINT_trunc_G. +% +% | % \begin{macrocode} \def\xintRound {\romannumeral0\xintround }% \def\xintiRound {\romannumeral0\xintiround }% @@ -31645,19 +32024,121 @@ math shift catcode. % cost of fetching long sequences of tokens. % \end{framed} % +% \lverb|Changes at 1.4e (done 2021/04/15; undone 2021/04/29) +% +% Macros named \XINTinFloat<name> are not public user-level but were designed +% a long time ago for \xintfloatexpr context as a very preliminary step +% towards attempting to preserve some internal format, here A[N] type. +% +% When <name> is lowercased it means it needs a \romannumeral0 trigger +% (\XINTinfloatS keeps an uppercase S). +% +% Most were coded to check for an optional argument [D], and to use +% D=\XINTdigits in its place if absent but it turned out only \XINTinfloatpow, +% \XINTinfloatmul, \XINTinfloatadd were actually used with an optional +% argument and this happened only in macros from the very old xintseries.sty, +% so I changed all of them to not check for optional argument [D] anymore, +% keeping only some private interface for the xintseries.sty use case. Some +% required being used with [D], some still had names ending in "digits" +% indicating they would use \XINTdigits always. +% +% Indeed basically all algebra is done "exactly" and the [D] governs rules of +% float-rounding on input and output. +% +% During development of 1.4e we fleetingly experimented with letting the value +% used in place of D be \XINTdigitsx to 1.4e, i.e. \XINTdigits with guard +% digits, a situation which was motivated by the implementation of +% trigonometrical functions at high level, i.e. using \xintdeffloatfunc which +% had no mechanism to make intermediate calculations with guard digits. +% +% Simply doing everything "as is" but with 2 guard digits proved very good +% (surprisingly efficient, even) to the trigonometrical functions. However +% using them systematically raises many issues (for example, the correct +% rounding at P digits is destroyed if we obtain it a D=P+2 then round from +% P+2 to P digits so we definitely can not do this as default, so some +% interface is needed to define intermediate functions only using such guard +% digits and keeping them in their output). +% +% Finally, an approach limited to the xinttrig.sty scope was used and I +% removed all \XINTdigitsx related matters from 1.4e. But this left some +% modifications of the interfaces of the "float" macros here which this list +% tries to document, mainly for the author's benefit. +% +%( Macros always using \XINTdigits and now not allowing [P] option +%: \XINTinFloatAdd +%: \XINTinFloatSub +%: \XINTinFloatMul +%: \XINTinFloatSqr +%: \XINTinFloatInv +%: \XINTinFloatDiv +%: \XINTinFloatPow +%: \XINTinFloatPower +%: \XINTinFloatPFactorial +%: \XINTinFloatBinomial +%: +%: Macros which already did not allow [P] option prior to 1.4e refactoring +%: \XINTinFloatFrac (renamed from \XINTinFloatFracdigits) +%: \XINTinFloatE +%: \XINTinFloatMod +%: \XINTinFloatDivFloor +%: \XINTinFloatDivMod +%: +%: Macros requiring a [P]. Some of the "_wopt" named macros are& +% renamings of macros formerly requiring [P]. +%: \XINTinFloat +%: \XINTinFloatS +%: \XINTFloatiLogTen +%: \XINTinRandomFloatS (this one has only the [P] mandatory argument) +%: \XINTinFloatFac +%: \XINTinFloatSqrt +%: \XINTinFloatAdd_wopt, \XINTinfloatadd_wopt +%: \XINTinFloatSub_wopt, \XINTinfloatsub_wopt +%: \XINTinFloatMul_wopt, \XINTinfloatmul_wopt +%: \XINTinFloatSqr_wopt +%: \XINTinfloatpow_wopt (not FloatPow) +%: \XINTinFloatDiv_wopt +%: \XINTinFloatInv_wopt +%: +%: Specially named macros indicating usage of \XINTdigits +%: \XINTinFloatdigits +%: \XINTinFloatSdigits +%: \XINTFloatiLogTendigits +%: \XINTinRandomFloatSdigits +%: \XINTinFloatFacdigits +%: \XINTinFloatSqrtdigits +%) +% | +% % \subsection{\csh{xintDigits}, \csh{xintSetDigits}} % \lverb|& -% 1.3f modifies the (strange) original signature #1#2 for \xintDigits macro -% into #1=, allowing usage -% without colon. It also adds \xintSetDigits. Starred variants are added -% by xintexpr.sty. +% +% 1.3f allows \xintDigits= in place of \xintDigits:= syntax. +% It defines \xintDigits*[:]= which reloads xinttrig.sty. Perhaps this should +% be default, well. +% +% During 1.4e development I added an interface for guard digits, but I decided +% to drop inclusion from 1.4e release because there were pending issues both +% in documentation and functionalities for which I did not have time left. +% +% 1.4e fixes the issue that \xinttheDigits could not be used in the right hand +% side of \xintDigits[*][:]=...; or inside the argument to \xintSetDigits. % | % \begin{macrocode} -\mathchardef\XINTdigits 16 -\def\xintDigits #1=% - {\afterassignment \xint_gobble_i \mathchardef\XINTdigits=}% -\def\xinttheDigits {\number\XINTdigits }% -\def\xintSetDigits #1{\mathchardef\XINTdigits=\numexpr#1\relax}% +\mathchardef\XINTdigits 16 +\chardef\XINTguarddigits 0 +\def\xinttheDigits {\number\XINTdigits}% +%\def\xinttheGuardDigits{\number\XINTguarddigits}% +\def\xinttheGuardDigits{0}% in case used in some of my test files +\def\xintDigits #1={\afterassignment\xintDigits_i\mathchardef\XINT_digits=}% +\def\xintDigits_i#1% +{% + \let\XINTdigits\XINT_digits +}% +\def\xintSetDigits #1% +{% + \mathchardef\XINT_digits=\numexpr#1\relax + \let\XINTdigits=\XINT_digits +}% % \end{macrocode} % % \subsection{\csh{xintFloat}} @@ -31703,7 +32184,7 @@ math shift catcode. % was ok, but printed 1.0...0eN with P-1 zeroes, not 10.0...0e(N-1). % % I decided it was not worth the effort to enhance the algorithm to detect -% with 100$% fiability all cases of rounding up to next +% with 100$% fiability all cases of rounding up to next &$ auctex! % power of ten, hence 1.2k dropped this. % % To avoid duplication of code, and any extra burden on \XINTinFloat, which is @@ -31760,6 +32241,8 @@ math shift catcode. % Since 1.2f, the mantissa always has exactly P digits even in case of % rounding up to next power of ten. This simplifies other routines. % +% (but the zero value must always be checked for, as it outputs 0[0]) +% % 1.2g added a variant \XINTinFloatS which, in case of decimal input with less % than the asked for precision P will not add extra zeros to the mantissa. For % example it may output 2[0] even if P=500, rather than the canonical @@ -31770,7 +32253,7 @@ math shift catcode. % at least the length of mantissa as data. % % Each time \XINTinFloat is called it at least computes a length. Naturally if -% we had some format for floats that would be dispensed of...$newline +% we had some format for floats that would be dispensed of...$newline&$ auctex! % something like % <letterP><length of mantissa>.mantissa.exponent, etc... not yet. % @@ -31778,7 +32261,7 @@ math shift catcode. % is a fraction with very big numerator and denominator. See the discussion of % \xintFloat. % -% 1.3e adds \XINTiLogTen. +% 1.3e adds \XINTFloatiLogTen. % | % \begin{macrocode} \def\XINTinFloat {\romannumeral0\XINTinfloat }% @@ -31812,12 +32295,14 @@ math shift catcode. {\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}% \def\XINT_infloatS_clean_a !#1.{ }% % \end{macrocode} -% \lverb|1.3e ajoute \XINTiLogTen. Le comportement pour un input nul est non -% encore finalisé. Il changera lorsque NaN, +Inf, -Inf existeront.| +% \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 @@ -31849,7 +32334,7 @@ math shift catcode. \fi #3.{#1}{#2}{#4}% }% % \end{macrocode} -% \lverb|Special quick treatment of B=1 case (1.2f then again 1.2g.)$newline +% \lverb|Special quick treatment of B=1 case (1.2f then again 1.2g.)$newline&$ auctex! % maintenant: A.{P}{N}{1} % Il est possible que A soit nul. % | @@ -31872,7 +32357,7 @@ math shift catcode. {\if#1!\expandafter\XINT_infloat_spneg_needzeros\fi -#1}% \def\XINT_infloat_spneg_needzeros -!#1.{!#1.-}% % \end{macrocode} -% \lverb|in: A.{P}{N}{1}$newline +% \lverb|in: A.{P}{N}{1}$newline&$ auctex! % out: P-L.A.P.N.| % \begin{macrocode} \def\XINT_infloat_sppos #1.#2#3#4% @@ -31897,7 +32382,7 @@ math shift catcode. % \begin{macrocode} \def\XINT_infloat_sp_quick 0.#1.#2.#3.{ #1[#3]}% % \end{macrocode} -% \lverb|Ici #1=P-L est >0. L'exposant sera N-(P-L). #2=A. #3=P. #4=N.$newline +% \lverb|Ici #1=P-L est >0. L'exposant sera N-(P-L). #2=A. #3=P. #4=N.$newline&$ auctex! % 18 mars 2016. En fait dans certains contextes il est sous-optimal d'ajouter les % zéros. Par exemple quand c'est appelé par la multiplication ou la division, % c'est idiot de convertir 2 en 200000...00000[-499]. @@ -31906,7 +32391,7 @@ math shift catcode. % \begin{macrocode} \def\XINT_infloat_sp_needzeros #1.#2.#3.#4.{!#1.#2[#4]}% % \end{macrocode} -% \lverb|L-P=#1.A=#2#3.P=#4.N=#5.$newline +% \lverb|L-P=#1.A=#2#3.P=#4.N=#5.$newline&$ % Ici P<L. Il va falloir arrondir. Attention si on va à la puissance de 10 % suivante. En #1 on a L-P qui est >0. L'exposant final sera N+L-P, % sauf dans le cas spécial, il sera alors N+L-P+1. L'ajustement final @@ -31970,7 +32455,7 @@ math shift catcode. #2.#1.{#3}% }% % \end{macrocode} -% \lverb?|A|.P+4.{A}{P}{n}{B}.$newline +% \lverb?|A|.P+4.{A}{P}{n}{B}.$newline&$ % Here A is short. We set u = P+4-|A|, and A''=A (A' = 10^u A) % % output: u.A''..P+4.|A|.{A}{P}{n}{B}? @@ -31981,7 +32466,7 @@ math shift catcode. #3..#2.#1.{#3}% }% % \end{macrocode} -% \lverb?input u.A''.junk.P+4.|A|.{A}{P}{n}{B}$newline +% \lverb?input u.A''.junk.P+4.|A|.{A}{P}{n}{B}$newline&$ % output |B|.P+4.{B}u.A''.P.|A|.n.{A}{B}? % \begin{macrocode} \def\XINT_infloat_MtoN #1.#2.#3.#4.#5.#6#7#8#9% @@ -31998,7 +32483,7 @@ math shift catcode. \fi #1.#2.% }% % \end{macrocode} -% \lverb?input |B|.P+4.{B}u.A''.P.|A|.n.{A}{B}$newline +% \lverb?input |B|.P+4.{B}u.A''.P.|A|.n.{A}{B}$newline&$ % output v=-0.B''.junk.|B|.u.A''.P.|A|.n.{A}{B}? % \begin{macrocode} \def\XINT_infloat_Oa #1.#2.#3% @@ -32063,7 +32548,7 @@ math shift catcode. #2#3#4#5.#1.% }% % \end{macrocode} -% \lverb?trailing digits.Q.P.|B|.|A|.n.{A}{B}$newline +% \lverb?trailing digits.Q.P.|B|.|A|.n.{A}{B}$newline&$ % #1=trailing digits (they may have leading zeros.)? % \begin{macrocode} \def\XINT_infloat_Sa #1.% @@ -32079,7 +32564,7 @@ math shift catcode. \xint_orthat\XINT_infloat_X\xint_c_i }% % \end{macrocode} -% \lverb?epsilon #2=Q.#3=P.#4=|B|.#5=|A|.#6=n.{A}{B}$newline +% \lverb?epsilon #2=Q.#3=P.#4=|B|.#5=|A|.#6=n.{A}{B}$newline&$ % exposant final est n+|A|-|B|-P+epsilon? % \begin{macrocode} \def\XINT_infloat_SEq #1#2.#3.#4.#5.#6.#7#8% @@ -32099,7 +32584,7 @@ math shift catcode. \romannumeral0\xintinc{#2#3}.#2% }% % \end{macrocode} -% \lverb?epsilon Q.P.|B|.|A|.n.{A}{B}$newline +% \lverb?epsilon Q.P.|B|.|A|.n.{A}{B}$newline&$ % % \xintDSH{-x}{U} multiplies U by 10^x. When x is negative, this means % it truncates (i.e. it drops the last -x digits). @@ -32139,31 +32624,62 @@ math shift catcode. \def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}% % \end{macrocode} % \subsection{\csh{xintPFloat}, \csh{xintPFloatE}} -% \lverb|1.1. This is a prettifying printing macro for floats. +% \lverb|& % -% The macro applies one simple rule: x.yz...eN will drop scientific notation in -% favor of pure decimal notation if -5<=N<=5. This is the default behaviour of -% Maple. The N here is as produced on output by \xintFloat. +% xint has not yet incorporated a general formatter as it was +% not a priority during development and external solutions exist +% (I did not check for a while but I think LaTeX3 has implemented +% a general formatter in the printf or Python ".format" spirit) % -% Special case: the zero value is printed 0. (with a dot) +% But when one starts using really the package, especially in +% an interactive way (xintsession 2021), one needs the default +% output to be as nice as possible. +% +% The \xintPFloat macro was added at 1.1 as a "prettifying printer" +% for floats, basically influenced by Maple. +% +%( The rules were: +%: 0. The input is float-rounded to either Digits or the optional argument +%: 1. zero is printed as "0." +%: 2. x.yz...eK is printed "as is" if K>5 or K<-5. +%: 3. if -5<=K<=5, fixed point decimal notation is used. +%: 4. in cases 2. and 3., no trimming of trailing zeroes. +%) % -% The coding got simpler with 1.2k as its \xintFloat always produces -% a mantissa with exactly P digits (no more 10.0...0eN annoying exception). +% 1.4b added \xintPFloatE to customize whether to use +% e or E. % -% 1.4b adds \xintPFloatE allowing to customize whether to use e or E (or -% something else). For usage with \xintfloateval{} (anyhow only catcode 11 e -% is recognized by xintfrac macros proper), and to match similar -% \xintFracToSciE. For reasons commented upon in user manual (section «The -% three parsers»), I did not make an effort to let the macro be usable as a -% hook to grab the exponent. % -% Althout \xintfloateval{} will use \xintPFloat in an \expanded context -% we have to maintain f-expandability here. +% 1.4e, with some hesitation, decided to make a breaking change and to modify +% the behaviour. +% +%( The new rules: +%: 0. The input is float-rounded to either Digits or the optional argument +%: 1. zero is printed as 0.0 +%: 2. x.yz...eK is printed in decimal fixed point if -4<=K<=+5& +% (notice the change, formerly K=-5 used fixed point notation in output)& +% else it is printed in scientific notation +%: 3. trailing zeros of the mantissa are trimmed always +%: 4. in case of decimal fixed point for an integer, there& +% is a trailing ".0" +%: 5. in case of scientific notation with a one-digit trimmed mantissa& +% 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. % % | % \begin{macrocode} -\def\xintPFloat {\romannumeral0\xintpfloat }% +\def\xintPFloat {\romannumeral0\xintpfloat }% \def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint:}% +\def\xintPFloat_wopt +{% + \romannumeral0\expandafter\XINT_pfloat\romannumeral0\XINTinfloatS +}% \def\XINT_pfloat_chkopt #1% {% \ifx [#1\expandafter\XINT_pfloat_opt @@ -32172,76 +32688,78 @@ math shift catcode. }% \def\XINT_pfloat_noopt #1\xint:% {% - \expandafter\XINT_pfloat_a - \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% }% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \def\XINT_pfloat_opt [\xint:#1]% {% - \expandafter\XINT_pfloat_opt_a \the\numexpr #1.% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]% }% -\def\XINT_pfloat_opt_a #1.#2% +\def\XINT_pfloat#1]% {% - \expandafter\XINT_pfloat_a\romannumeral0\xintfloat [#1]{#2};#1.% + \expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1]}% }% -\def\XINT_pfloat_a #1% +\def\XINT_pfloat_fork#1% {% \xint_UDzerominusfork - #1-\XINT_pfloat_zero - 0#1\XINT_pfloat_neg + #1-\XINT_pfloat_zero + 0#1\XINT_pfloat_neg 0-\XINT_pfloat_pos \krof #1% }% +\def\XINT_pfloat_zero#1]{ 0.0}% +\def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos}% +\def\XINT_pfloat_pos#1/1[#2]% +{% + \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.% + #2.#1.% +}% +\def\XINT_pfloat_a #1.#2#3.% +{% + \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% + #2#1.% +}% +\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 #1<\xint_c_ \xint_dothis\XINT_pfloat_N\fi + \if-#2\xint_dothis\XINT_pfloat_P\fi + \xint_orthat\XINT_pfloat_Ps + #1.% +}% % \end{macrocode} % \lverb|& +% #1 is the scientific exponent, #2 is the length of trimmed mantissa. +% +% \xintPFloatE can be replaced by any f-expandable macro with a dot-delimited +% argument. % | % \begin{macrocode} -\def\XINT_pfloat_zero #1;#2.{ 0.}% -\def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos }% -% \end{macrocode} -% \lverb|& -% 1.4b modifies the replacement pattern here #1{#2}{#3} in order to -% facilitate injection of once-expanded \xintPFloatE. -% | -% \begin{macrocode} -\def\XINT_pfloat_pos #1.#2e#3;#4.% +\def\XINT_pfloat_sci #1.#2.% {% - \ifnum #3>\xint_c_v \xint_dothis\XINT_pfloat_no\fi - \ifnum #3<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi - \ifnum #3<\xint_c_ \xint_dothis\XINT_pfloat_N\fi - \ifnum #3>\numexpr #4-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi - \xint_orthat\XINT_pfloat_P #1{#2}{#3}% + \ifnum#2=\xint_c_i\expandafter\XINT_pfloat_sci_i\expandafter\fi + \expandafter\XINT_pfloat_sci_a\romannumeral`&&@\xintPFloatE #1.% }% -\def\XINT_pfloat_no -{% - \expandafter\XINT_pfloat_no_e\expandafter{\xintPFloatE}% -}% -\def\XINT_pfloat_no_e #1#2#3#4{ #2.#3#1#4}% -\def\xintPFloatE{e}% +\def\XINT_pfloat_sci_a #1.#2#3.{ #2.#3#1}% % \end{macrocode} -% \lverb|This is all simpler coded, now that 1.2k's \xintFloat always -% outputs a mantissa with exactly one digits before decimal mark always. -% | +% \lverb|& +% #1#2=\fi\XINT_pfloat_sci_a +% +% 1-digit mantissa, hesitation between d.0eK or deK| % \begin{macrocode} -\def\XINT_pfloat_N #1#2#3% +\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-#3\endcsname #1#2% + \csname XINT_pfloat_N_\romannumeral-#1\endcsname #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_v { 0.0000}% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} -\def\XINT_pfloat_P #1#2#3% +\def\XINT_pfloat_P #1.#2.#3.% {% - \csname XINT_pfloat_P_\romannumeral#3\endcsname #1#2% + \csname XINT_pfloat_P_\romannumeral#1\endcsname #3% }% \def\XINT_pfloat_P_ #1{ #1.}% \def\XINT_pfloat_P_i #1#2{ #1#2.}% @@ -32249,21 +32767,18 @@ math shift catcode. \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|& -% | -% \begin{macrocode} -\def\XINT_pfloat_Ps #1#2#3% +\def\XINT_pfloat_Ps #1.#2.#3.% {% - \csname XINT_pfloat_Ps\romannumeral#3\endcsname #1#200000;% + \csname XINT_pfloat_Ps_\romannumeral#1\endcsname #300000.% }% -\def\XINT_pfloat_Psi #1#2#3;{ #1#2.}% -\def\XINT_pfloat_Psii #1#2#3#4;{ #1#2#3.}% -\def\XINT_pfloat_Psiii#1#2#3#4#5;{ #1#2#3#4.}% -\def\XINT_pfloat_Psiv #1#2#3#4#5#6;{ #1#2#3#4#5.}% -\def\XINT_pfloat_Psv #1#2#3#4#5#6#7;{ #1#2#3#4#5#6.}% +\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{XINTinFloatFracdigits}} +% \subsection{\csh{XINTinFloatFrac}} % \lverb|1.09i, 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 @@ -32274,18 +32789,22 @@ math shift catcode. % % 1.1a renames the macro as \XINTinFloatFracdigits (from \XINTinFloatFrac) to % be synchronous with the \XINTinFloatSqrt and \XINTinFloat habits related to -% \xintNewExpr problems. +% \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.| +% implementation. +% +% 1.4e renames it back to \XINTinFloatFrac because of all such similarly named +% macros also using \XINTdigits forcedly. +% | % \begin{macrocode} -\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% -\def\XINTinfloatfracdigits #1% +\def\XINTinFloatFrac {\romannumeral0\XINTinfloatfrac}% +\def\XINTinfloatfrac #1% {% - \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% + \expandafter\XINT_infloatfrac_a\expandafter {\romannumeral0\xinttfrac{#1}}% }% -\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% +\def\XINT_infloatfrac_a {\XINTinfloat[\XINTdigits]}% % \end{macrocode} % \subsection{\csh{xintFloatAdd}, \csh{XINTinFloatAdd}} % \lverb|First included in release 1.07. @@ -32296,13 +32815,18 @@ math shift catcode. % Which didn't happen until 1.2f. Now, the inputs are first rounded to P % digits, not P+2 as earlier. % +% See general introduction for important changes at 1.4e relative to +% the \XINTinFloat<name> macros. +% % %| % \begin{macrocode} -\def\xintFloatAdd {\romannumeral0\xintfloatadd }% -\def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatAdd {\romannumeral0\XINTinfloatadd }% -\def\XINTinfloatadd #1{\XINT_fladd_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatAdd {\romannumeral0\xintfloatadd}% +\def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatAdd{\romannumeral0\XINTinfloatadd }% +\def\XINTinfloatadd{\XINT_fladd_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatAdd_wopt{\romannumeral0\XINTinfloatadd_wopt}% +\def\XINTinfloatadd_wopt[#1]{\expandafter\XINT_fladd_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_fladd_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fladd_opt @@ -32362,10 +32886,12 @@ math shift catcode. % precision P not P+2.| % % \begin{macrocode} -\def\xintFloatSub {\romannumeral0\xintfloatsub }% -\def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% -\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatSub {\romannumeral0\xintfloatsub}% +\def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSub{\romannumeral0\XINTinfloatsub}% +\def\XINTinfloatsub{\XINT_flsub_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatSub_wopt{\romannumeral0\XINTinfloatsub_wopt}% +\def\XINTinfloatsub_wopt[#1]{\expandafter\XINT_flsub_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flsub_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsub_opt @@ -32401,10 +32927,12 @@ math shift catcode. % 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:}% -\def\XINTinFloatMul {\romannumeral0\XINTinfloatmul }% -\def\XINTinfloatmul #1{\XINT_flmul_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatMul {\romannumeral0\xintfloatmul}% +\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatMul{\romannumeral0\XINTinfloatmul}% +\def\XINTinfloatmul{\XINT_flmul_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatMul_wopt{\romannumeral0\XINTinfloatmul_wopt}% +\def\XINTinfloatmul_wopt[#1]{\expandafter\XINT_flmul_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flmul_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flmul_opt @@ -32435,12 +32963,52 @@ math shift catcode. % \begin{macrocode} \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. +% +% An \XINTinFloatSqr{#1} was defined in xintexpr.sty directly as +% \XINTinFloatMul[\XINTdigits]{#1}{#1}, to support the sqr() function. The +% {#1}{#1} causes no problem as #1 in this context is always pre-expanded so +% we don't need to worry about this, and the \xintdeffloatfunc mechanism +% should hopefully take care to add the needed argument pre-expansion if need +% be. +% +% Anyway let's do this finally properly here. +% | +% \begin{macrocode} +\def\xintFloatSqr {\romannumeral0\xintfloatsqr}% +\def\xintfloatsqr #1{\XINT_flsqr_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSqr{\romannumeral0\XINTinfloatsqr}% +\def\XINTinfloatsqr{\XINT_flsqr_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINT_flsqr_chkopt #1#2% +{% + \ifx [#2\expandafter\XINT_flsqr_opt + \else\expandafter\XINT_flsqr_noopt + \fi #1#2% +}% +\def\XINT_flsqr_noopt #1#2\xint: +{% + #1[\XINTdigits]% + {\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[\XINTdigits]{#2}}% +}% +\def\XINT_flsqr_opt #1[\xint:#2]% +{% + \expandafter\XINT_flsqr_opt_a\the\numexpr #2.#1% +}% +\def\XINT_flsqr_opt_a #1.#2#3% +{% + #2[#1]{\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[#1]{#3}}% +}% +\def\XINT_FL_sqr_a #1[#2]{\xintiiSqr{#1}/1[#2+#2]}% +\def\XINTinFloatSqr_wopt[#1]#2{\XINTinFloatS[#1]{\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[#1]{#2}}}% +% \end{macrocode} % \subsection{\csh{XINTinFloatInv}} % \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.| % \begin{macrocode} \def\XINTinFloatInv#1{\XINTinFloatS[\XINTdigits]{\xintInv{#1}}}% +\def\XINTinFloatInv_wopt[#1]#2{\XINTinFloatS[#1]{\xintInv{#2}}}% % \end{macrocode} % \subsection{\csh{xintFloatDiv}, \csh{XINTinFloatDiv}} % \lverb|1.07. @@ -32458,10 +33026,11 @@ math shift catcode. % multiplication: earlier code was unnecessarily high level. % | % \begin{macrocode} -\def\xintFloatDiv {\romannumeral0\xintfloatdiv }% -\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% -\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatDiv {\romannumeral0\xintfloatdiv}% +\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatDiv{\romannumeral0\XINTinfloatdiv}% +\def\XINTinfloatdiv{\XINT_fldiv_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatDiv_wopt[#1]{\romannumeral0\XINT_fldiv_opt_a#1.\XINTinfloatS}% \def\XINT_fldiv_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fldiv_opt @@ -32516,10 +33085,11 @@ math shift catcode. % % | % \begin{macrocode} -\def\xintFloatPow {\romannumeral0\xintfloatpow}% -\def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPow {\romannumeral0\XINTinfloatpow }% -\def\XINTinfloatpow #1{\XINT_flpow_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatPow {\romannumeral0\xintfloatpow}% +\def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPow{\romannumeral0\XINTinfloatpow }% +\def\XINTinfloatpow{\XINT_flpow_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinfloatpow_wopt[#1]{\expandafter\XINT_flpow_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flpow_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpow_opt @@ -32729,7 +33299,9 @@ math shift catcode. % digits), and then there is the final rounding of this to the target % precision. The total error (for positive as well as negative exponent) has % been estimated to at worst possibly exceed slightly 0.5125 ulp(Z), and at -% any rate it is less than 0.52 ulp(Z).| +% any rate it is less than 0.52 ulp(Z). +% +% | % \begin{macrocode} \def\XINT_flpow_III #1.#2.#3.#4.#5% {% @@ -32753,78 +33325,24 @@ math shift catcode. % % Same modifications as in \xintFloatPow for 1.2f. % -% 1.2f adds a special private macro for allowing half-integral exponents for -% use with ^ within \xintfloatexpr. The exponent will be first truncated to -% either an integer or an half-integer. The macro is not for general use. +% 1.2f \XINTinFloatPowerH (now moved to $xintlognameimp, and renamed). It +% truncated the exponent to an integer of half-integer, and in the latter case +% use Square-root extraction. At 1.2k this was improved as 1.2f stupidly +% 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. % -% 1.2k does anew this 1.2f handling of half-integer exponents for the -% \xintfloatexpr parser: with 1.2f's code -% the final square-root extraction was applied to a value already rounded to -% the target precision, unneedlessly losing precision. +% 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 +% log10() and pow10() support macros, see $xintlognameimp. The code +% has now been relocated there. % | % \begin{macrocode} -\def\xintFloatPower {\romannumeral0\xintfloatpower}% -\def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower }% -\def\XINTinfloatpower #1{\XINT_flpower_chkopt \XINTinfloatS #1\xint:}% -% \end{macrocode} -% \lverb|First the special macro for use by the expression parser which checks -% if one raises to an half-integer exponent. This is always with \XINTdigits -% precision. Rewritten for 1.2k in order for the final square root to keep -% three guard digits. -% -% We have to be careful that exponent #2 is not constrained by TeX bound. And -% we must allow fractions. The 1.2k variant does a rounding to nearest integer -% of half-integer, 1.2f did a truncation rather (this is done after truncation -% of #2 to fixed point with one digit after mark.) We try to recognize quickly -% the case of integer exponent, for speed, but there is overhead of going -% through \xintiTrunc1.| -% \begin{macrocode} -\def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerh }% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} -\def\XINTinfloatpowerh #1#2% -{% - \expandafter\XINT_flpowerh_a\romannumeral0\xintitrunc1{#2};% - \XINTdigits.{#1}{\XINTinfloatS[\XINTdigits]}% -}% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} -\def\XINT_flpowerh_a #1;% -{% - \if0\xintLDg{#1}\expandafter\XINT_flpowerh_int - \else\expandafter\XINT_flpowerh_b - \fi #1.% -}% -\def\XINT_flpowerh_int #1% -{% - \if0#1\expandafter\XINT_flpower_BisZero - \else\expandafter\XINT_flpowerh_i - \fi #1% -}% -\def\XINT_flpowerh_i #10.{\expandafter\XINT_flpower_checkB_a#1.}% -\def\XINT_flpowerh_b #1.% -{% - \expandafter\XINT_flpowerh_c\romannumeral0\xintdsrr{\xintDouble{#1}}.% -}% -\def\XINT_flpowerh_c #1.% -{% - \ifodd\xintLDg{#1} %<- intentional space - \expandafter\XINT_flpowerh_d\else\expandafter\XINT_flpowerh_e - \fi #1.% -}% -\def\XINT_flpowerh_d #1.\XINTdigits.#2#3% -{% - \XINT_flpower_checkB_a #1.\XINTdigits.{#2}\XINT_flpowerh_finish -}% -\def\XINT_flpowerh_finish #1% - {\XINTinfloatS[\XINTdigits]{\XINTinFloatSqrt[\XINTdigits+\xint_c_iii]{#1}}}% -\def\XINT_flpowerh_e #1.% - {\expandafter\XINT_flpower_checkB_a\romannumeral0\xinthalf{#1}.}% +\def\xintFloatPower {\romannumeral0\xintfloatpower}% +\def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPower{\romannumeral0\XINTinfloatpower }% +\def\XINTinfloatpower{\XINT_flpower_opt_a\XINTdigits.\XINTinfloatS}% % \end{macrocode} % \lverb|Start of macro. Check for optional argument.| % \begin{macrocode} @@ -32976,12 +33494,22 @@ math shift catcode. }% % \end{macrocode} % \subsection{\csh{xintFloatFac}, \csh{XINTFloatFac}} -% |Done at 1.2. At 1.3e \XINTinFloatFac outputs using \XINTinFloatS.| +% \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... +% | % \begin{macrocode} -\def\xintFloatFac {\romannumeral0\xintfloatfac}% -\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatFac {\romannumeral0\XINTinfloatfac }% -\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatFac {\romannumeral0\xintfloatfac}% +\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatFac{\romannumeral0\XINTinfloatfac}% +\def\XINTinfloatfac[#1]{\expandafter\XINT_flfac_opt_a\the\numexpr#1.\XINTinfloatS}% +\def\XINTinFloatFacdigits{\romannumeral0\XINT_flfac_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flfac_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flfac_opt @@ -33264,12 +33792,15 @@ math shift catcode. % 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.| +% condition 0<=a<=b<10^8 is violated. Same as for \xintiiPFactorial. +% +% 1.4e extends the precision in floating point context adding some overhead +% but well.| % \begin{macrocode} -\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% -\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPFactorial {\romannumeral0\XINTinfloatpfactorial }% -\def\XINTinfloatpfactorial #1{\XINT_flpfac_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% +\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPFactorial{\romannumeral0\XINTinfloatpfactorial }% +\def\XINTinfloatpfactorial{\XINT_flpfac_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flpfac_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpfac_opt @@ -33285,9 +33816,9 @@ math shift catcode. }% \def\XINT_flpfac_opt #1[\xint:#2]% {% - \expandafter\XINT_flpfac_opt_b\the\numexpr #2.#1% + \expandafter\XINT_flpfac_opt_a\the\numexpr #2.#1% }% -\def\XINT_flpfac_opt_b #1.#2#3#4% +\def\XINT_flpfac_opt_a #1.#2#3#4% {% \expandafter\XINT_FL_pfac_fork \the\numexpr \xintNum{#3}\expandafter.% @@ -33471,12 +34002,17 @@ math shift catcode. % 2016/11/19 for 1.2h. 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.| +% 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:}% -\def\XINTinFloatBinomial {\romannumeral0\XINTinfloatbinomial }% -\def\XINTinfloatbinomial #1{\XINT_flbinom_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% +\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatBinomial{\romannumeral0\XINTinfloatbinomial }% +\def\XINTinfloatbinomial{\XINT_flbinom_opt\XINTinfloatS[\xint:\XINTdigits]}% \def\XINT_flbinom_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flbinom_opt @@ -33562,13 +34098,26 @@ math shift catcode. % 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. +% +% % % | % \begin{macrocode} -\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% -\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% -\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt}% +\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSqrt{\romannumeral0\XINTinfloatsqrt}% +\def\XINTinfloatsqrt[#1]{\expandafter\XINT_flsqrt_opt_a\the\numexpr#1.\XINTinfloatS}% +\def\XINTinFloatSqrtdigits{\romannumeral0\XINT_flsqrt_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flsqrt_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsqrt_opt @@ -33702,9 +34251,9 @@ math shift catcode. % \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, contrarily to -% other \XINTinFloat<foo> macros it inserts itself the [\XINTdigits] thing, -% and with value 0 it produces on output 0[N], not 0[0]. +% +% Attention about \XINTinFloatE: it is for use by xintexpr.sty. +% With input 0 it produces on output an 0[N], not 0[0]. % | % \begin{macrocode} \def\xintFloatE {\romannumeral0\xintfloate }% @@ -33789,8 +34338,7 @@ math shift catcode. % % No time now at the time of completion of the big 1.4 rewrite of xintexpr % to test whether code efficiency here can be improved to expand the second -% item of output. -% | +% item of output.| % \begin{macrocode} \def\XINTinFloatDivMod {\romannumeral0\XINTinfloatdivmod [\XINTdigits]}% \def\XINTinfloatdivmod [#1]#2#3% @@ -33808,7 +34356,7 @@ math shift catcode. % \begin{macrocode} \def\xintifFloatInt {\romannumeral0\xintiffloatint}% \def\xintiffloatint #1{\expandafter\XINT_iffloatint - \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}}% + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}}% \def\XINT_iffloatint #1#2/1[#3]% {% \if 0#1\xint_dothis\xint_stop_atfirstoftwo\fi @@ -33821,25 +34369,35 @@ math shift catcode. % \begin{macrocode} \def\xintFloatIsInt {\romannumeral0\xintfloatisint}% \def\xintfloatisint #1{\expandafter\XINT_iffloatint - \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}10}% + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}10}% % \end{macrocode} -% \subsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSqrtdigits}, -% \csh{XINTinFloatFacdigits}, \csh{XINTiLogTendigits}} -% \lverb|For \xintNewExpr matters, mainly. -% -% At 1.3e I add \XINTinFloatSdigits and use it at various places. I also modified -% \XINTinFloatFac to use S(hort) output format. -% -% Also added \XINTiLogTendigits. +% \subsection{\csh{xintFloatIntType}} +% \lverb|1.4e 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} +\def\xintFloatIntType {\romannumeral`&&@\xintfloatinttype}% +\def\xintfloatinttype #1% +{% + \expandafter\XINT_floatinttype + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}% +}% +\def\XINT_floatinttype #1#2/1[#3]% +{% + \if 0#1\xint_dothis\xint_c_\fi + \ifnum#3<\xint_c_\xint_dothis\xint_c_mone\fi + \ifnum#3>\xint_c_\xint_dothis\xint_c_\fi + \ifodd\xintLDg{#1#2} \xint_dothis\xint_c_i\fi + \xint_orthat\xint_c_ +}% +% \end{macrocode} +% \subsection{\csh{XINTinFloatdigits}, \csh{XINTinFloatSdigits}} +% \lverb|For \xintNewExpr/\xintdeffloatfunc matters, mainly. % -% This whole stuff moved over from xintexpr.sty at 1.4 % | % \begin{macrocode} -\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% -\def\XINTinFloatSdigits {\XINTinFloatS [\XINTdigits]}% -\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}% -\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}% -\def\XINTFloatiLogTendigits{\XINTFloatiLogTen[\XINTdigits]}% +\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% +\def\XINTinFloatSdigits{\XINTinFloatS[\XINTdigits]}% % \end{macrocode} % \subsection{(WIP) \csh{XINTinRandomFloatS}, \csh{XINTinRandomFloatSdigits}} % \lverb|1.3b. Support for random() function. @@ -33867,6 +34425,7 @@ math shift catcode. % in Python (which of course uses radix 2), and indeed this is what happens % there. % +% % | % \begin{macrocode} \def\XINTinRandomFloatS{\romannumeral0\XINTinrandomfloatS}% @@ -33881,7 +34440,8 @@ math shift catcode. \romannumeral0\xintrandomdigits{#1}[-#1]% }% % \end{macrocode} -% \lverb|We add one macro to handle a tiny bit faster 90% of cases, after all +% \lverb|We add one macro to handle a tiny bit faster 90$%&$ +% of cases, after all % we also use one extra macro for the completely improbable all 0 case.| % \begin{macrocode} \def\XINT_inrandomfloatS_a#1% @@ -33906,87 +34466,11 @@ math shift catcode. \romannumeral`&&@\expandafter\XINT_eightrandomdigits \romannumeral`&&@\XINT_eightrandomdigits[-16]% }% -% \end{macrocode} -% \subsection{\csh{PoorManLogBaseTen}} -% \lverb|1.3f. Code originally in poormanlog v0.4 got transferred here. It -% produces the logarithm in base 10 with an error (believed to be at -% most) about 1 unit in the 9th (i.e. last) fractional digit. Testing seems -% to indicate error at most 2 units.| -% \begin{macrocode} -\def\PoorManLogBaseTen{\romannumeral0\poormanlogbaseten}% -\def\poormanlogbaseten #1% - {\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]{#1}}% -\def\PML@logbaseten#1[#2]% -{% - \xintiiadd{\xintDSx{-9}{\the\numexpr#2+8\relax}}{\the\numexpr\PML@#1.}% - [-9]% -}% -% \end{macrocode} -% \subsection{\csh{PoorManPowerOfTen}} -% \lverb|1.3f. Transferred from poormanlog v0.4. Produces the 10^#1 with 9 -% digits of float precision, with an error (believed to be) at most 2 units in -% the last place. Of course for this the input must be precise enough to have -% 9 fractional digits of **fixed point** precision. -% -% Attention that this breaks with low level Number too big error if -% integral part of argument exceeds TeX bound on integers. Indeed some -% \numexpr is used in the code to subtract 8... but anyway xintfrac -% allows for scientific exponents only integers within TeX bounds, so -% even if it did not break here it would quickly elsewhere. -% | -% \begin{macrocode} -\def\PoorManPowerOfTen{\the\numexpr\poormanpoweroften}% -\def\poormanpoweroften #1% - {\expandafter\PML@powoften\romannumeral0\xintraw{#1}}% -\def\PML@powoften#1% -{% - \xint_UDzerominusfork - #1-\PML@powoften@zero - 0#1\PML@powoften@neg - 0-\PML@powoften@pos - \krof #1% -}% -\def\PML@powoften@zero 0{1\relax}%/1[0] -\def\PML@powoften@pos#1[#2]% -{% - \expandafter\PML@powoften@pos@a\romannumeral0\xintround{9}{#1[#2]}.% -}% -\def\PML@powoften@pos@a#1.#2.{\PML@Pa#2.\expandafter[\the\numexpr-8+#1]}% -\def\PML@powoften@neg#1[#2]% -{% - \expandafter\PML@powoften@neg@a\romannumeral0\xintround{9}{#1[#2]}.% -}% -\def\PML@powoften@neg@a#1.#2.% -{\ifnum#2=\xint_c_ \xint_afterfi{1\relax/1[#1]}\else - \expandafter\expandafter\expandafter - \PML@Pa\expandafter\xint_gobble_i\the\numexpr2000000000-#2.% - \expandafter[\the\numexpr-9+#1\expandafter]\fi -}% -% \end{macrocode} -% \subsection{\csh{PoorManPower}} -% \lverb|1.3f. This code originally in poormanlog v0.4 transferred here. It does -% #1 to the power #2.| -% \begin{macrocode} -\def\PoorManPower#1#2% -{% - \PoorManPowerOfTen{\xintMul{#2}{\PoorManLogBaseTen{#1}}}% -}% -% \end{macrocode} -% \subsection{Support macros for natural logarithm and exponential -% \xintexprnameimp functions} -% \lverb|At 1.3f, the poormanlog v0.04 extension to xintfrac.sty got -% transferred here. These macros from xintlog.sty 1.3e got transferred here -% too.| -% \begin{macrocode} -\def\xintLog#1{\xintMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}% -\def\XINTinFloatLog#1{\XINTinFloatMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}% -\def\xintExp#1{\PoorManPowerOfTen{\xintMul{#1}{434294481903[-12]}}}% -\def\XINTinFloatExp#1{\PoorManPowerOfTen{\XINTinFloatMul{#1}{434294481903[-12]}}}% \let\XINTinFloatMaxof\XINT_Maxof \let\XINTinFloatMinof\XINT_Minof \let\XINTinFloatSum\XINT_Sum \let\XINTinFloatPrd\XINT_Prd -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintfrac} % \cleardoublepage\let\xintfracnameUp\undefined @@ -33995,7 +34479,7 @@ math shift catcode. %\let<*xintseries>\gardesinactifs %</xintfrac>^^A--------------------------------------------------- %<*xintseries>^^A------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintseriesnameUp\endcsname % \section{Package \xintseriesnameimp implementation} % \RaisedLabel{sec:seriesimp} @@ -34061,7 +34545,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2021/03/29 v1.4d Expandable partial sums with xint package (JFB)]% + [2021/05/05 v1.4e Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -34369,7 +34853,12 @@ math shift catcode. % \end{macrocode} % \subsection{\csh{xintFloatPowerSeries}} % \lverb|1.08a. I still have to re-visit \xintFxPtPowerSeries; temporarily I -% just adapted the code to the case of floats.| +% just adapted the code to the case of floats. +% +% Usage of new names +% \XINTinfloatpow_wopt \XINTinfloatmul_wopt, \XINTinfloatadd_wopt to track +% xintfrac.sty changes at 1.4e. +% | % \begin{macrocode} \def\xintFloatPowerSeries {\romannumeral0\xintfloatpowerseries }% \def\xintfloatpowerseries #1{\XINT_flpowseries_chkopt #1\xint:}% @@ -34399,7 +34888,7 @@ math shift catcode. \else \xint_afterfi {\expandafter\XINT_flpowseries_loop_pre\expandafter - {\romannumeral0\XINTinfloatpow [#3]{#5}{#1}}% + {\romannumeral0\XINTinfloatpow_wopt[#3]{#5}{#1}}% {#1}{#5}{#2}{#4}{#3}% }% \fi @@ -34409,7 +34898,7 @@ math shift catcode. \ifnum #4>#2 \else\XINT_flpowseries_dont_i \fi \expandafter\XINT_flpowseries_loop_i\expandafter {\the\numexpr #2+\xint_c_i\expandafter}\expandafter - {\romannumeral0\XINTinfloatmul [#6]{#5{#2}}{#1}}% + {\romannumeral0\XINTinfloatmul_wopt[#6]{#5{#2}}{#1}}% {#1}{#3}{#4}{#5}{#6}% }% \def\XINT_flpowseries_dont_i \fi\expandafter\XINT_flpowseries_loop_i @@ -34419,26 +34908,28 @@ math shift catcode. {% \ifnum #5>#1 \else \XINT_flpowseries_exit_i \fi \expandafter\XINT_flpowseries_loop_ii\expandafter - {\romannumeral0\XINTinfloatmul [#7]{#3}{#4}}% + {\romannumeral0\XINTinfloatmul_wopt[#7]{#3}{#4}}% {#1}{#4}{#2}{#5}{#6}{#7}% }% \def\XINT_flpowseries_loop_ii #1#2#3#4#5#6#7% {% \expandafter\XINT_flpowseries_loop_i\expandafter {\the\numexpr #2+\xint_c_i\expandafter}\expandafter - {\romannumeral0\XINTinfloatadd [#7]{#4}% - {\XINTinfloatmul [#7]{#6{#2}}{#1}}}% + {\romannumeral0\XINTinfloatadd_wopt[#7]{#4}% + {\XINTinfloatmul_wopt[#7]{#6{#2}}{#1}}}% {#1}{#3}{#5}{#6}{#7}% }% \def\XINT_flpowseries_exit_i\fi\expandafter\XINT_flpowseries_loop_ii {\fi \expandafter\XINT_flpowseries_exit_ii }% \def\XINT_flpowseries_exit_ii #1#2#3#4#5#6#7% {% - \xintfloatadd [#7]{#4}{\XINTinfloatmul [#7]{#6{#2}}{#1}}% + \xintfloatadd[#7]{#4}{\XINTinfloatmul_wopt[#7]{#6{#2}}{#1}}% }% % \end{macrocode} % \subsection{\csh{xintFloatPowerSeriesX}} -% \lverb|1.08a| +% \lverb|1.08a +% +% See \xintFloatPowerSeries for 1.4e comments.| % \begin{macrocode} \def\xintFloatPowerSeriesX {\romannumeral0\xintfloatpowerseriesx }% \def\xintfloatpowerseriesx #1{\XINT_flpowseriesx_chkopt #1\xint:}% @@ -34475,10 +34966,10 @@ math shift catcode. \def\XINT_flpowseriesx_pre #1#2#3#4#5% {% \expandafter\XINT_flpowseries_loop_pre\expandafter - {\romannumeral0\XINTinfloatpow [#5]{#1}{#2}}% + {\romannumeral0\XINTinfloatpow_wopt[#5]{#1}{#2}}% {#2}{#1}{#3}{#4}{#5}% }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintseries} % \cleardoublepage\let\xintseriesnameUp\undefined @@ -34487,7 +34978,7 @@ math shift catcode. %\let<*xintcfrac>\gardesinactifs %</xintseries>^^A------------------------------------------------- %<*xintcfrac>^^A-------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintcfracnameUp\endcsname % \section{Package \xintcfracnameimp implementation} % \RaisedLabel{sec:cfracimp} @@ -34562,7 +35053,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2021/03/29 v1.4d Expandable continued fractions with xint package (JFB)]% + [2021/05/05 v1.4e Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -35666,7 +36157,7 @@ math shift catcode. \expandafter\XINT_gctgc_end_b }% \def\XINT_gctgc_end_b #1#2#3{ #3{#1}}% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintcfrac} % \cleardoublepage\let\xintcfracnameUp\undefined @@ -35675,7 +36166,7 @@ math shift catcode. %\let<*xintexpr>\gardesinactifs %</xintcfrac>^^A-------------------------------------------------- %<*xintexpr>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintexprnameUp\endcsname % \section{Package \xintexprnameimp implementation} % \RaisedLabel{sec:exprimp} @@ -35954,21 +36445,35 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2021/03/29 v1.4d Expandable expression parser (JFB)]% + [2021/05/05 v1.4e Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% % \end{macrocode} -% \subsection{\csh{xintDigits*}, \csh{xintSetDigits*}} -% \lverb|1.3f| +% \subsection{\csh{xintDigits*}, \csh{xintSetDigits*}, \csh{xintreloadscilibs}} +% \lverb|1.3f. 1.4e added some \xintGuardDigits and \XINTdigitsx mechanism but +% it was finally removed, due to pending issues of user interface, +% functionality, and documentation (the worst part) for whose resolution +% no time was left. +%| % \begin{macrocode} -\def\xintDigits {\futurelet\XINT_token\xintDigitss}% -\def\xintDigitss #1={\afterassignment\xintDigitsss\mathchardef\XINTdigits=}% -\def\xintDigitsss#1{\ifx*\XINT_token\expandafter\xintreloadxinttrig\fi}% +\def\xintreloadscilibs{\xintreloadxintlog\xintreloadxinttrig}% +\def\xintDigits {\futurelet\XINT_token\xintDigits_i}% +\def\xintDigits_i#1={\afterassignment\xintDigits_j\mathchardef\XINT_digits=}% +\def\xintDigits_j#1% +{% + \let\XINTdigits=\XINT_digits + \ifx*\XINT_token\expandafter\xintreloadscilibs\fi +}% \let\xintfracSetDigits\xintSetDigits -\def\xintSetDigits#1#{\if\relax\detokenize{#1}\relax - \else\afterassignment\xintreloadxinttrig\fi - \xintfracSetDigits}% +\def\xintSetDigits#1#{\if\relax\detokenize{#1}\relax\expandafter\xintfracSetDigits + \else\expandafter\xintSetDigits_a\fi}% +\def\xintSetDigits_a#1% +{% + \mathchardef\XINT_digits=\numexpr#1\relax + \let\XINTdigits\XINT_digits + \xintreloadscilibs +}% % \end{macrocode} % \subsection{Support for output and transform of nested braced contents as % core data type} @@ -36130,9 +36635,9 @@ math shift catcode. % will be allowed to transform a number into an ople, the applied macro % is supposed to apply one level of bracing to its ouput. Thus to apply this % with an xintfrac macro such as \xintiRound{0} one needs first to define -% a wrapper which will expand it into braces : +% a wrapper which will expand it inside an added brace pair: % -% \def\foo#1{{\xintiRound{0}{#1}}% +% \def\foo#1{{\xintiRound{0}{#1}}}% % % As the things will expand inside expanded, propagating expansion is not an % issue. @@ -36185,9 +36690,18 @@ math shift catcode. % ATTENTION! 1.3d renamed \xinteval to \xintexpro etc... % % +% Usage of \xintiRound{0} for \xintiexpr without optional [D] means that +% \xintiexpr ... \relax wrapper can be used to insert rounded-to-integers +% values in \xintiiexpr context: no post-fix [0] which would break it. But +% this does not apply to the \xintiexpr [D]...\relax form with negative D. +% +% 1.4a add support for the optional argument [D] for \xintiexpr being negative +% D, with same meaning as the 1.4a modified \xintRound from xintfrac.sty. % -% The 1.4a version of optional argument [D] for \xintiexpr accepts a negative -% D, with same meaning as the 1.4a \xintRound from xintfrac.sty. +% \xintiexpr mechanism was refactored at 1.4e so that rounding due to [D] +% optional argument uses raw format, not fixed point format on output, +% delegating fixed point conversion to an \XINTiexprprint now separated from +% \XINTexprprint. % | % \begin{macrocode} \def\xintexpr {\romannumeral0\xintexpro }% @@ -36209,9 +36723,9 @@ math shift catcode. {% \expandafter\XINT_expr_wrap \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracediRoundzero}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTiRoundzero_braced}% }% -\def\XINTbracediRoundzero#1{{\xintiRound{0}{#1}}}% +\def\XINTiRoundzero_braced#1{{\xintiRound{0}{#1}}}% \def\XINT_iexpr_withopt [#1]% {% \expandafter\XINT_iexpr_round @@ -36225,11 +36739,11 @@ math shift catcode. }% \def\XINT_iexpr_round_a #1.% {% - \expandafter\XINT_expr_wrap + \expandafter\XINT_iexpr_wrap \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracedRound{#1}}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTiRound_braced{#1}}% }% -\def\XINTbracedRound#1#2{{\xintRound{#1}{#2}}}% +\def\XINTiRound_braced#1#2{{\xintiRound{#1}{#2}[\the\numexpr-#1]}}% \def\xintfloatexpro #1% {% \ifx [#1\expandafter\XINT_flexpr_withopt\else\expandafter\XINT_flexpr_noopt @@ -36255,39 +36769,52 @@ math shift catcode. \expandafter\XINT_flexpr_wrap \the\numexpr#1\expandafter.% \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracedinFloat[#1]}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTinFloat_braced[#1]}% }% -\def\XINTbracedinFloat[#1]#2{{\XINTinFloat[#1]{#2}}}% +\def\XINTinFloat_braced[#1]#2{{\XINTinFloat[#1]{#2}}}% % \end{macrocode} % \subsubsection{\csh{XINT_expr_wrap}, \csh{XINT_iiexpr_wrap}, \csh{XINT_flexpr_wrap}} % \lverb|1.3e removes some leading space tokens which served nothing. There is -% no \XINT_iexpr_wrap, because \XINT_expr_wrap is used directly.| +% no \XINT_iexpr_wrap, because \XINT_expr_wrap is used directly. +% +% 1.4e has \XINT_iexpr_wrap separated from \XINT_expr_wrap, thus simplifying +% internal matters as output printer for \xintexpr will not have to handle +% fixed point input but only extended-raw type input (i.e. A, A/B, A[N] or A/B[N]). +% | % \begin{macrocode} \def\XINT_expr_wrap {\XINTfstop\XINTexprprint.}% +\def\XINT_iexpr_wrap {\XINTfstop\XINTiexprprint.}% \def\XINT_iiexpr_wrap {\XINTfstop\XINTiiexprprint.}% \def\XINT_flexpr_wrap {\XINTfstop\XINTflexprprint}% % \end{macrocode} -% \subsubsection{\csh{XINTexprprint}, \csh{XINTiiexprprint}, \csh{XINTflexprprint}} +% \subsubsection{\csh{XINTexprprint}, \csh{XINTiexprprint}, \csh{XINTiiexprprint}, \csh{XINTflexprprint}} % \lverb| % -% Comments currently under reconstruction. +% Comments (still) currently under reconstruction. +% +% 1.4: this now requires \expanded context. +% +% 1.4e has a separate \XINTiexprprint and \xintiexprPrintOne. % -% 1.4: attention that this now requires \expanded context as the «printer» -% macros are not f-expandable but only e-expandable. +% 1.4e has a breaking change of \XINTflexprprint and \xintfloatexprPrintOne +% which now requires \xintfloatexprPrintOne[D]{x} usage, with first argument +% in brackets. % % | % \begin{macrocode} \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 \def\xintexprEmptyItem{[]}% \protected\def\XINTiiexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintiiexprPrintOne}% \let\xintiiexprPrintOne\xint_firstofone \protected\def\XINTflexprprint #1.% - {\XINT:NEhook:x:toblist\XINT:expr:toblistwith{\xintfloatexprPrintOne{#1}}}% -\def\xintfloatexprPrintOne#1% - {\romannumeral0\XINT_pfloat_opt [\xint:#1]}% bad direct jump + {\XINT:NEhook:x:toblist\XINT:expr:toblistwith{\xintfloatexprPrintOne[#1]}}% +\let\xintfloatexprPrintOne\xintPFloat_wopt \protected\def\XINTboolexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintboolexprPrintOne}% \def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% @@ -36361,11 +36888,23 @@ math shift catcode. % \end{macrocode} % \subsubsection{\csh{xintthebareeval}, \csh{xintthebarefloateval}, % \csh{xintthebareiieval}} -% \lverb|For matters of \XINT_NewFunc| +% \lverb|For matters of \XINT_NewFunc +% | % \begin{macrocode} +\def\XINT_expr_unlock {\expandafter\xint_firstofone\romannumeral`&&@}% \def\xintthebareeval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbareeval}% -\def\xintthebarefloateval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbarefloateval}% \def\xintthebareiieval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbareiieval}% +\def\xintthebarefloateval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbarefloateval}% +\def\xintthebareroundedfloateval +{% + \romannumeral0\expandafter\xintthebareroundedfloateval_a\romannumeral0\xintbarefloateval +}% +\def\xintthebareroundedfloateval_a +{% + \expandafter\xint_stop_atfirstofone + \expanded\XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTinFloatSdigits_braced}% +}% +\def\XINTinFloatSdigits_braced#1{{\XINTinFloatS[\XINTdigits]{#1}}}% % \end{macrocode} % \subsubsection{\csh{xinteval}, \csh{xintieval}, \csh{xintfloateval}, % \csh{xintiieval}} @@ -36879,7 +37418,12 @@ math shift catcode. % \end{macrocode} % \subsubsection{Scientific notation} % \lverb|Some pluses and minuses are allowed at the start of the scientific -% part, however not later, and no parenthesis.| +% part, however not later, and no parenthesis. +% +% ATTENTION! 1e\numexpr2+3\relax or 1e\xintiexpr i\relax, i=1..5 +% are not allowed and 1e1\numexpr2\relax does 1e1 * \numexpr2\relax. +% Use \the\numexpr, \xinttheiexpr, etc... +% | % \begin{macrocode} \def\XINT_expr_scanexp_a #1#2% {% @@ -36895,7 +37439,7 @@ math shift catcode. {% \expandafter\XINT_expr_scanexp_main_b\romannumeral`&&@#1% }% -\def\XINT_expr_scanexpr_hit_cs\ifnum#1\fi#2\XINT_expr_scanexp_again +\def\XINT_expr_scanexp_hit_cs\ifnum#1\fi#2\XINT_expr_scanexp_again {% ]\iffalse{{{\fi}}\expandafter}\romannumeral`&&@\XINT_expr_getop#2% }% @@ -37681,7 +38225,7 @@ math shift catcode. \XINT_expr_defbin_b {flexpr} / {xiv}{xiv}{XINTinFloatDiv}% \XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% \XINT_expr_defbin_b {expr} ^ {xviii}{xviii}{xintPow}% -\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatPowerH}% +\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatSciPow}% \XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii}{xintiiPow}% \catcode`& 12 \xintFor #1 in {and,or,xor,mod} \do @@ -38579,7 +39123,7 @@ math shift catcode. {% \expandafter\XINT_expr_put_op_first \expanded{{\romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatFac#1}}\expandafter}\romannumeral`&&@\XINT_expr_getop + {\romannumeral`&&@\XINTinFloatFacdigits#1}}\expandafter}\romannumeral`&&@\XINT_expr_getop }% \def\XINT_iiexpr_op_! #1% {% @@ -38658,7 +39202,22 @@ math shift catcode. % breakage elsewhere, and that the February 2020 |1.4| did not break something % else. % +% \lverb|& +% 1.4e, done 2021/04/17, modifies \xintdeffloatvar to round to the prevailing +% precision (formerly, any operation would induce rounding, but in case of +% things such as \xintdeffloatvar foo:=\xintexpr 1/100!\relax; there was no +% automatic rounding. One could use 0+ syntax to trigger it, and for oples, +% some trick like \xintfloatexpr[\XINTdigits]...\relax extra wrapper. +% +% Now inner computations are done with guard digits. But, with some +% hesitation, I decided that it would be problematic if \xintfloateval{} would +% print only a partial view of a variable, the variable having unknown hidden +% extra digits. Also, xintsession 0.1 was done to use \xintfloateval{} to +% display the computation result, and it would be very confusing if one could +% not copy paste that value and expect exact same behaviour as the automatic +% label variable. % +% | % % \begin{macrocode} \catcode`* 11 @@ -38696,7 +39255,8 @@ math shift catcode. \def\XINT_expr_defvar #1#2% {% \def\XINT_defvar_tmpa{#2}% - \expandafter\XINT_expr_defvar_a\expandafter#1\romannumeral\XINT_expr_fetch_to_semicolon + \expandafter\XINT_expr_defvar_a\expanded{\unexpanded{{#1}}\expandafter}% + \romannumeral\XINT_expr_fetch_to_semicolon }% \def\XINT_expr_defvar_a #1#2% {% @@ -38718,11 +39278,11 @@ math shift catcode. {Aborting: not allowed to declare variable with empty name.}% \or \XINT_global - \expandafter\edef\csname XINT_expr_varvalue_\XINT_defvar_tmpa\endcsname - {\romannumeral0#1#2\relax}% + \expandafter + \edef\csname XINT_expr_varvalue_\XINT_defvar_tmpa\endcsname{#1#2\relax}% \XINT_expr_defvar_one_b\XINT_defvar_tmpa \else - \edef\XINT_defvar_tmpb{\romannumeral0#1#2\relax}% + \edef\XINT_defvar_tmpb{#1#2\relax}% \edef\XINT_defvar_tmpd{\expandafter\xintLength\expandafter{\XINT_defvar_tmpb}}% \let\XINT_defvar_tmpe\empty \if1\XINT_defvar_tmpd @@ -38758,14 +39318,28 @@ math shift catcode. \catcode`: 11 % \end{macrocode} % \lverb|This SafeCatcodes is mainly in the hope that semi-colon ending the -% expression can still be sanitized.| +% expression can still be sanitized. +% +% Pre 1.4e definition: +%(\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}% +%:\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintthebarefloateval{#1}}% +%) +% This would keep the value (or values) with extra digits, now. +% If this is actually wanted one can use +% \xintdefvar foo:=\xintfloatexpr...\relax; +% syntax, but recalling that only operations trigger the rounding inside +% \xintfloatexpr. Some tricks are needed for no operations case if multiple or +% nested values. But for a single one, one can use simply the float() +% function. +% +% | % \begin{macrocode} -\def\xintdefvar {\xintexprSafeCatcodes\xintdefvar_a}% -\def\xintdefiivar {\xintexprSafeCatcodes\xintdefiivar_a}% -\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}% -\def\xintdefvar_a #1={\XINT_expr_defvar\xintthebareeval {#1}}% -\def\xintdefiivar_a #1={\XINT_expr_defvar\xintthebareiieval {#1}}% -\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintthebarefloateval {#1}}% +\def\xintdefvar {\xintexprSafeCatcodes\xintdefvar_a}% +\def\xintdefvar_a#1={\XINT_expr_defvar\xintthebareeval{#1}}% +\def\xintdefiivar {\xintexprSafeCatcodes\xintdefiivar_a}% +\def\xintdefiivar_a#1={\XINT_expr_defvar\xintthebareiieval{#1}}% +\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}% +\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintthebareroundedfloateval{#1}}% % \end{macrocode} % \subsubsection{\csh{xintunassignvar}} % \changed{1.2e}{} @@ -40153,7 +40727,7 @@ math shift catcode. {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatFracdigits#3}}% + {\romannumeral`&&@\XINTinFloatFrac#3}}% }% % \end{macrocode} % \lverb|no \XINT_iiexpr_func_frac| @@ -40195,7 +40769,6 @@ math shift catcode. \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\xintSqr#3}}% }% -\def\XINTinFloatSqr#1{\XINTinFloatMul{#1}{#1}}% \def\XINT_flexpr_func_sqr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% @@ -40312,13 +40885,6 @@ math shift catcode. }}% }% \let\XINT_flexpr_func_sqrt\XINT_expr_func_sqrt -\def\XINT_expr_func_sqrt_ #1#2#3% -{% - \expandafter #1\expandafter #2\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatSqrtdigits#3}}% -}% -\let\XINT_flexpr_func_sqrt_\XINT_expr_func_sqrt_ \def\XINT_iiexpr_func_sqrt #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% @@ -40386,17 +40952,24 @@ math shift catcode. }% \let\XINT_flexpr_func_float\XINT_expr_func_float % \end{macrocode} -% \lverb|float_() added at 1.4. Does not check for optional argument. Useful -% to transfer functions defined with \xintdeffunc to functions usable in -% \xintfloateval. I hesitated briefly about notation but here we go. -% Unfortunately I will have to document it (contrarily to sqrt_). +% \lverb|& +% float_() was added at 1.4, as a shortcut alias to float() skipping the check +% for an optional second argument. This is useful to transfer function +% definitions between \xintexpr and \xintfloatexpr contexts. % -% No need to do same for sfloat() currently used in xinttrig.sty to go from -% float to expr, because sfloat(x) sees there is no optional argument. % -% Still I wonder if better would not be to have some function «single()» which -% signals to outer one it is a single argument? Must think about this. Too -% late now for 1.4.| +% No need for a similar shortcut for sfloat() as currently used in +% xinttrig.sty to go from float to expr: as it is used there as sfloat(x) with +% dummy x, it sees there is no optional argument, contrarily to for example +% float(\xintexpr...\relax) which has to allow for the inner expression to +% expand to an ople with two items, so does not know in which branch it is at +% time of definiion. +% +% +% After some hesitation at 1.4e regarding guard digits mechanism the float_() +% got renamed to float_dgt(), but then renamed back to float_() to avoid a +% breaking change and having to document it. But I don't like the name. +% | % \begin{macrocode} \def\XINT_expr_func_float_ #1#2#3% {% @@ -40405,6 +40978,7 @@ math shift catcode. {\romannumeral`&&@\XINTinFloatdigits#3}}% }% \let\XINT_flexpr_func_float_\XINT_expr_func_float_ +% no \XINT_iiexpr_func_float_dgt \def\XINT_expr_func_sfloat #1#2#3% {% \expandafter #1\expandafter #2\expandafter{\expandafter{% @@ -40413,7 +40987,7 @@ math shift catcode. }}% }% \let\XINT_flexpr_func_sfloat\XINT_expr_func_sfloat -% \XINT_iiexpr_func_sfloat not defined +% no \XINT_iiexpr_func_sfloat \expandafter\def\csname XINT_expr_func_ilog10\endcsname #1#2#3% {% \expandafter #1\expandafter #2\expandafter{\expandafter{% @@ -40421,6 +40995,11 @@ math shift catcode. \XINT:expr:f:one:and:opt #3,!\xintiLogTen\XINTFloatiLogTen }}% }% +% \end{macrocode} +% \lverb|& +% 1.4e does not add guard digits usage to ilog10(x) +% | +% \begin{macrocode} \expandafter\def\csname XINT_flexpr_func_ilog10\endcsname #1#2#3% {% \expandafter #1\expandafter #2\expandafter{\expandafter{% @@ -41945,7 +42524,7 @@ math shift catcode. \fi}@ }@ \catcode`% 14 -\XINT_setcatcodes % clean up to avoid surprises if something changes +\XINTsetcatcodes % clean up to avoid surprises if something changes % \end{macrocode} % \subsubsection{\csh{ifxintexprsafecatcodes}, \csh{xintexprSafeCatcodes}, \csh{xintexprRestoreCatcodes}} % \changed{1.3c}{2018/06/17} @@ -41957,6 +42536,7 @@ math shift catcode. {% \unless\ifxintexprsafecatcodes \edef\xintexprRestoreCatcodes {% + \endlinechar=\the\endlinechar \catcode59=\the\catcode59 % ; \catcode34=\the\catcode34 % " \catcode63=\the\catcode63 % ? @@ -41985,6 +42565,7 @@ math shift catcode. }% \fi \xintexprsafecatcodestrue + \endlinechar=13 % \catcode59=12 % ; \catcode34=12 % " \catcode63=12 % ? @@ -42018,7 +42599,7 @@ math shift catcode. {\input xinttrig.sty \input xintlog.sty }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintexpr} % \cleardoublepage\let\xintexprnameUp\undefined @@ -42027,7 +42608,7 @@ math shift catcode. %\let<*xinttrig>\gardesinactifs %</xintexpr>^^A-------------------------------------------------- %<*xinttrig>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xinttrignameUp\endcsname % \section{Package \xinttrignameimp implementation} % \RaisedLabel{sec:trigimp} @@ -42036,33 +42617,77 @@ math shift catcode. % % \localtableofcontents % -% Comments under reconstruction. -% -% The original was done in January 15 and 16, 2019. It provided |asin()| and -% |acos()| based on a Newton algorithm approach. Then during March 25-31 I -% revisited the code, adding more inverse trigonometrical functions (with a -% modified algorithm, quintically convergent), extending the precision range -% (so that the package reacts to the \csbxint{Digits} value at time of load, -% or reload), and replaced high level range reduction by some optimized lower -% level coding. -% -% This led me next to improve upon the innards of \csbxint{deffunc} and -% \csbxint{NewExpr}, and to add to \xintexprnameimp the \csa{xintdefefunc} -% macro (see user documentation). -% -% Finally on April 5, 2019 I pushed further the idea of the algorithm for the -% arcsine function. The cost is at least the one of a combined |sin()/cos()| -% evaluation, surely this is not best approach for low precision, but I like -% the principle and its suitability to go into hundreds of digits if desired. -% -% Almost all of the code remains written at high level, and in particular it -% is not easily feasible from this interface to execute computations with -% guard digits. Expect the last one or two digits to be systematically off. -% -% Also, small floating-point inputs are handled quite sub-optimally both for -% the direct and inverse functions; substantial gains are possible. I added -% the ilog10() function too late to consider using it here with the high level -% interface. +% A preliminary implementation was done only late in the development of +% \cs{xintexpr}, as an example of the high level user interface, in January +% 2019. In March and April 2019 I improved the algorithm for the inverse +% trigonometrical functions and included the whole as a new \csbxint{expr} +% module. But, as the high level interface provided no way to have +% intermediate steps executed with guard digits, the whole scheme could only +% target say P-2 digits where P is the prevailing precision, and only with a +% moderate requirement on what it means to have P-2 digits about correct. +% +% Finally in April 2021, after having at long last added exponential and +% logarithm up to 62 digits and at a rather strong precision requirement +% (something like, say with inputs in normal ranges: targeting at most 0.505ulp +% distance to exact result), I revisited the code here. +% +% We keep most of the high level usage of \csbxint{deffloatfunc}, but hack +% into its process in order to let it map the 4 operations and some functions +% such as square-root to macros using 4 extra digits. This hack is enough to +% support the used syntax here, but is not usable generally. All functions and +% their auxiliaries defined during the time the hack applies are named with +% |@| as first letter. +% +% Later the public functions, without the |@|, are defined as wrappers of the +% |@|-named ones, which float-round to P digits on output. +% +% Apart from that the sine and cosine series were implemented at macro level, +% bypassing the \csbxint{deffloatfunc} interface. This is done mainly for +% handling Digits at high value (24 or more) as it then becomes beneficial to +% float-round the variable to less and less digits, the deeper one goes into +% the series. +% +% And regarding the arcsine I modified a bit my original idea in order to +% execute the first step in a single \cs{numexpr}. It turns out that that for +% 16 digits the algorithm then ``only'' needs one sine and one cosine +% evaluation (and a square-root), and there is no need for an arcsine series +% auxiliary then. I am aware this is by far not the ``best'' approach but the +% problem is that I am a bit enamored into the idea of the algorithm even +% though it is at least twice as costly than a sine evaluation! Actually, for +% many digits, it turns out the arcsine is less costly than two random sine +% evaluations, probably because the latter have the overhead of range +% reduction. +% +% Speaking of this, the range reduction is rather naive and not extremely +% ambitious. I wrote it initially having only |sind()| and |cosd()| in mind, +% and in 2019 reduced degrees to radians in the most naive way possible. I +% have only slighly improved this for this |1.4e| 2021 release, the announced +% precision for inputs less than say |1e6|, but at |1e8| and higher, one will +% start feeling the gradual loss of precision compared to the task of +% computing the exact mathematical result correctly rounded. Also, I do not +% worry here about what happens when the input is very near a big multiple of +% $\pi$, and one computes a sine for example. Maybe I will improve in future +% this aspect but I decided I was seriously running out of steam for the +% |1.4e| release. +% +% As commented in \xintlognameimp regarding exponential and logarithms, even +% though we have instilled here some dose of lower level coding, the whole +% suffers from \xintfracnameimp not yet having made floating point numbers a +% native type. Thus inefficiencies accumulate... +% +% At 8 digits, the gain was only about 40\% compared to 16 digits. So at the +% last minute, on the day I was going to do the release I decided to implement +% a poorman way for sine and cosine, for "speed". I transferred the idea from +% the arcsine numexpr to sine and cosine. Indeed there is an interesting speed +% again of about 4X compared to applying the same approach as for higher +% values of Digits. Correct rounding during random testing is still obtained +% reasonably often (at any rate more than 95\% of cases near 45 degrees and +% always faithful rounding), although at less than the 99\% reached for the +% main branch handling Digits up to 62. But the precision is more than enough +% for usage in plots for example. I am keeping the guard digits, as removing +% then would add a further speed gain of about 20\% to 40\% but the precision +% then would drop dramatically, and this is not acceptable at the time of our +% 2021 standards (not a period of enlightenment generally speaking, though). % % \subsection{Catcodes, \protect\eTeX{} and reload detection} % \begin{macrocode} @@ -42102,7 +42727,8 @@ math shift catcode. \fi \fi \z% -\catcode`_ 11 \XINT_setcatcodes \catcode`? 12 +\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\catcode`? 12 % \end{macrocode} % \subsection{Library identification} % \begin{macrocode} @@ -42112,10 +42738,10 @@ math shift catcode. \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/03/29 v1.4d}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/05/05 v1.4e}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2021/03/29 v1.4d Trigonometrical functions for xintexpr (JFB)]% +[2021/05/05 v1.4e Trigonometrical functions for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{Ensure used letters are dummy letters} @@ -42123,210 +42749,387 @@ math shift catcode. \xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}% % \end{macrocode} % \subsection{\csh{xintreloadxinttrig}} +% \lverb|Much simplified at 1.4e, from a modified catcode regime management.| % \begin{macrocode} -\def\xintreloadxinttrig - {\edef\XINT_restorecatcodes_now{\XINT_restorecatcodes}% - \XINT_setcatcodes\catcode`? 12 - \input xinttrig.sty - \XINT_restorecatcodes_now}% +\def\xintreloadxinttrig{\input xinttrig.sty }% % \end{macrocode} -% \subsection{Auxiliary variables (only temporarily needed, but left free to re-use)} +% \subsection{Auxiliary variables} % \lverb|& -% These variables don't have really private names but this does not matter -% because only their actual values will be stored in the functions defined -% next. Nevertheless they are not unassigned, and are left free to use as is. +% The variables with private names have extra digits. Whether private or +% public, the variables can all be redefined without impacting the defined +% functions, whose meanings will contain already the variable values. +% +% Formerly variables holding the 1/n! were defined, but this got removed at 1.4e. % | -% \subsubsection{\cshn{twoPi}, \cshn{threePiover2}, \cshn{Pi}, \cshn{Piover2}} +% \subsubsection{\cshn{@twoPi}, \cshn{@threePiover2}, \cshn{@Pi}, \cshn{@Piover2}} % \lverb|& -% We take them with 60 digits -% and force conversion to \xintDigits setting via "0 + " syntax. -% | -% \begin{macrocode} -\xintdeffloatvar twoPi := 0 + - 6.28318530717958647692528676655900576839433879875021164194989;% -\xintdeffloatvar threePiover2 := 0 + - 4.71238898038468985769396507491925432629575409906265873146242;% -\xintdeffloatvar Pi := 0 + - 3.14159265358979323846264338327950288419716939937510582097494;% -\xintdeffloatvar Piover2 := 0 + - 1.57079632679489661923132169163975144209858469968755291048747;% -% \end{macrocode} -% \subsubsection{\cshn{oneDegree}, \cshn{oneRadian}} +% At 1.4e we need more digits, also \xintdeffloatvar changed and always rounds +% to P=Digits precision so we use another path to store values with extra digits. +% | +% \begin{macrocode} +\xintdefvar @twoPi := + float( +6.2831853071795864769252867665590057683943387987502116419498891846156328125724180 + ,\xinttheDigits+4);% +\xintdefvar @threePiover2 := + float( +4.7123889803846898576939650749192543262957540990626587314624168884617246094293135 + ,\xinttheDigits+4);% +\xintdefvar @Pi := + float( +3.1415926535897932384626433832795028841971693993751058209749445923078164062862090 + ,\xinttheDigits+4);% +\xintdefvar @Piover2 := + float( +1.5707963267948966192313216916397514420985846996875529104874722961539082031431045 + ,\xinttheDigits+4);% +% \end{macrocode} +% \subsubsection{\cshn{@oneDegree}, \cshn{@oneRadian}} +% \lverb|& +% Those are needed for range reduction, particularly @oneRadian. We define +% it with 12 extra digits. But the whole process of range reduction in radians +% is very naive one.| +% \begin{macrocode} +\xintdefvar @oneDegree := + float( +0.017453292519943295769236907684886127134428718885417254560971914401710091146034494 + ,\xinttheDigits+4);% +\xintdefvar @oneRadian := + float( +57.295779513082320876798154814105170332405472466564321549160243861202847148321553 + ,\xinttheDigits+12);% +% \end{macrocode} +% \subsection{Hack \cs{xintdeffloatfunc} for inserting usage of guard digits} +% \lverb|1.4e. This is not a general approach, but it sufficient for the +% limited use case done here of \xintdeffloatfunc. What it does is to let +% \xintdeffloatfunc hardcode usage of macros which will execute computations +% with an elevated number of digits. But for example if 5/3 is encountered in +% a float expression it will remain unevaluated so one would have to use +% alternate input syntax for efficiency (\xintexpr +% float(5/3,\xinttheDigits+4)\relax as a subexpression, for example).| % \begin{macrocode} -\xintdeffloatvar oneDegree := 0 + - 0.0174532925199432957692369076848861271344287188854172545609719;% Pi/180 -\xintdeffloatvar oneRadian := 0 + - 57.2957795130823208767981548141051703324054724665643215491602;% 180/Pi +\catcode`~ 12 +\def\XINT_tmpa#1#2#3.#4.% +{% + \let #1#2% + \def #2##1##2##3##4{##2##3{{~expanded{~unexpanded{#4[#3]}~expandafter}~expanded{##1##4}}}}% +}% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_+_\expandafter\endcsname + \csname XINT_flexpr_exec_+\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatAdd_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_-_\expandafter\endcsname + \csname XINT_flexpr_exec_-\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSub_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_*_\expandafter\endcsname + \csname XINT_flexpr_exec_*\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatMul_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_/_\expandafter\endcsname + \csname XINT_flexpr_exec_/\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatDiv_wopt.% +\def\XINT_tmpa#1#2#3.#4.% +{% + \let #1#2% + \def #2##1##2##3{##1##2{{~expanded{~unexpanded{#4[#3]}~expandafter}##3}}}% +}% +\expandafter\XINT_tmpa + \csname XINT_flexpr_sqrfunc\expandafter\endcsname + \csname XINT_flexpr_func_sqr\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSqr_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_sqrtfunc\expandafter\endcsname + \csname XINT_flexpr_func_sqrt\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSqrt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_invfunc\expandafter\endcsname + \csname XINT_flexpr_func_inv\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatInv_wopt.% +\catcode`~ 3 % \end{macrocode} -% \subsubsection{Inverse factorial coefficients: \cshn{invfact2}, ..., \cshn{invfact44}} +% \subsection{The sine and cosine series} % \lverb|& -% Pre-compute 1/n! for n = 2, ..., 44 +% Old pending question: should I rather use successive divisions by (2n+1)(2n), or rather +% multiplication by their precomputed inverses, in a modified Horner scheme ? +% The \ifnum tests are executed at time of definition. +% +% Update at last minute: this is actually exactly what I do if Digits is at +% most 8. % +% Small values of the variable are very badly handled here because a much +% shorter truncation of the series should be used. % -% We have to be careful that 1/i! in a float expression first evaluates i! -% as a floating point number then computes the inverse. Even if i! was -% computed exactly before being float-rounded, this process would not -% necessarily lead to the correct rounding of the exact fraction 1/i!. +% At 1.4e the original \xintdeffloatfunc was converted into macros, whose +% principle can be seen also at work in xintlog.sty. We prepare the input +% variables with shorter and shorter mantissas for usage deep in the series. % -% We could use \xintexpr1/i!\relax encapsulation but then the actual -% rounding is delayed to the time when functions are used... this is bad. +% This divided by about 3 the execution cost of the series for P about 60. % -% We need to get now the correct rounding of the exact 1/i!. +% Originally, the thresholds were computed a priori with 0.79 as upper bound +% of the variable, but then for 1.4e I developped enough test files to try to +% adjust heuristically with a target of say +% 99,5$% of correct rounding, and always at most +% 1ulp error. The numerical analysis is not easy due to the complications of +% the implementation... % -% 1.4 update: use \xintfloatexpr with optional argument for the rounding -% rather than «0+x» method. And there is no need now to hide within braces -% the inner semi-colon. +% Also, random testing never explores the weak spots... +% +% The 0.79 (a bit more than Pi/4) upper bound induces a costly check of +% variable on input, if Digits is big. Much faster would be to check if input +% is less than 10 degrees or 1 radian as done in xfp. But using enough +% coefficients for allowing up to 1 radian, which is without pain for +% Digits=16 starts being annoying for higher values such as Digits=48. +% +% But the main reason I don't do it now is that I spend too much time +% fine-tuning the table of thresholds... maybe in next release. % | -% \begin{macrocode} -\xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}% - := \xintfloatexpr [\XINTdigits] % force float rounding after exact evaluations - \xintexpr rseq(1/2; @/i, i=3..44)\relax % no need to hide this inner ; - \relax;% -% \end{macrocode} -% \subsection{The sine and cosine series} -% \subsubsection{\cshn{sin_aux()}, \cshn{cos_aux()}} -% \lverb|& -% Should I rather use successive divisions by (2n+1)(2n), or rather -% multiplication by their precomputed inverses, in a modified Horner scheme ? -% The \ifnum tests are executed at time of definition. +% \subsubsection{Support macros for the sine and cosine series} +% +% \lverb|Computing the 1/n! from n! then inverting would require +% costly divisions and significantly increase the loading time. % -% Criteria for truncated series using π/4, actually 0.79. +% So a method is employed to simply divide by 2k(2k-1) or (2k+1)(2k) +% step by step, with what we hope are enough 8 security digits, and +% reducing the sizes of the mantissas at each step. % -% Small values of the variable X are very badly handled here because a much -% shorter truncation of the sine series should be used. +% This whole section is conditional on Digits being at least nine. % | +% % \begin{macrocode} -\xintdeffloatfunc sin_aux(X) := 1 - X(invfact3 - X(invfact5 -\ifnum\XINTdigits>4 - - X(invfact7 -\ifnum\XINTdigits>6 - - X(invfact9 \ifnum\XINTdigits>8 - - X(invfact11 -\ifnum\XINTdigits>10 - - X(invfact13 -\ifnum\XINTdigits>13 - - X(invfact15 -\ifnum\XINTdigits>15 - - X(invfact17 -\ifnum\XINTdigits>18 - - X(invfact19 -\ifnum\XINTdigits>21 - - X(invfact21 -\ifnum\XINTdigits>24 - - X(invfact23 -\ifnum\XINTdigits>27 - - X(invfact25 -\ifnum\XINTdigits>30 - - X(invfact27 -\ifnum\XINTdigits>33 - - X(invfact29 -\ifnum\XINTdigits>36 - - X(invfact31 -\ifnum\XINTdigits>39 - - X(invfact33 -\ifnum\XINTdigits>43 - - X(invfact35 -\ifnum\XINTdigits>46 - - X(invfact37 -\ifnum\XINTdigits>49 - - X(invfact39 -\ifnum\XINTdigits>53 - - X(invfact41 -\ifnum\XINTdigits>59 - - X(invfact43 - )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));% -% \end{macrocode} -% \lverb|Criteria on basis of π/4, we actually used 0.79 to choose the -% transition values and this makes them a bit less favourable at 24, 26, -% 29...and some more probably. Again this is very bad for small X.| -% \begin{macrocode} -\xintdeffloatfunc cos_aux(X) := 1 - X(invfact2 - X(invfact4 -\ifnum\XINTdigits>3 - - X(invfact6 -\ifnum\XINTdigits>5 - - X(invfact8 -\ifnum\XINTdigits>7 - - X(invfact10 -\ifnum\XINTdigits>9 - - X(invfact12 -\ifnum\XINTdigits>12 - - X(invfact14 -\ifnum\XINTdigits>14 - - X(invfact16 -\ifnum\XINTdigits>17 - - X(invfact18 -\ifnum\XINTdigits>20 - - X(invfact20 -\ifnum\XINTdigits>23 - - X(invfact22 -\ifnum\XINTdigits>25 - - X(invfact24 -\ifnum\XINTdigits>28 - - X(invfact26 -\ifnum\XINTdigits>32 - - X(invfact28 -\ifnum\XINTdigits>35 - - X(invfact30 -\ifnum\XINTdigits>38 - - X(invfact32 -\ifnum\XINTdigits>41 - - X(invfact34 -\ifnum\XINTdigits>44 - - X(invfact36 -\ifnum\XINTdigits>48 - - X(invfact38 -\ifnum\XINTdigits>51 - - X(invfact40 -\ifnum\XINTdigits>55 - - X(invfact42 -\ifnum\XINTdigits>58 - - X(invfact44 - )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));% -% \end{macrocode} -% \subsubsection{Make \cshnnolabel{sin\_aux()} and \cshnnolabel{cos\_aux()} -% known to \cshnolabel{xintexpr}} -% \lverb|We need them shortly for the asin() in an \xintexpr variant. -% We short-circuit the high level interface as it will not be needed to -% add some \xintFloat wrapper. -% | -% \begin{macrocode} -\expandafter\let\csname XINT_expr_func_sin_aux\expandafter\endcsname - \csname XINT_flexpr_func_sin_aux\endcsname -\expandafter\let\csname XINT_expr_func_cos_aux\expandafter\endcsname - \csname XINT_flexpr_func_cos_aux\endcsname +\edef\XINT_tmpG % 1/3! + {1\xintReplicate{\XINTdigits+2}{6}7[\the\numexpr-\XINTdigits-4]}% +\edef\XINT_tmpH % 1/5! + {8\xintReplicate{\XINTdigits+1}{3}[\the\numexpr-\XINTdigits-4]}% +\edef\XINT_tmpd % 1/5! + {8\xintReplicate{\XINTdigits+9}{3}[\the\numexpr-\XINTdigits-12]}% +\def\XINT_tmpe#1.#2.#3.#4.#5#6#7% +{% +\def#5##1\xint: +{% + \expandafter#6\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def#6##1\xint: +{% + \expandafter#7\romannumeral0\xintsub{#4}{\XINTinFloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def#7##1\xint:##2\xint: +{% + \xintSub{1/1[0]}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}% +}% +}% +\expandafter\XINT_tmpe + \the\numexpr\XINTdigits+4\expandafter.% + \the\numexpr\XINTdigits+2\expandafter.\expanded{% + \XINT_tmpH.% 1/5! + \XINT_tmpG.% 1/3! + \expandafter}% + \csname XINT_SinAux_series_a_iii\expandafter\endcsname + \csname XINT_SinAux_series_b\expandafter\endcsname + \csname XINT_SinAux_series_c_i\endcsname +\def\XINT_tmpa #1 #2 #3 #4 #5 #6 #7 #8 % +{% + \def\XINT_tmpb ##1##2##3##4##5% + {% + \def\XINT_tmpc####1.####2.####3.####4.####5.% + {% + \def##1########1\xint: + {% + \expandafter##2% + \romannumeral0\XINTinfloatS[####1]{########1}\xint:########1\xint: + }% + \def##2########1\xint: + {% + \expandafter##3% + \romannumeral0\XINTinfloatS[####2]{########1}\xint:########1\xint: + }% + \def##3########1\xint: + {% + \expandafter##4% + \romannumeral0\xintsub{####4}{\XINTinFloat[####2]{\xintMul{####3}{########1}}}\xint: + }% + \def##4########1\xint:########2\xint: + {% + \expandafter##5% + \romannumeral0\xintsub{####5}{\XINTinFloat[####1]{\xintMul{########1}{########2}}}\xint: + }% + }% + }% + \expandafter\XINT_tmpb + \csname XINT_#8Aux_series_a_\romannumeral\numexpr#1-1\expandafter\endcsname + \csname XINT_#8Aux_series_a_\romannumeral\numexpr#1\expandafter\endcsname + \csname XINT_#8Aux_series_b\expandafter\endcsname + \csname XINT_#8Aux_series_c_\romannumeral\numexpr#1-2\expandafter\endcsname + \csname XINT_#8Aux_series_c_\romannumeral\numexpr#1-3\endcsname + \edef\XINT_tmpd + {\XINTinFloat[\XINTdigits-#2+8]{\xintDiv{\XINT_tmpd}{\the\numexpr#5*(#5-1)\relax}}}% + \let\XINT_tmpF\XINT_tmpG + \let\XINT_tmpG\XINT_tmpH + \edef\XINT_tmpH{\XINTinFloat[\XINTdigits-#2]{\XINT_tmpd}}% + \expandafter\XINT_tmpc + \the\numexpr\XINTdigits-#3\expandafter.% + \the\numexpr\XINTdigits-#2\expandafter.\expanded{% + \XINT_tmpH.% + \XINT_tmpG.% + \XINT_tmpF.% + }% +}% +\XINT_tmpa 4 -1 -2 -4 7 5 3 Sin % +\ifnum\XINTdigits>3 \XINT_tmpa 5 1 -1 -2 9 7 5 Sin \fi +\ifnum\XINTdigits>5 \XINT_tmpa 6 3 1 -1 11 9 7 Sin \fi +\ifnum\XINTdigits>8 \XINT_tmpa 7 6 3 1 13 11 9 Sin \fi +\ifnum\XINTdigits>11 \XINT_tmpa 8 9 6 3 15 13 11 Sin \fi +\ifnum\XINTdigits>14 \XINT_tmpa 9 12 9 6 17 15 13 Sin \fi +\ifnum\XINTdigits>16 \XINT_tmpa 10 14 12 9 19 17 15 Sin \fi +\ifnum\XINTdigits>19 \XINT_tmpa 11 17 14 12 21 19 17 Sin \fi +\ifnum\XINTdigits>22 \XINT_tmpa 12 20 17 14 23 21 19 Sin \fi +\ifnum\XINTdigits>25 \XINT_tmpa 13 23 20 17 25 23 21 Sin \fi +\ifnum\XINTdigits>28 \XINT_tmpa 14 26 23 20 27 25 23 Sin \fi +\ifnum\XINTdigits>31 \XINT_tmpa 15 29 26 23 29 27 25 Sin \fi +\ifnum\XINTdigits>34 \XINT_tmpa 16 32 29 26 31 29 27 Sin \fi +\ifnum\XINTdigits>37 \XINT_tmpa 17 35 32 29 33 31 29 Sin \fi +\ifnum\XINTdigits>40 \XINT_tmpa 18 38 35 32 35 33 31 Sin \fi +\ifnum\XINTdigits>44 \XINT_tmpa 19 42 38 35 37 35 33 Sin \fi +\ifnum\XINTdigits>47 \XINT_tmpa 20 45 42 38 39 37 35 Sin \fi +\ifnum\XINTdigits>51 \XINT_tmpa 21 49 45 42 41 39 37 Sin \fi +\ifnum\XINTdigits>55 \XINT_tmpa 22 53 49 45 43 41 39 Sin \fi +\ifnum\XINTdigits>58 \XINT_tmpa 23 56 53 49 45 43 41 Sin \fi +\edef\XINT_tmpd % 1/4! + {41\xintReplicate{\XINTdigits+8}{6}7[\the\numexpr-\XINTdigits-12]}% +\edef\XINT_tmpH % 1/4! + {41\xintReplicate{\XINTdigits}{6}7[\the\numexpr-\XINTdigits-4]}% +\def\XINT_tmpG{5[-1]}% 1/2! +\expandafter\XINT_tmpe + \the\numexpr\XINTdigits+4\expandafter.% + \the\numexpr\XINTdigits+3\expandafter.\expanded{% + \XINT_tmpH.% + \XINT_tmpG.% + \expandafter}% + \csname XINT_CosAux_series_a_iii\expandafter\endcsname + \csname XINT_CosAux_series_b\expandafter\endcsname + \csname XINT_CosAux_series_c_i\endcsname +\XINT_tmpa 4 -2 -3 -4 6 4 2 Cos % +\ifnum\XINTdigits>2 \XINT_tmpa 5 0 -2 -3 8 6 4 Cos \fi +\ifnum\XINTdigits>4 \XINT_tmpa 6 2 0 -2 10 8 6 Cos \fi +\ifnum\XINTdigits>7 \XINT_tmpa 7 5 2 0 12 10 8 Cos \fi +\ifnum\XINTdigits>9 \XINT_tmpa 8 7 5 2 14 12 10 Cos \fi +\ifnum\XINTdigits>12 \XINT_tmpa 9 10 7 5 16 14 12 Cos \fi +\ifnum\XINTdigits>15 \XINT_tmpa 10 13 10 7 18 16 14 Cos \fi +\ifnum\XINTdigits>18 \XINT_tmpa 11 16 13 10 20 18 16 Cos \fi +\ifnum\XINTdigits>20 \XINT_tmpa 12 18 16 13 22 20 18 Cos \fi +\ifnum\XINTdigits>24 \XINT_tmpa 13 22 18 16 24 22 20 Cos \fi +\ifnum\XINTdigits>27 \XINT_tmpa 14 25 22 18 26 24 22 Cos \fi +\ifnum\XINTdigits>30 \XINT_tmpa 15 28 25 22 28 26 24 Cos \fi +\ifnum\XINTdigits>33 \XINT_tmpa 16 31 28 25 30 28 26 Cos \fi +\ifnum\XINTdigits>36 \XINT_tmpa 17 34 31 28 32 30 28 Cos \fi +\ifnum\XINTdigits>39 \XINT_tmpa 18 37 34 31 34 32 30 Cos \fi +\ifnum\XINTdigits>42 \XINT_tmpa 19 40 37 34 36 34 32 Cos \fi +\ifnum\XINTdigits>45 \XINT_tmpa 20 43 40 37 38 36 34 Cos \fi +\ifnum\XINTdigits>49 \XINT_tmpa 21 47 43 40 40 38 36 Cos \fi +\ifnum\XINTdigits>53 \XINT_tmpa 22 51 47 43 42 40 38 Cos \fi +\ifnum\XINTdigits>57 \XINT_tmpa 23 55 51 47 44 42 40 Cos \fi +\ifnum\XINTdigits>60 \XINT_tmpa 24 58 55 51 46 44 42 Cos \fi +\let\XINT_tmpH\xint_undefined\let\XINT_tmpG\xint_undefined\let\XINT_tmpF\xint_undefined +\let\XINT_tmpd\xint_undefined\let\XINT_tmpe\xint_undefined +\def\XINT_SinAux_series#1% +{% + \expandafter\XINT_SinAux_series_a_iii + \romannumeral0\XINTinfloatS[\XINTdigits+4]{#1}\xint: +}% +\def\XINT_CosAux_series#1% +{% + \expandafter\XINT_CosAux_series_a_iii + \romannumeral0\XINTinfloatS[\XINTdigits+4]{#1}\xint: +}% +\fi % end of \XINTdigits>8 +% \end{macrocode} +% \subsubsection{The poor man approximate but speedier approach for Digits at most 8} +% \begin{macrocode} +\ifnum\XINTdigits<9 +\def\XINT_SinAux_series#1% +{% + \the\numexpr\expandafter\XINT_SinAux_b\romannumeral0\xintiround9{#1}.[-9]% +}% +\def\XINT_SinAux_b#1.% +{% + ((((((((((((%(\xint_c_x^ix/-210) + -4761905*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -156)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -110)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -72)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -42)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -20)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -6)*#1/\xint_c_x^ix+\xint_c_x^ix +}% +\def\XINT_CosAux_series#1% +{% + \the\numexpr\expandafter\XINT_CosAux_b\romannumeral0\xintiround9{#1}.[-9]% +}% +\def\XINT_CosAux_b#1.% +{% + ((((((((((((((%(\xint_c_x^ix/-240) + -4166667*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -182)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -132)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -90)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -56)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -30)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -12)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -2)*#1/\xint_c_x^ix+\xint_c_x^ix +}% +\fi % \end{macrocode} -% \subsubsection{\cshn{sin_()}, \cshn{cos_()}} -% \lverb|& -% Use this only between -pi/4 and pi/4 -% | +% \subsubsection{Declarations of the \cshn{@sin_aux()} and \cshn{@cos_aux()} functions} % \begin{macrocode} -\xintdeffloatfunc sin_(x) := x * sin_aux(sqr(x));% +\def\XINT_flexpr_func_@sin_aux#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_SinAux_series#3}}% +}% +\def\XINT_flexpr_func_@cos_aux#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_CosAux_series#3}}% +}% % \end{macrocode} -% \lverb|& -% Use this only between -pi/4 and pi/4 -% | +% \subsubsection{\cshn{@sin_series()}, \cshn{@cos_series()}} % \begin{macrocode} -\xintdeffloatfunc cos_(x) := cos_aux(sqr(x));% +\xintdeffloatfunc @sin_series(x) := x * @sin_aux(sqr(x));% +\xintdeffloatfunc @cos_series(x) := @cos_aux(sqr(x));% % \end{macrocode} % \subsection{Range reduction for sine and cosine using degrees} % -% Notice that even when handling radians it is much better to convert to -% degrees and then do range reduction there, because this can be done in the -% fixed point sense. I lost 1h puzzled about some mismatch of my results with -% those of Maple (at 16 digits) near -π. Turns out that Maple probably adds π +% \lverb|& +% As commented in the package introduction, Range reduction is a demanding +% domain and we handle it semi-satisfactorily. The main problem is that in +% January 2019 I had done only support for degrees, and when I added radians I +% used the most naive approach. But one can find worse: in 2019 I was +% surprised to have importent divergences with Maple's results at 16 digits +% near -π. Turns out that Maple probably adds π % in the floating point sense causing catastrophic loss of digits when one is -% near -π. On the other hand my sin(x) function will first convert to degrees -% then add 180 without any loss of floating point precision, even for a result -% near zero, then convert back to radians and use the sine series. +% near -π. On the other hand even though the approach here is still naive, it +% behaves much better. +% +% The @sind_rr() and @cosd_rr() sine and cosine "doing range reduction" are +% coded directly at macro level via \xintSind and \xintCosd which will +% dispatch to usage of the sine or cosine series, depending on case. % -% \subsubsection{Core level macro \csh{XINT_mod_ccclx_i}} +% Old note from 2019: attention that \xintSind and \xintCosd must be used +% with a positive argument. +% +% We start with an auxiliary macro to reduce modulo 360 quickly. +% | +% \subsubsection{Low level modulo 360 helper macro \csh{XINT_mod_ccclx_i}} % \lverb|& % input: \the\numexpr\XINT_mod_ccclx_i k.N. (delimited by dots) % % output: (N times 10^k) modulo 360. (with a final dot) % -% Attention N must be non-negative (I could make it accept negative +% Attention that N must be non-negative (I could make it accept negative % but the fact that numexpr / is not periodical in numerator % adds overhead). % @@ -42334,15 +43137,15 @@ math shift catcode. % group generated by it modulo 360 is the set of multiples of 40. % | % \begin{macrocode} -\def\XINT_mod_ccclx_i #1.% input <k>.<N>. k is a non-negative exponent +\def\XINT_mod_ccclx_i #1.% {% \expandafter\XINT_mod_ccclx_e\the\numexpr \expandafter\XINT_mod_ccclx_j\the\numexpr1\ifcase#1 \or0\or00\else000\fi.% }% -\def\XINT_mod_ccclx_j 1#1.#2.% #2=N is a non-negative mantissa +\def\XINT_mod_ccclx_j 1#1.#2.% {% (\XINT_mod_ccclx_ja {++}#2#1\XINT_mod_ccclx_jb 0000000\relax -}% 1 2345678 +}% \def\XINT_mod_ccclx_ja #1#2#3#4#5#6#7#8#9% {% #9+#8+#7+#6+#5+#4+#3+#2\xint_firstoftwo{+\XINT_mod_ccclx_ja{+#9+#8+#7}}{#1}% @@ -42358,47 +43161,55 @@ math shift catcode. \def\XINT_mod_ccclx_e#1.{\expandafter\XINT_mod_ccclx_z\the\numexpr(#1+180)/360-1.#1.}% \def\XINT_mod_ccclx_z#1.#2.{#2-360*#1.}% % \end{macrocode} -% \subsubsection{\cshn{sind_()}, \cshn{cosd_()}, and support macros \csh{xintSind}, \csh{xintCosd}} -% \lverb|& -% -% sind_() coded directly at macro level with a macro \xintSind (ATTENTION! it -% requires a positive argument) -% which will suitably use \XINT_flexpr_func_sin_ defined from \xintdeffloatfunc -% | +% \subsubsection{\cshn{@sind_rr()} function and its support macro \csh{xintSind}} % \begin{macrocode} -\def\XINT_flexpr_func_sind_ #1#2#3% +\def\XINT_flexpr_func_@sind_rr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one{\romannumeral`&&@\xintSind#3}}% }% % \end{macrocode} % \lverb|& -% Must be f-expandable for nesting macros from \xintNewExpr +% old comment: Must be f-expandable for nesting macros from \xintNewExpr % -% ATTENTION ONLY FOR POSITIVE ARGUMENTS +% This is where the prize of using the same macros for two distinct use cases +% has serious disadvantages. The reason of Digits+12 is only to support an +% input which contains a multiplication by @oneRadian with its extended +% digits. +% +% Then we do a somewhat strange truncation to a fixed point of fractional +% digits, which is ok in the "Degrees" case, but causes issues of its own in +% the "Radians" case. Please consider this whole thing as marked for future +% improvement, when times allows. +% +% ATTENTION \xintSind ONLY FOR POSITIVE ARGUMENTS % | % \begin{macrocode} -\def\XINT_expr_unlock{\expandafter\xint_firstofone\romannumeral`&&@}% -\def\xintSind#1{\romannumeral`&&@\expandafter\xintsind - \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}% +\def\XINT_tmpa #1.{% +\def\xintSind##1% +{% + \romannumeral`&&@\expandafter\xintsind\romannumeral0\XINTinfloatS[#1]{##1}}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+12.% \def\xintsind #1[#2#3]% {% \xint_UDsignfork #2\XINT_sind -\XINT_sind_int - \krof#2#3.#1..%<< attention extra dot + \krof#2#3.#1..% }% -\def\XINT_sind #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2. +\def\XINT_tmpa #1.{% +\def\XINT_sind ##1.##2.% {% \expandafter\XINT_sind_a - \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}% + \romannumeral0\xinttrunc{#1}{##2[##1]}% }% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+5.% \def\XINT_sind_a{\expandafter\XINT_sind_i\the\numexpr\XINT_mod_ccclx_i0.}% \def\XINT_sind_int {% \expandafter\XINT_sind_i\the\numexpr\expandafter\XINT_mod_ccclx_i }% -\def\XINT_sind_i #1.% range reduction inside [0, 360[ +\def\XINT_sind_i #1.% {% \ifcase\numexpr#1/90\relax \expandafter\XINT_sind_A @@ -42409,82 +43220,58 @@ math shift catcode. \fi#1.% }% % \end{macrocode} -% \lverb|& -% #2 will be empty in the "integer branch". Notice that a single dot "." is -% valid as input to the xintfrac macros. During developing phase I did many -% silly mistakes due to wanting to use too low-level interface, e.g. I would -% use something like #2[-\XINTdigits] with #2 the fractional digits, but there -% maybe some leading zero and then xintfrac.sty will think the whole thing is -% zero due to the requirements of my own core format A[N].... -% -% Multiplication is done exactly but anyway currently float multiplication -% goes via exact multiplication after rounding arguments ; as here integer -% part has at most three digits, doing exact multiplication will prove -% not only more accurate but probably faster. -% | % \begin{macrocode} -\def\XINT_sind_A#1{% +\def\XINT_tmpa #1.#2.{% \def\XINT_sind_A##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_sind_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_B#1{\xint_UDsignfork#1\XINT_sind_B_n-\XINT_sind_B_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_B_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_B_p##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_C#1{\xint_UDsignfork#1\XINT_sind_C_n-\XINT_sind_C_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_C_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_C_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_D#1{\xint_UDsignfork#1\XINT_sind_D_n-\XINT_sind_D_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_D_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_D_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_E#1{% \def\XINT_sind_E-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% -}\expandafter -\XINT_sind_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+4\expandafter.% + \romannumeral`&&@\xintbarefloateval @oneDegree\relax.% +\def\XINT_sind_B#1{\xint_UDsignfork#1\XINT_sind_B_n-\XINT_sind_B_p\krof #1}% +\def\XINT_sind_C#1{\xint_UDsignfork#1\XINT_sind_C_n-\XINT_sind_C_p\krof #1}% +\def\XINT_sind_D#1{\xint_UDsignfork#1\XINT_sind_D_n-\XINT_sind_D_p\krof #1}% % \end{macrocode} -% \lverb|The cosd_ auxiliary function| +% \subsubsection{\cshn{@cosd_rr()} function and its support macro \csh{xintCosd}} % \begin{macrocode} -\def\XINT_flexpr_func_cosd_ #1#2#3% +\def\XINT_flexpr_func_@cosd_rr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one{\romannumeral`&&@\xintCosd#3}}% @@ -42494,20 +43281,25 @@ math shift catcode. % ATTENTION ONLY FOR POSITIVE ARGUMENTS % | % \begin{macrocode} -\def\xintCosd#1{\romannumeral`&&@\expandafter\xintcosd - \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}% +\def\XINT_tmpa #1.{% +\def\xintCosd##1% +{% + \romannumeral`&&@\expandafter\xintcosd\romannumeral0\XINTinfloatS[#1]{##1}}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+12.% \def\xintcosd #1[#2#3]% {% \xint_UDsignfork #2\XINT_cosd -\XINT_cosd_int - \krof#2#3.#1..%<< attention extra dot + \krof#2#3.#1..% }% -\def\XINT_cosd #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2. +\def\XINT_tmpa #1.{% +\def\XINT_cosd ##1.##2.% {% \expandafter\XINT_cosd_a - \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}% + \romannumeral0\xinttrunc{#1}{##2[##1]}% }% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+5.% \def\XINT_cosd_a{\expandafter\XINT_cosd_i\the\numexpr\XINT_mod_ccclx_i0.}% \def\XINT_cosd_int {% @@ -42529,390 +43321,433 @@ math shift catcode. % 180, 270, or 360, and avoid abusing A[N] notation which yes speeds up % xintfrac parsing but has its pitfalls.| % \begin{macrocode} -\def\XINT_cosd_A#1{% +\def\XINT_tmpa#1.#2.{% \def\XINT_cosd_A##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_cosd_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_B#1{\xint_UDsignfork#1\XINT_cosd_B_n-\XINT_cosd_B_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_B_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_B_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_C#1{\xint_UDsignfork#1\XINT_cosd_C_n-\XINT_cosd_C_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_C_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_C_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_D#1{\xint_UDsignfork#1\XINT_cosd_D_n-\XINT_cosd_D_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_D_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_D_p##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_E#1{% \def\XINT_cosd_E-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% -}\expandafter -\XINT_cosd_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+4\expandafter.% + \romannumeral`&&@\xintbarefloateval @oneDegree\relax.% +\def\XINT_cosd_B#1{\xint_UDsignfork#1\XINT_cosd_B_n-\XINT_cosd_B_p\krof #1}% +\def\XINT_cosd_C#1{\xint_UDsignfork#1\XINT_cosd_C_n-\XINT_cosd_C_p\krof #1}% +\def\XINT_cosd_D#1{\xint_UDsignfork#1\XINT_cosd_D_n-\XINT_cosd_D_p\krof #1}% % \end{macrocode} -% \subsection{\cshn{sind()}, \cshn{cosd()}} +% \subsection{\cshn{@sind()}, \cshn{@cosd()}} +% \lverb|& +% The -45 is stored internally as -45/1[0] from the action of the unary minus +% operator, which float macros then parse faster. The 45e0 is to let it become +% 45[0] and not simply 45. +% +% Here and below the \ifnum\XINTdigits>8 45\else60\fi will all be resolved +% at time of definition. This is the charm and power of expandable parsers! +% | % \begin{macrocode} -\xintdeffloatfunc sind(x) := (x)?? - {(x>=-45)? - {sin_(x*oneDegree)} - {-sind_(-x)} +\xintdeffloatfunc @sind(x) := (x)?? + {(x>=-\ifnum\XINTdigits>8 45\else60\fi)? + {@sin_series(x*@oneDegree)} + {-@sind_rr(-x)} } - {0} - {(x<=45)? - {sin_(x*oneDegree)} - {sind_(x)} + {0e0} + {(x<=\ifnum\XINTdigits>8 45\else60\fi e0)? + {@sin_series(x*@oneDegree)} + {@sind_rr(x)} } ;% -\xintdeffloatfunc cosd(x) := (x)?? - {(x>=-45)? - {cos_(x*oneDegree)} - {cosd_(-x)} +\xintdeffloatfunc @cosd(x) := (x)?? + {(x>=-\ifnum\XINTdigits>8 45\else60\fi)? + {@cos_series(x*@oneDegree)} + {@cosd_rr(-x)} } - {1} - {(x<=45)? - {cos_(x*oneDegree)} - {cosd_(x)} + {1e0} + {(x<=\ifnum\XINTdigits>8 45\else60\fi e0)? + {@cos_series(x*@oneDegree)} + {@cosd_rr(x)} } ;% % \end{macrocode} -% \subsection{\cshn{sin()}, \cshn{cos()}} +% \subsection{\cshn{@sin()}, \cshn{@cos()}} % \lverb|& % For some reason I did not define sin() and cos() in January 2019 ?? +% +% The sub \xintexpr x*@oneRadian\relax means that the multiplication will be +% done exactly @oneRadian having its 12 extra digits (and x its 4 extra +% digits), before being rounded in entrance of \xintSind, respectively +% \xintCosd, to P+12 mantissa. +% +% The strange 79e-2 could be 0.79 which would give 79[-2] internally too. % | % \begin{macrocode} -\xintdeffloatfunc sin(x):= (abs(x)<0.79)? - {sin_(x)} +\xintdeffloatfunc @sin(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin_series(x)} {(x)?? - {-sind_(-x*oneRadian)} + {-@sind_rr(-\xintexpr x*@oneRadian\relax)} {0} - {sind_(x*oneRadian)} + {@sind_rr(\xintexpr x*@oneRadian\relax)} } ;% -\xintdeffloatfunc cos(x):= (abs(x)<0.79)? - {cos_(x)} - {cosd_(abs(x*oneRadian))} +\xintdeffloatfunc @cos(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@cos_series(x)} + {@cosd_rr(abs(\xintexpr x*@oneRadian\relax))} ;% % \end{macrocode} -% \subsection{\cshn{sinc()}} +% \subsection{\cshn{@sinc()}} % \lverb|& % Should I also consider adding (1-cos(x))/(x^2/2) ? it is sinc^2(x/2) but % avoids a square. % | % \begin{macrocode} -\xintdeffloatfunc sinc(x):= (abs(x)<0.79) ? - {sin_aux(sqr(x))} - {sind_(abs(x)*oneRadian)/abs(x)} +\xintdeffloatfunc @sinc(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi) ? + {@sin_aux(sqr(x))} + {@sind_rr(\xintexpr abs(x)*@oneRadian\relax)/abs(x)} ;% % \end{macrocode} -% \subsection{\cshn{tan()}, \cshn{tand()}, \cshn{cot()}, \cshn{cotd()}} -% \lverb|The 0 in cot(x) is a dummy place holder, 1/0 would raise an error at +% \subsection{\cshn{@tan()}, \cshn{@tand()}, \cshn{@cot()}, \cshn{@cotd()}} +% \lverb|The 0e0 in cot(x) is a dummy place holder, 1/0 would raise an error at % time of definition...| % \begin{macrocode} -\xintdeffloatfunc tand(x):= sind(x)/cosd(x);% -\xintdeffloatfunc cotd(x):= cosd(x)/sind(x);% -\xintdeffloatfunc tan(x) := (x)?? - {(x>-0.79)? - {sin(x)/cos(x)} - {-cotd(90+x*oneRadian) +\xintdeffloatfunc @tand(x):= @sind(x)/@cosd(x);% +\xintdeffloatfunc @cotd(x):= @cosd(x)/@sind(x);% +\xintdeffloatfunc @tan(x) := (x)?? + {(x>-\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin(x)/@cos(x)} + {-@cotd(\xintexpr9e1+x*@oneRadian\relax) } } - {0} - {(x<0.79)? - {sin(x)/cos(x)} - {cotd(90-x*oneRadian)} + {0e0} + {(x<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin(x)/@cos(x)} + {@cotd(\xintexpr9e1-x*@oneRadian\relax)} } ;% -\xintdeffloatfunc cot(x) := (abs(x)<0.79)? - {cos(x)/sin(x)} +\xintdeffloatfunc @cot(x) := (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@cos(x)/@sin(x)} {(x)?? - {-tand(90+x*oneRadian)} - {0} - {tand(90-x*oneRadian)} + {-@tand(\xintexpr9e1+x*@oneRadian\relax)} + {0e0} + {@tand(\xintexpr9e1-x*@oneRadian\relax)} };% % \end{macrocode} -% -% \subsection{\cshn{sec()}, \cshn{secd()}, \cshn{csc()}, \cshn{cscd()}} +% \subsection{\cshn{@sec()}, \cshn{@secd()}, \cshn{@csc()}, \cshn{@cscd()}} % \begin{macrocode} -\xintdeffloatfunc sec(x) := inv(cos(x));% -\xintdeffloatfunc csc(x) := inv(sin(x));% -\xintdeffloatfunc secd(x):= inv(cosd(x));% -\xintdeffloatfunc cscd(x):= inv(sind(x));% +\xintdeffloatfunc @sec(x) := inv(@cos(x));% +\xintdeffloatfunc @csc(x) := inv(@sin(x));% +\xintdeffloatfunc @secd(x):= inv(@cosd(x));% +\xintdeffloatfunc @cscd(x):= inv(@sind(x));% % \end{macrocode} % \subsection{Core routine for inverse trigonometry} +% % \lverb|& -% Compute asin(x) -% -% The approach I shall first describe (which is only a first step towards our -% final approach) converges quintically but requires an initial square root -% computation. For atan(x), we do not have to do any -% such square root extraction. See code next. -% -% The algorithm (for this first approach): we have 0 <= t < 0.72, -% let t1 = t*(1+t^2/6). We also have -% u = sqrt(1 - t^2). We seek a = Arcsin t with t = sin(a). -% -% Then t1 < Arcsin t and the difference (we don't know it!) δ_1 is < 0.02. -% We compute D = t*cos(t1)-u*sin(t1). This computation is done "exactly" via -% the \xintexpr encapsulation. In other terms we use doubled precision. -% Anyhow, currently (1.3e) the Float macros of xintfrac.sty for multiplication -% do go via such exact multiplication when the mantissas have the expected -% sizes. So we can't gain but only lose due to catastrophic subtraction in -% using float operations here. -% -% Thus D is sin(a-t1) = sin(δ_1). And δ_1 = Arcsin D, but D is small! -% We then use again two terms of the Arcsin series and define -% t2 = t1 + D * (1 + D^2/6). Let δ_2 = a - t2. Then δ_2 is of the order of -% the neglected term 3*(δ_1)^5/40. -% -% ©copyright J.F. Burnol, March 30, 2019. This surely has a name. -% -% The algorithm is quintically convergent. -% One can do the same to go from exp to log. Basically the idea is that we can -% improve the Newton Method for any function f for which knowing target value -% of f implies one also knows target value of its derivative. In fact I -% obtained the quintic algorithm by combining the Newton formula with the one -% from using f(x)/f'(a) and not f(x)/f'(x) in the update to cancel the two -% quadratic errors. -% -% One iteration (t2) gives about 9 digits, two iterations (t3) 49 digits ! -% And if we want hepta-convergence we only need to use one more term -% of the Arcsin series in the update of the t_n... really this is very nice. -% -% And actually (t2) already gives 30 digits of floating point precision for -% input t<0.1. Let's confirm this: -%( > Digits := 60: -%: > t0 := 0.1; t1 := t0*(1+t0^2/6); u0 := sqrt(1-t0^2); D1 :=t0*cos(t1)-u0*sin(t1); -%: t0 := 0.1 -%: -%: t1 := 0.100166666666666666666666666666666666666666666666666666666667 -%: -%: u0 := 0.994987437106619954734479821001206005178126563676806079117605 -%: -%: -6 -%: D1 := 0.7544948931296072722324333622021201414040837652959011668 10 -%: -%: > t2 := t1 + D1*(1+D1^2/6); -%: t2 := 0.100167421161559796345523179452674980956388959919827205633117 -%: -%: > a := arcsin(0.1); -%: a := 0.100167421161559796345523179452693318568675972229629541391024 -%: > t2/a; -%: 0.999999999999999999999999999999816930374423480281306812814173 -%) +% I always liked very much the general algorithm whose idea I found +% in 2019. But it costs a square root plus a sine plus a cosine all +% at target precision. For the arctangent the square root will be +% avoided by a trick. % -% Each iteration costs a computation of one cos and one sine done at the full -% final precision. This is stupid because we should compute at an evolving -% precision, but anyhow this is not our problem anymore as our final algorithm -% is not a loop but it does exactly one iteration for all inputs. As -% examplified above it remains true that we could improve its speed for small -% inputs by using shorter auxiliary series (see below). -% -% In January I used a loop via an iter() construct, with some subs() to avoid -% repeating computations. This can only be done in an \xintNewFunction. Here -% is how it looked after some optimization for the stopping criteria, after -% replacing generic Newton algorithm by a specific quintic one for arcsine: -% -%( \begingroup -%: \edef\x{\endgroup -%: \noexpand\xintNewFunction{asin_l}[2]{% -%: iter(##1*(1+sqr(##1)/6);% -%: $% FIXME : réfléchir au critère d'arrêt. -%: $% -%: $% Je n'utilise pas abs(D) pour un micro-gain est-ce que le risque en vaut la -%: $% chandelle ? (avec abs(D) on pourrait utiliser la fonction avec un #1 négatif) -%: $% -%: $% Am I sure rounding errors could not cause neverending loop? -%: $% Such things should be done with increased precision and rounded at end. -%: subs((D<\ifcase\numexpr2+\XINTdigits-5*(\XINTdigits/5)\relax -%: 3.68\or2.32\or1.47\or0.923\or0.582\fi -%: e-\the\numexpr\XINTdigits/5\relax)% -%: ?{break(@+D*(1+sqr(D)/6))}{@+D*(1+sqr(D)/6)},% -%: D=\noexpand\xintexpr -%: subs(##1*cos_aux(X) - ##2*@*sin_aux(X), X=sqr(@))% -%: \relax -%: ),% -%: i=1++)% dummy iteration index, not used but needed by iter() -%: }}\x -%) +% And now I like it even more as I have re-done the first step entirely +% in a single \numexpr... Thus the inverse trigonometry got a serious +% improvement at 1.4e... +% +% Here is the idea. We have 0<t<sqrt(2)/2 and we want a = Arcsin t. +% +% Imagine we have some very good approximation b = a - h. We know b, +% and don't know yet h. No problem h is a-b so sin(h)=sin(a)cos(b)- +% cos(a)sin(b). And we know everything here: sin(a) is t, cos(a) is +% u = sqrt(1-t^2), and we can compute cos(b) and sin(b). +% +% I said h was small so the computation of sin(a)cos(b)-cos(a)sin(b) will +% involve a lot of cancellation, no problem with xint, as it knows how to +% compute exactly... and if we wanted to go very low level we could do +% cos(a)sin(b) paying attention only on least significant digits. +% +% Ok, so we have sin(h), but h is small, so the series of Arcsine can be used +% with few terms! % -% I don't have time to explain the final algorithm below and how the -% transition values were chosen or why (the series below is enough up to 59 -% digits of precision). It does only one iteration, in all cases. Using it for -% arcsine requires a preliminary square root extraction, but for arctangent -% one arranges things to avoid having to compute a square root. +% In fact h will be at most of the order of 1e-9, so it is no problem to +% simply replace sin(h) with h if the target precision is 16 ! % +% Ok, so how do we obtain b, the good approximation to Arcsin t ? Simply by +% using its Taylor series, embedded in a single \numexpr working with nine +% digits numbers... I like this one! Notice that it reminisces with my +% questioning about how to best do Horner like for sine and cosine. Here in +% \numexpr we can only manipulate whole integers and simply can't do things +% such as ...)*x + 5/112)*x + 3/40)*x + 1/6)*x +1 .... But I found another +% way, see the code, which uses extensively the "scaling" operations in +% \numexpr. +% +% I have not proven rigorously that b-a is always less or equal in absolute +% value than 1e-9, but it is possible for example in Python to program it and +% go through all possible (less than) 1e9 inputs and check what happens. +% +% Very small inputs will give b=0 (first step is a fixe point rounding of t to +% nine fractional digits, so this rounding gives zero for input <0.5e-9, +% others will give b=t, because the arcsine numexpr will end up with +% 1000000000 (last time I checked that was for t a bit less than 5e-5, +% the latter gives 1000000001). +% All seems to work perfectly fine, in practice... % -% ©copyright J.F. Burnol, April 5, 2019. This surely has a name. % -% Certainly I can do similar things to compute logarithms. % | +% +% \lverb|First we let the @sin_aux() and @cos_aux() functions be usable in exact +% \xintexpr context. +% +% The @asin_II() function will be used only for Digits>16.| % \begin{macrocode} -\xintdeffloatfunc asin_aux(X) := 1 -\ifnum\XINTdigits>3 % actually 4 would achieve 1ulp in place of <0.5ulp - + X(1/6 -\ifnum\XINTdigits>9 - + X(3/40 +\expandafter\let\csname XINT_expr_func_@sin_aux\expandafter\endcsname + \csname XINT_flexpr_func_@sin_aux\endcsname +\expandafter\let\csname XINT_expr_func_@cos_aux\expandafter\endcsname + \csname XINT_flexpr_func_@cos_aux\endcsname \ifnum\XINTdigits>16 - + X(5/112 -\ifnum\XINTdigits>25 - + X(35/1152 -\ifnum\XINTdigits>35 - + X(63/2816 -\ifnum\XINTdigits>46 - + X(231/13312 - )\fi)\fi)\fi)\fi)\fi)\fi;% -\xintdeffloatfunc asin_o(D, T) := T + D*asin_aux(sqr(D));% -\xintdeffloatfunc asin_n(V, T, t, u) :=% V is square of T - asin_o (\xintexpr t*cos_aux(V) - u*T*sin_aux(V)\relax, T);% -\xintdeffloatfunc asin_m(T, t, u) := asin_n(sqr(T), T, t, u);% -\xintdeffloatfunc asin_l(t, u) := asin_m(t*asin_aux(sqr(t)), t, u);% -% \end{macrocode} -% \subsection{\cshn{asin()}, \cshn{asind()}} +\def\XINT_flexpr_func_@asin_II#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_Arcsin_II_a#3}}% +}% +\def\XINT_tmpc#1.% +{% +\def\XINT_Arcsin_II_a##1% +{% + \expandafter\XINT_Arcsin_II_c_i\romannumeral0\XINTinfloatS[#1]{##1}% +}% +\def\XINT_Arcsin_II_c_i##1[##2]% +{% + \xintAdd{1/1[0]}{##1/6[##2]}% +}% +}% +\expandafter\XINT_tmpc\the\numexpr\XINTdigits-14.% +\fi +\ifnum\XINTdigits>34 +\def\XINT_tmpc#1.#2.#3.#4.% +{% +\def\XINT_Arcsin_II_a##1% +{% + \expandafter\XINT_Arcsin_II_a_iii\romannumeral0\XINTinfloatS[#1]{##1}\xint: +}% +\def\XINT_Arcsin_II_a_iii##1\xint: +{% + \expandafter\XINT_Arcsin_II_b\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_b##1\xint: +{% + \expandafter\XINT_Arcsin_II_c_i\romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def\XINT_Arcsin_II_c_i##1\xint:##2\xint: +{% + \xintAdd{1/1[0]}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}% +}% +}% +\expandafter\XINT_tmpc + \the\numexpr\XINTdigits-14\expandafter.% + \the\numexpr\XINTdigits-32\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-32]{3/40[0]}.% + \XINTinFloat[\XINTdigits-14]{1/6[0]}.% + }% +\fi +\ifnum\XINTdigits>52 +\def\XINT_tmpc#1.#2.#3.#4.#5.% +{% +\def\XINT_Arcsin_II_a_iii##1\xint: +{% + \expandafter\XINT_Arcsin_II_a_iv\romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_a_iv##1\xint: +{% + \expandafter\XINT_Arcsin_II_b\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_b##1\xint: +{% + \expandafter\XINT_Arcsin_II_c_ii + \romannumeral0\xintadd{#4}{\XINTinfloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def\XINT_Arcsin_II_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_Arcsin_II_c_i + \romannumeral0\xintadd{#5}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}\xint: +}% +}% +\expandafter\XINT_tmpc + \the\numexpr\XINTdigits-32\expandafter.% + \the\numexpr\XINTdigits-50\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-50]{5/112[0]}.% + \XINTinFloat[\XINTdigits-32]{3/40[0]}.% + \XINTinFloat[\XINTdigits-14]{1/6[0]}.% + }% +\fi +\def\XINT_flexpr_func_@asin_I#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_Arcsin_I#3}}% +}% +\def\XINT_Arcsin_I#1{\the\numexpr\expandafter\XINT_Arcsin_Ia\romannumeral0\xintiround9{#1}.}% +\def\XINT_Arcsin_Ia#1.% +{% + (\expandafter\XINT_Arcsin_Ib\the\numexpr#1*#1/\xint_c_x^ix.)*% + #1/\xint_c_x^ix[-9]% +}% +\def\XINT_Arcsin_Ib#1.% +{%(((((((((((((((( + % 3481/3660)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 3249/3422)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 3025/3192)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2809/2970)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2601/2756)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2401/2550)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2209/2352)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2025/2162)*#1/\xint_c_x^ix+\xint_c_x^ix)*% +((((((((((((((((((((((((((((((((((((((((((% + %(\xint_c_x^ix*1849/1980)*% + 933838384*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1681/1806)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1521/1640)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1369/1482)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1225/1332)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1089/1190)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 961/1056)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 841/930)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 729/812)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 625/702)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 529/600)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 441/506)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 361/420)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 289/342)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 225/272)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 169/210)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 121/156)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 81/110)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 49/72)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 25/42)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 9/20)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1/6)*#1/\xint_c_x^ix+\xint_c_x^ix +}% +\ifnum\XINTdigits>16 + \xintdeffloatfunc @asin_o(D, T) := T + D*@asin_II(sqr(D));% + \xintdeffloatfunc @asin_n(V, T, t, u) :=% + @asin_o(\xintexpr t*@cos_aux(V) - u*T*@sin_aux(V)\relax, T);% +\else + \xintdeffloatfunc @asin_n(V, T, t, u) :=% + \xintexpr t*@cos_aux(V) - u*T*@sin_aux(V)\relax + T;% +\fi +\xintdeffloatfunc @asin_m(T, t, u) := @asin_n(sqr(T), T, t, u);% +\xintdeffloatfunc @asin_l(t, u) := @asin_m(@asin_I(t), t, u);% +% \end{macrocode} +% \subsection{\cshn{@asin()}, \cshn{@asind()}} % \lverb|& % Only non-negative arguments t and u for asin_a(t,u), and asind_a(t,u). -% | -% -% \lverb|At 1.4 usage of sqrt_() which has only one argument, whereas -% currently sqrt() admits a second optional argument hence sub-optimality here -% if we use sqrt(), especially since 1.4 handles more fully such functions -% with optional argument in \xintdeffunc. -% -% Actually thinking of making sqrt() a one argument only function and -% sqrt_() will be the one with two arguments. But I worked hard on the -% \xintdeffunc hooks, thus some reticence, because why then not do that -% for all others?| +% | % \begin{macrocode} -\xintdeffloatfunc asin_a(t, u) := (t<u)? - {asin_l(t, u)} - {Piover2 - asin_l(u, t)} +\xintdeffloatfunc @asin_a(t, u) := (t<u)? + {@asin_l(t, u)} + {@Piover2 - @asin_l(u, t)} ;% -\xintdeffloatfunc asind_a(t, u):= (t<u)? - {asin_l(t, u) * oneRadian} - {90 - asin_l(u, t) * oneRadian} +\xintdeffloatfunc @asind_a(t, u):= (t<u)? + {@asin_l(t, u) * @oneRadian} + {9e1 - @asin_l(u, t) * @oneRadian} ;% -\xintdeffloatfunc asin(t) := (t)?? - {-asin_a(-t, sqrt_(1-sqr(t)))} - {0} - {asin_a(t, sqrt_(1-sqr(t)))} +\xintdeffloatfunc @asin(t) := (t)?? + {-@asin_a(-t, sqrt(1e0-sqr(t)))} + {0e0} + {@asin_a(t, sqrt(1e0-sqr(t)))} ;% -\xintdeffloatfunc asind(t) := (t)?? - {-asind_a(-t, sqrt_(1-sqr(t)))} - {0} - {asind_a(t, sqrt_(1-sqr(t)))} +\xintdeffloatfunc @asind(t) := (t)?? + {-@asind_a(-t, sqrt(1e0-sqr(t)))} + {0e0} + {@asind_a(t, sqrt(1e0-sqr(t)))} ;% % \end{macrocode} -% \subsection{\cshn{acos()}, \cshn{acosd()}} +% \subsection{\cshn{@acos()}, \cshn{@acosd()}} % \begin{macrocode} -\xintdeffloatfunc acos(t) := Piover2 - asin(t);% -\xintdeffloatfunc acosd(t):= 90 - asind(t);% +\xintdeffloatfunc @acos(t) := @Piover2 - @asin(t);% +\xintdeffloatfunc @acosd(t):= 9e1 - @asind(t);% % \end{macrocode} -% \subsection{\cshn{atan()}, \cshn{atand()}} +% \subsection{\cshn{@atan()}, \cshn{@atand()}} % \lverb|& -% This involves no square root! -% -% TeX hackers note 1: -% -% The subs( , x = ..) mechanism has no utility in a function definition, -% there is no parallel mechanism at the underlying macros, so in fact -% the substituted things will remain unevaluated if they involve -% indeterminates, so this is exactly like not trying to make things -% more efficient at all. -% -% Currently, the only way is thus to employ auxiliary functions like is done -% next. Contrarily to TeX macros, we must define the functions one after the -% other in the correct order, so the auxiliaries come first. -% -% TeX hackers note 2: -% -% At 1.4, the way to inject lazy conditionals in function definitions has changed. -% Prior one used if(,,) and ifsgn(,,,) which was counter-intuitive because -% in pure numeric context they evaluate all branches. Now one must use ? and ?? -% which the are the lazy conditionals from the numeric context. -% +% Uses same core routine asin_l() as for asin(), but avoiding a square-root +% extraction in preparing its arguments (to the cost of computing an inverse, +% rather). % % radians % | % \begin{macrocode} -\xintdeffloatfunc atan_b(t, w, z):= 0.5 * (w< 0)? - {Pi - asin_a(2z * t, -w*z)} - {asin_a(2z * t, w*z)} +\xintdeffloatfunc @atan_b(t, w, z):= 5e-1 * (w< 0)? + {@Pi - @asin_a(2e0*z * t, -w*z)} + {@asin_a(2e0*z * t, w*z)} ;% -\xintdeffloatfunc atan_a(t, T) := atan_b(t, 1-T, inv(1+T));% -\xintdeffloatfunc atan(t):= (t)?? - {-atan_a(-t, sqr(t))} +\xintdeffloatfunc @atan_a(t, T) := @atan_b(t, 1e0-T, inv(1e0+T));% +\xintdeffloatfunc @atan(t):= (t)?? + {-@atan_a(-t, sqr(t))} {0} - {atan_a(t, sqr(t))} + {@atan_a(t, sqr(t))} ;% % \end{macrocode} % \lverb|& % degrees % | % \begin{macrocode} -\xintdeffloatfunc atand_b(t, w, z) := 0.5 * (w< 0)? - {180 - asind_a(2z * t, -w*z)} - {asind_a(2z * t, w*z)} +\xintdeffloatfunc @atand_b(t, w, z) := 5e-1 * (w< 0)? + {18e1 - @asind_a(2e0*z * t, -w*z)} + {@asind_a(2e0*z * t, w*z)} ;% -\xintdeffloatfunc atand_a(t, T) := atand_b(t, 1-T, inv(1+T));% -\xintdeffloatfunc atand(t) := (t)?? - {-atand_a(-t, sqr(t))} +\xintdeffloatfunc @atand_a(t, T) := @atand_b(t, 1e0-T, inv(1e0+T));% +\xintdeffloatfunc @atand(t) := (t)?? + {-@atand_a(-t, sqr(t))} {0} - {atand_a(t, sqr(t))} + {@atand_a(t, sqr(t))} ;% % \end{macrocode} -% \subsection{\cshn{Arg()}, \cshn{atan2()}, \cshn{Argd()}, \cshn{atan2d()}, \cshn{pArg()}, \cshn{pArgd()}} +% \subsection{\cshn{@Arg()}, \cshn{@atan2()}, \cshn{@Argd()}, \cshn{@atan2d()}, \cshn{@pArg()}, \cshn{@pArgd()}} % \lverb|& % Arg(x,y) function from -π (excluded) to +π (included) % | % \begin{macrocode} -\xintdeffloatfunc Arg(x, y):= (y>x)? +\xintdeffloatfunc @Arg(x, y):= (y>x)? {(y>-x)? - {Piover2 - atan(x/y)} + {@Piover2 - @atan(x/y)} {(y<0)? - {-Pi + atan(y/x)} - {Pi + atan(y/x)} + {-@Pi + @atan(y/x)} + {@Pi + @atan(y/x)} } } {(y>-x)? - {atan(y/x)} - {-Piover2 + atan(x/-y)} + {@atan(y/x)} + {-@Piover2 + @atan(x/-y)} } ;% % \end{macrocode} @@ -42921,23 +43756,23 @@ math shift catcode. % but the convention here seems the most often encountered) % | % \begin{macrocode} -\xintdeffloatfunc atan2(y,x) := Arg(x, y);% +\xintdeffloatfunc @atan2(y,x) := @Arg(x, y);% % \end{macrocode} % \lverb|& % Argd(x,y) function from -180 (excluded) to +180 (included) % | % \begin{macrocode} -\xintdeffloatfunc Argd(x, y):= (y>x)? +\xintdeffloatfunc @Argd(x, y):= (y>x)? {(y>-x)? - {90 - atand(x/y)} + {9e1 - @atand(x/y)} {(y<0)? - {-180 + atand(y/x)} - {180 + atand(y/x)} + {-18e1 + @atand(y/x)} + {18e1 + @atand(y/x)} } } {(y>-x)? - {atand(y/x)} - {-90 + atand(x/-y)} + {@atand(y/x)} + {-9e1 + @atand(x/-y)} } ;% % \end{macrocode} @@ -42945,24 +43780,24 @@ math shift catcode. % atan2d(y,x) = Argd(x,y) % | % \begin{macrocode} -\xintdeffloatfunc atan2d(y,x) := Argd(x, y);% +\xintdeffloatfunc @atan2d(y,x) := @Argd(x, y);% % \end{macrocode} % \lverb|& % pArg(x,y) function from 0 (included) to 2π (excluded) % I hesitated between pArg, Argpos, and Argplus. Opting for pArg in the end. % | % \begin{macrocode} -\xintdeffloatfunc pArg(x, y):= (y>x)? +\xintdeffloatfunc @pArg(x, y):= (y>x)? {(y>-x)? - {Piover2 - atan(x/y)} - {Pi + atan(y/x)} + {@Piover2 - @atan(x/y)} + {@Pi + @atan(y/x)} } {(y>-x)? {(y<0)? - {twoPi + atan(y/x)} - {atan(y/x)} + {@twoPi + @atan(y/x)} + {@atan(y/x)} } - {threePiover2 + atan(x/-y)} + {@threePiover2 + @atan(x/-y)} } ;% % \end{macrocode} @@ -42970,54 +43805,92 @@ math shift catcode. % pArgd(x,y) function from 0 (included) to 360 (excluded) % | % \begin{macrocode} -\xintdeffloatfunc pArgd(x, y):=(y>x)? +\xintdeffloatfunc @pArgd(x, y):=(y>x)? {(y>-x)? - {90 - atan(x/y)*oneRadian} - {180 + atan(y/x)*oneRadian} + {9e1 - @atan(x/y)*@oneRadian} + {18e1 + @atan(y/x)*@oneRadian} } {(y>-x)? - {(y<0)? - {360 + atan(y/x)*oneRadian} - {atan(y/x)*oneRadian} + {(y<0e0)? + {36e1 + @atan(y/x)*@oneRadian} + {@atan(y/x)*@oneRadian} } - {270 + atan(x/-y)*oneRadian} + {27e1 + @atan(x/-y)*@oneRadian} } ;% % \end{macrocode} -% \subsection{Synonyms: \cshn{tg()}, \cshn{cotg()}} -% \lverb|These are my childhood notations and I am attached to them. In -% radians only. We skip some overhead here by using a \let at core level.| -% \begin{macrocode} -\expandafter\let\csname XINT_flexpr_func_tg\expandafter\endcsname - \csname XINT_flexpr_func_tan\endcsname -\expandafter\let\csname XINT_flexpr_func_cotg\expandafter\endcsname - \csname XINT_flexpr_func_cot\endcsname +% \subsection{Restore \cs{xintdeffloatfunc} to its normal state, with no extra +% digits} +% \begin{macrocode} +\expandafter\let + \csname XINT_flexpr_exec_+\expandafter\endcsname + \csname XINT_flexpr_exec_+_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_-\expandafter\endcsname + \csname XINT_flexpr_exec_-_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_*\expandafter\endcsname + \csname XINT_flexpr_exec_*_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_/\expandafter\endcsname + \csname XINT_flexpr_exec_/_\endcsname +\expandafter\let + \csname XINT_flexpr_func_sqr\expandafter\endcsname + \csname XINT_flexpr_sqrfunc\endcsname +\expandafter\let + \csname XINT_flexpr_func_sqrt\expandafter\endcsname + \csname XINT_flexpr_sqrtfunc\endcsname +\expandafter\let + \csname XINT_flexpr_func_inv\expandafter\endcsname + \csname XINT_flexpr_invfunc\endcsname % \end{macrocode} % \subsection{Let the functions be known to the \cshnolabel{xintexpr} parser} -% \lverb|See xint.pdf for some explanations (as well as code comments in -% xintexpr.sty). In fact it is this context which led to my addition at 1.3e of -% \xintdefefunc to the \xintexpr syntax. | +% \lverb|& +% | % \begin{macrocode} \xintFor #1 in {sin, cos, tan, sec, csc, cot, asin, acos, atan}\do {% - \xintdeffunc #1(x) := \xintfloatexpr #1(sfloat(x))\relax;% - \xintdeffunc #1d(x):= \xintfloatexpr #1d(sfloat(x))\relax;% + \xintdeffloatfunc #1(x) := float_(@#1(x));% + \xintdeffloatfunc #1d(x) := float_(@#1d(x));% + \xintdeffunc #1(x) := float_(\xintfloatexpr @#1(sfloat(x))\relax);% + \xintdeffunc #1d(x):= float_(\xintfloatexpr @#1d(sfloat(x))\relax);% }% \xintFor #1 in {Arg, pArg, atan2}\do {% - \xintdeffunc #1(x, y) := \xintfloatexpr #1(sfloat(x), sfloat(y))\relax;% - \xintdeffunc #1d(x, y):= \xintfloatexpr #1d(sfloat(x), sfloat(y))\relax;% + \xintdeffloatfunc #1(x, y) := float_(@#1(x, y));% + \xintdeffloatfunc #1d(x, y) := float_(@#1d(x, y));% + \xintdeffunc #1(x, y) := float_(\xintfloatexpr @#1(sfloat(x), sfloat(y))\relax);% + \xintdeffunc #1d(x, y):= float_(\xintfloatexpr @#1d(sfloat(x), sfloat(y))\relax);% }% -\xintdeffunc tg(x) := \xintfloatexpr tg(sfloat(x))\relax;% -\xintdeffunc cotg(x):= \xintfloatexpr cotg(sfloat(x))\relax;% -\xintdeffunc sinc(x):= \xintfloatexpr sinc(sfloat(x))\relax;% +\xintdeffloatfunc sinc(x):= float_(@sinc(x));% +\xintdeffunc sinc(x):= float_(\xintfloatexpr @sinc(sfloat(x))\relax);% % \end{macrocode} +% \subsection{Synonyms: \cshn{@tg()}, \cshn{@cotg()}} +% \lverb|These are my childhood notations and I am attached to them. In +% radians only, and for \xintfloateval only. We skip some overhead here by using a \let at core level.| +% \begin{macrocode} +\expandafter\let\csname XINT_flexpr_func_tg\expandafter\endcsname + \csname XINT_flexpr_func_tan\endcsname +\expandafter\let\csname XINT_flexpr_func_cotg\expandafter\endcsname + \csname XINT_flexpr_func_cot\endcsname +% \end{macrocode} +% \subsection{Final clean-up} % \lverb|Restore used dummy variables to their status prior to the package reloading. % On first loading this is not needed naturally, because this is done % immediately at end of xintexpr.sty.| % \begin{macrocode} +\xintdeffloatvar twoPi := @twoPi;% +\xintdeffloatvar threePiover2 := @threePiover2;% +\xintdeffloatvar Pi := @Pi;% +\xintdeffloatvar Piover2 := @Piover2;% +\xintdeffloatvar oneDegree := @oneDegree;% +\xintdeffloatvar oneRadian := @oneRadian;% +\xintunassignvar{@twoPi}\xintunassignvar{@threePiover2}% +\xintunassignvar{@Pi}\xintunassignvar{@Piover2}% +\xintunassignvar{@oneRadian}\xintunassignvar{@oneDegree}% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintrestorevariable{#1}}% +\XINTtrigendinput% % \end{macrocode} % \StoreCodelineNo {xinttrig} % \cleardoublepage\let\xinttrignameUp\undefined @@ -43026,7 +43899,7 @@ math shift catcode. %\let<*xintlog>\gardesinactifs %</xinttrig>^^A-------------------------------------------------- %<*xintlog>^^A--------------------------------------------------- -%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; -*- +%^^A -*- coding: utf-8; mode: doctex; fill-column: 78; sentence-end-double-space: t; -*- % \clearpage\csname xintlognameUp\endcsname % \section{Package \xintlognameimp implementation} % \RaisedLabel{sec:logimp} @@ -43037,12 +43910,101 @@ math shift catcode. % % \etocsettocstyle{}{} % -% I almost included extended precision implementation for 1.3e but -% was a bit short on time; besides I hesitated between using poormanlog -% at starting point or not. For up to 50 digits, it would help reduce -% considerably the needed series for the logarithm. For more digits -% I should rather apply my copyrighted method of the arcsine (it must -% be in literature). +% In 2019, at 1.3e release I almost included extended precision for log() and +% exp() but the time I could devote to xint expired. Finally, at long last, +% (and I had procrastinated far more than the two years since 2019) the 1.4e +% release in April 2021 brings log10(), pow10(), log(), pow() to P=Digits +% precision: up to 62 digits with at least (said roughly) 99\% chances of +% correct rounding (the design is targeting less than about 0.005ulp distance +% to mathematical value, before rounding). +% +% Implementation is EXPERIMENTAL. +% +% For up to Digits=8, it is simply based upon the poormanlog package. The +% probability of correct rounding will be less than for Digits>8, especially +% in the cases of Digits=8 and to a lesser extent Digits=7. And, for all +% Digits<=8, there is a systematic loss of rounding precision in the floating +% point sense in the case of log10(x) for inputs close to 1: +% +% \lverb|& +% +% Summary of limitations of log10() and pow10() in the case of Digits<=8: +%( - For log10(x) with x near 1, the precision of output as floating point& +% will be mechanically reduced from the fact that this is based on a fixed& +% point result, for example log10(1.0011871) is produced as 5.15245e-4,& +% which stands for 0.000515145 having indeed 9 correct fractional digits,& +% but only 6 correct digits in the floating point sense.& +% +% This feature affects the entire range Digits<=8. +%: - Even if limiting to inputs x with 1.26<x<10 (1.26 is a bit more than& +% 10^0.1 hence its choice as lower bound), the poormanlog documentation& +% mentions an absolute error possibly up to about 1e-9. In practice a& +% test of 10000 random inputs 1.26<x<10 revealed 9490 correctly rounded& +% log10(x) at 8 digits (and the 510 non-correctly rounded ones with an error& +% of 1 in last digit compared to correct rounding). So correct rounding& +% achieved only in about 95$% of cases here.& +% +% At 7 digits the same 10000 random& +% inputs are correctly rounded in 99.4$% of cases, and at 6 digits it is& +% 99.94$% of cases.& +% +% Againd with Digits=8, the log10(i) for i in 1..1000 are all correctly& +% rounded to 8 digits with two exceptions: log10(3) and log10(297) with a& +% 1ulp error. +%: - Regarding the computation of 10^x, I obtained for -1<x<1 the following& +% with 10000 random inputs: 518/10000 errors at 1ulp, 60/10000, and 8/10000,& +% at respectively Digits = 8, 7, 6 so chances of correct rounding are& +% respectively about 95$%, 99.4$% and more than 99.9$%. +%) +% | +% +% Despite its limitations the poormanlog based approach used for Digits up to +% 8 has the advantage of speed (at least 8X compared to working with 16 +% digits) and is largely precise enough for plots. +% +% For 9 digits or more, the observed precision in some random tests appears to +% be at least of 99.9\% chances of correct rounding, and the log10(x) with x +% near 1 are correctly (if not really efficiently) handled in the floating +% point sense for the output. The poormanlog approximate log10() is still used +% to boot-strap the process, generally. The pow10() at Digits=9 or more is +% done independently of poormanlog. +% +% All of this is done on top of my 2013 structures for floating point +% computations which have always been marked as provisory and rudimentary and +% instills intrinsic non-efficiency: +% +%\lverb|& +%( - no internal data format for a ``floating point number at P digits'', +%: - mantissa lengths are again and again computed, +%: - digits are not pre-organized say in blocks of 4 by 4 or 8 by 8, +%: - floating point multiplication is done via an *exact* multiplication, then& +% rounding to P digits! +%) +% | +% +% This is legacy of the fact that the project was initially devoted to big +% integers only, but in the weeks that followed its inception in March 2013 I +% added more and more functionalities without a well laid out preliminary +% plan. +% +% Anyway, for years I have felt a better foundation would help achieve at +% least something such as 2X gain (perhaps the last item by itself, if +% improved upon, would bring most of such 2X gain?) +% +% I did not try to optimize for the default 16 digits, the goal being more of +% having a general scalable structure in place and there is no difficulty to +% go up to 100 digits precision if one stores extended pre-computed constants +% and increases the length of the ``series'' support. +% +% Apart from log(10) and its inverse, no other logarithms are stored or +% pre-computed: the rest of the stored data is the same for pow10() and +% log10() and consists of the fractional powers 10\string^±0.i, +% 10\string^±0.0i, ..., 10\string^±0.00000i at P+5 and also at P+10 digits. +% +% In order to reduce the loading time of the package the inverses are not +% computed internally (as this would require costly divisions) but simply +% hard-coded with enough digits to cover the allowed Digits range. +% % % \subsection{Catcodes, \protect\eTeX{} and reload detection} % \begin{macrocode} @@ -43061,7 +44023,6 @@ math shift catcode. \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname - \expandafter\let\expandafter\x\csname ver@xintlog.sty\endcsname \expandafter \ifx\csname PackageInfo\endcsname\relax \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% @@ -43080,224 +44041,2296 @@ math shift catcode. \else\string\input\space xintexpr.sty \fi rather, aborting}% \aftergroup\endinput - \else - \ifx\x\relax % first loading (initiated from xintexpr.sty) - \else - \ifx\x\empty % LaTeX first loading, \ProvidesPackage not yet seen - \else - \y{xintlog}{Already loaded, aborting}% - \aftergroup\endinput - \fi - \fi \fi \fi \z% +\edef\XINTendxintloginput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% % \end{macrocode} -% \lverb|Attention to catcode regime when loading below poormanlog. It (v0.04) -% uses ^ with its normal catcode but \XINT_setcatcodes would set it to letter. +% \subsection{Library identification} +% \begin{macrocode} +\ifcsname xintlibver@log\endcsname + \expandafter\xint_firstoftwo +\else + \expandafter\xint_secondoftwo +\fi +{\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2021/05/05 v1.4e}% +\XINT_providespackage +\ProvidesPackage{xintlog}% +[2021/05/05 v1.4e Logarithms and exponentials for xintexpr (JFB)]% +}% +% \end{macrocode} +% \subsection{\csh{xintreloadxintlog}} +% \lverb|Now needed at 1.4e. % -% This file can only be loaded from xintexpr.sty and it restores catcodes near -% its end. To play it safe and be hopefully immune to whatever is done in -% poormanlog or in xinttrig.sty which is loaded before, we will switch to -% standard catcode regime here. +% | +% \begin{macrocode} +\def\xintreloadxintlog{\input xintlog.sty }% +% \end{macrocode} +% \subsection{Loading the \cshn{poormanlog} package} +% \lverb|& +% Attention to the catcode regime when loading poormanlog. % % As I learned the hard way (I never use my user macros), at the worst moment % when wrapping up the final things for 1.3e release, % \xintexprSafeCatcodes MUST be followed by some \xintexprRestoreCatcodes % quickly, else next time it is used (for example by \xintdefvar) the -% \xintexprRestoreCatcodes will restore an obsolete catcode regime...| -% \subsection{Library identification} +% \xintexprRestoreCatcodes will restore an obsolete catcode regime... +% +% Also, for xintlog.sty to be multiple-times loadable, we need to avoid using +% LaTeX's \RequirePackage twice.| % \begin{macrocode} \xintexprSafeCatcodes\catcode`_ 11 -\XINT_providespackage -\ProvidesPackage{xintlog}% -[2021/03/29 v1.4d Logarithms and exponentials for xintexpr (JFB)]% -% \end{macrocode} -% \subsection{Loading of \cshn{poormanlog} package} -% \lverb|Attention to catcode regime when loading poormanlog. It matters less -% now for 1.3f as those chunks of code from poormanlog.tex v0.04 which needed -% specific xintexpr like catcodes got transferred here anyway.| -% \begin{macrocode} +\unless\ifdefined\XINTinFloatPowTen \ifdefined\RequirePackage \RequirePackage{poormanlog}% \else \input poormanlog.tex +\fi\fi +\xintexprRestoreCatcodes\XINTsetcatcodes +% \end{macrocode} +% \subsection{Macro layer on top of the poormanlog package} +% \lverb|This was moved here with some macro renames from xintfrac on occasion +% of 1.4e release. +% +% Breaking changes at 1.4e: +% +%( - these macros will be mapped to log10(), log(), pow10(), exp(), pow(,)& +% and the ** and ^ (if \poormanloghack) only for Digits at most 8 +%: - \xintLog was used for \xinteval and differed slightly from its& +% counterpart used for \xintfloateval, the latter float-rounded& +% to P = Digits, the former did not and kept completly meaning-less& +% digits in output. Both macros now replaced by a \PoorManLog& +% which will always float round the output to P = Digits. Because xint& +% does not really implement a fixed point interface anyhow. +%: - \xintExp (used in \xinteval) and another macro (used in \xintfloateval)& +% did not use a sufficiently long approximation to 1/log(10) to& +% support precisely enough exp(x) if output of the order of 10^10000 for& +% example, (last two digits wrong then)& +% and situation became worse for very high values such as exp(1e8)& +% which had only 4 digits correct. +% The new \PoorManExp which replaces them is more careful... and for& +% example exp(12345678) obtains correct rounding (Digits=8). +%: - \XINTinFloatxintLog and \XINTinFloatxintExp were removed; they were& +% used for log() and exp() in \xintfloateval, and differed from \xintLog& +% and \xintExp a bit, now renamed to \PoorManLog and \PoorManExp. +%: - \PoorManPower has simply disappeared, see \XINTinFloatSciPow and \xintPow. +%) +% +% See the general xintlog introduction for some comments on the achieved +% precision and probabilities of correct rounding. +% +% | +% +% \subsubsection{\csh{PoorManLogBaseTen}, \csh{PoorManLog}} +% \lverb|1.3f. Code originally in poormanlog v0.04 got transferred here. It +% produces the logarithm in base 10 with an error (believed to be at most) of +% the order of 1 unit in the 9th (i.e. last, fixed point) fractional +% digit. Testing seems to indicate the error is never exceeding 2 units in the +% 9th place, in worst cases. +% +% These macros will still be the support macros for \xintfloatexpr log10(), +% pow10(), etc... up to Digits=8 and the poormanlog logarithm is used as +% starting point for higher precision if Digits is at least 9. +% +% Notice that \PML@999999999. expands (in \numexpr) to 1000000000 (ten +% digits), which is the only case with the output having ten digits. But there +% is no need here to treat this case especially, it works fine in +% \PML@logbaseten. +% +% Breaking change at 1.4e: for consistency with various considerations +% on floats, the output will be float rounded to P=Digits. +% +% One could envision the \xinteval variant to keep 9 fractional digits +% (it is known the last one may very well be off by 1 unit). But this +% creates complications of principles. +% +% All of this is very strange because the logarithm clearly shows the +% deficiencies of the whole idea of floating point arithmetic, logarithm goes +% from floating point to fixed point, and coercing it into pure floating point +% has moral costs. Anyway, I shall obide. +% +% | +% \begin{macrocode} +\def\PoorManLogBaseTen{\romannumeral0\poormanlogbaseten}% +\def\poormanlogbaseten #1% +{% + \XINTinfloat[\XINTdigits]% + {\romannumeral0\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]{#1}}% +}% +\def\PoorManLogBaseTen_raw%#1 +{% + \romannumeral0\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]%{#1}% +}% +\def\PML@logbaseten#1[#2]% +{% + \xintiiadd{\xintDSx{-9}{\the\numexpr#2+8\relax}}{\the\numexpr\PML@#1.}[-9]% +}% +\def\PoorManLog#1% +{% + \XINTinFloat[\XINTdigits]{\xintMul{\PoorManLogBaseTen_raw{#1}}{23025850923[-10]}}% +}% +% \end{macrocode} +% \subsubsection{\csh{PoorManPowerOfTen}, \csh{PoorManExp}} +% \lverb|Originally in poormanlog v0.04, got transferred into xintfrac.sty at +% 1.3f, then here into xintlog.sty at 1.4e. +% +% Produces 10^x with 9 digits of float precision, with an error (believed to +% be) at most 2 units in the last place, when 0<x<1. Of course for this the +% input must be precise enough to have 9 fractional digits of **fixed point** +% precision. +% +% Breaking change at 1.4e: output always float-rounded at P=Digits. +% +% The 1.3f definition for \xintExp (now \PoorManExp) was not careful enough +% (see comments above) for very large exponents. This has been corrected at +% 1.4e. Formerly exp(12345678) produced shameful 6.3095734e5361659 where only +% the first digit (and exponent...) is correct! Now, with \xintDigits*:=8;, +% exp(12345678) will produce 6.7725836e5361659 which is correct rounding to 8 +% digits. Sorry if your rover expedition to Mars ended in failure due to using +% my software. I was not expecting anyone to use it so I did back then in 2019 +% a bit too expeditively the \xintExp thing on top of 10^x. +% +% The 1.4e \PoorManExpr replaces and amends deceased \xintExp. +% +% Before using \xintRound we screen out the case of zero as \xintRound in this +% case outputs no fractional digits. +% | +% \begin{macrocode} +\def\PoorManPowerOfTen{\romannumeral0\poormanpoweroften}% +\def\poormanpoweroften #1% +{% + \expandafter\PML@powoften@out + \the\numexpr\expandafter\PML@powoften\romannumeral0\xintraw{#1}% +}% +\def\PML@powoften@out#1[#2]{\XINTinfloat[\XINTdigits]{#1[#2]}}% +\def\PML@powoften#1% +{% + \xint_UDzerominusfork + #1-\PML@powoften@zero + 0#1\PML@powoften@neg + 0-\PML@powoften@pos + \krof #1% +}% +\def\PML@powoften@zero 0/1[0]{1\relax/1[0]}% +\def\PML@powoften@pos#1[#2]% +{% + \expandafter\PML@powoften@pos@a\romannumeral0\xintround{9}{#1[#2]}.% +}% +\def\PML@powoften@pos@a#1.#2.{\PML@Pa#2.\expandafter[\the\numexpr-8+#1]}% +\def\PML@powoften@neg#1[#2]% +{% + \expandafter\PML@powoften@neg@a\romannumeral0\xintround{9}{#1[#2]}.% +}% +\def\PML@powoften@neg@a#1.#2.% +{% + \ifnum#2=\xint_c_ \xint_afterfi{1\relax/1[#1]}\else + \expandafter\expandafter\expandafter + \PML@Pa\expandafter\xint_gobble_i\the\numexpr2000000000-#2.% + \expandafter[\the\numexpr-9+#1\expandafter]\fi +}% +\def\PoorManExp#1{\PoorManPowerOfTen{\xintMul{#1}{43429448190325182765[-20]}}}% +% \end{macrocode} +% \subsubsection{Removed: \csh{PoorManPower}, see \cshnolabel{XINTinFloatSciPow}} +% \lverb|Originally in poormanlog v0.04, got transferred into xintfrac.sty at +% 1.3f, then here into xintlog.sty at 1.4e. Support for powers with "about 8 +% to 9 digits" (only when output not too big). This definition +% 10^(log10(x)*y), or e^(log(x)*y), matching the mathematical one, is common +% in many float support software but has many problems of precision when the +% result starts getting big (i.e. has a decimal exponent larger than 1000000 +% for example, and already 10000 will start demonstrating the loss of +% precision); recall for example for e^y = 10^(y/log(10)) that we had to be +% careful with log(10) precision, and this is only one instance of a general +% phenomenon. +% +% When computing a^b, it would be more precise to express b as an integer n +% plus a fractional part t, and compute a^b as a^n times a^t, where a^n is +% evaluated for example using repeated squaring base approach, with guard +% digits. This is precisely what \XINTinFloatPower available in xintfrac does +% (the documentation mentions a 0.52ulp error bound in result). But let's not +% make life complicated, and anyway this is all now for special "speedy" +% context at most 8 digits. +% +% Removed at 1.4e. See \XINTinFloatSciPow. +% | +% \subsubsection{Made a no-op: \csh{poormanloghack}} +% \lverb|& +% +% +% Made a no-op at 1.4e.| +% \begin{macrocode} +\def\poormanloghack#1% +{% + \xintMessage{xintexpr}{Warning}% + {\string\poormanloghack\space is a no-op since 1.4e and will be removed at next major release}% +}% +% \end{macrocode} +% \subsection{Macro support for the expression functional syntax} +% \lverb|As up to Digits=8 we use only poormanlog, we delay to end of package +% the lay-out of macros used for the actual computations, so that we execute +% an earlier \endinput if Digits<=8. +% +% Let us start by the support for the ** and ^ operators which will use +% in \xintfloatexpr \XINTinFloatSciPow and in \xintexpr \xintPow. The latter +% from $xintfracnameimp is thus modified here. +% +% The code is a bit complicated as we want to recycle things between the +% floateval and eval context, and between Digits>8 and Digits<=8. +% +% In the end I decided to simply define everything for Digits>8, and then +% let some macros be re-defined for the Digits<=8 case. The latter differs +% from the former in using systematically always the log10/pow10 approach, +% with the sole exception of integer exponents in \xintexpr context. +% | +% +% \subsubsection{\csh{XINTinFloatSciPow}} +% \lverb|& +% +% This is the new name and extension of \XINTinFloatPowerH which was +% a non user-documented macro used for a^b previously, and previously +% was located in $xintfracnameimp. +% +% For integer exponents up to at least 10000 (and certainly more but I have +% not yet much tested) the old $xintfracnameimp implementation of powers is +% faster than using logarithms and exponentials. And this is still the case +% for half-integer exponents, which are handled via a final square-root. +% +% The user documentation of \xintFloatPower mentions a 0.52 ulp(Z) error where +% Z is the computed result. Individually, \XINTinFloatLogTen and +% \XINTinFloatPowTen have been designed for an even higher accuracy but I have +% not really much tested what this gives in practice for powers. It is +% possible that \xintFloatPower less often finds the correct rounding than +% going (as below) via log10 and pow10 (in a special way described below), for +% non too big exponents, but what is certain is that: +% +% - the old \xintFloatPower is more accurate when one goes into extremely high +% exponent. For example 1.0000001^(12^16), where 12^16 is 184884258895036416 +% and has 18 digits, is computed to be at 60 Digits +% +% 1.87998567669494838838184407480229599674641360996864647488708e802942130 +% +% by \xintFloatPower and this is the correct rounding. Whereas going via +% logarithm as below would give the least 5 significant digits wrong (in fact +% the logarithm road will start having accuracy problems if exponent is of the +% order 1e12, something like that, although right now I say that a bit at +% random because I don't know why I started to write these comments and I +% rather want to finish the code). +% +% - also for integer exponents up to 10000 (and quite beyond, surely 100000 +% also, but I limited to 10000 when I was testing against xfp, as it doesn't +% support higher powers of 10) the old \xintFloatPower is faster than current +% log+exp (but I have not benchmarked much, as this takes tremendous amount of +% time and energy). And this is even true when one adds a square root +% extraction to cover half-integer exponents. +% +% We also want to do this in \xinteval for integer exponents, not only +% \xintfloateval, with a twist: in \xinteval we will compute *exactly* for not +% too big exponents: for A^b, we want the output to not have more than 10000 +% digits. For this we limit b depending on the length of A. +% +% If it is decided that the output would be too big, the computation is done +% as in \xintfloateval, i.e. using the old \xintFloatPower float macros. +% +% If the exponent is half-integer the +% computation will be done as in \xintfloateval, i.e. using FloatPower then a +% square root. +% +% The check whether exponent is integer or half-integer is not on the value +% but on the representation. Even in \xintfloatexpr, input such +% 10^\xintexpr4/2\relax is possible, and 4/2 will not be recognized as integer +% to avoid costly overhead. 3/2 will not be recognized as half-integer. +% But 2.0 will be recognized as integer, 25e-1 as half-integer. +% +% In the computation of a^b, a will be float-rounded to Digits, but the +% exponent b will be handled as is until last minute. Recall that the +% \xintfloatexpr parser does not automatically float round isolated inputs, +% this happens only once involved in computations. +% +% In the Digits<=8 branch the test for b integer if a is negative +% is done after float-rounding b, but the input b is used for computation. +% | +% \begin{macrocode} +\def\XINTinFloatSciPow{\romannumeral0\XINTinfloatscipow}% +\def\XINTinfloatscipow#1#2% +{% + \expandafter\XINT_scipow_a\romannumeral0\xintrez{#2}\XINT_scipow_int{#1}% +}% +\def\XINT_scipow_a #1% +{% + \xint_gob_til_zero#1\XINT_scipow_Biszero0\XINT_scipow_b#1% +}% +\def\XINT_scipow_Biszero#1]#2#3{ 1[0]}% +\def\XINT_scipow_b #1#2/#3[#4]#5% +{% + \unless\if1\XINT_is_One#3XY\xint_dothis\XINT_scipow_c\fi + \ifnum#4<\xint_c_mone\xint_dothis\XINT_scipow_c\fi + \ifnum#4=\xint_c_mone + \if5\xintLDg{#1#2} % + \xint_afterfi{\xint_dothis\XINT_scipow_halfint}\else + \xint_afterfi{\xint_dothis\XINT_scipow_c}% + \fi + \fi + \xint_orthat#5#1#2/#3[#4]% +}% +\def\XINT_scipow_int #1/1[#2]#3% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\XINT_dsx_addzeros{#2}#1;.\XINTdigits.{#3}{\XINTinfloatS[\XINTdigits]}% +}% +\def\XINT_scipow_halfint#1/1[#2]#3% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintdsr{\xintDouble{#1}}.\XINTdigits.{#3}\XINT_flpowerh_finish +}% +\def\XINT_flpowerh_finish #1% + {\XINTinfloatS[\XINTdigits]{\XINTinFloatSqrt[\XINTdigits+\xint_c_iii]{#1}}}% +\def\XINT_tmpa#1.{% +\def\XINT_scipow_c ##1[##2]##3% +{% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloatS[#1]{##3}\xint:##1[##2]\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\def\XINT_scipow_d #1% +{% + \xint_UDzerominusfork + #1-\XINT_scipow_Aiszero + 0#1\XINT_scipow_Aisneg + 0-\XINT_scipow_Aispos + \krof #1% +}% +\def\XINT_scipow_Aiszero #1\xint:#2#3\xint: +{% + \if-#2\xint_dothis + {\XINT_signalcondition{InvalidOperation}{Zero to negative power #2#3}{}{1["7FFF8000]}}\fi + \xint_orthat{ 0[0]}% +}% +\def\XINT_scipow_Aispos #1\xint:#2\xint: +{% + \XINTinfloatpowten{\xintMul{#2}{\XINTinFloatLogTen_xdgout#1}}% +}% +\def\XINT_scipow_Aisneg #1#2\xint:#3\xint: +{% + \XINT_signalcondition{InvalidOperation}{Fractional power of negative argument}{}{0[0]} +}% +\ifnum\XINTdigits<9 + \def\XINTinfloatscipow#1#2% + {% + \expandafter\XINT_scipow_a\romannumeral0\xintraw{#2}\relax{#1}% + }% + \def\XINT_scipow_b #1[#2]#3#4% + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]{#4}\xint:#1[#2]\xint: + }% + \def\XINT_scipow_Aispos #1\xint:#2\xint: + {% + \poormanpoweroften{\xintMul{#2}{\romannumeral0\expandafter\PML@logbaseten#1}}% + }% + \def\XINT_scipow_Aisneg #1#2\xint:#3\xint: + {% + \ifcase\xintFloatIntType{#3}% + \or\expandafter-\romannumeral0% + \else + \expandafter\XINT_scipow_AnegBfrac + \fi + \poormanpoweroften{\xintMul{#3}{\romannumeral0\expandafter\PML@logbaseten#2}}% + }% \fi % \end{macrocode} -% \lverb|\XINT_setcatcodes switches to the standard catcode regime of -% xint*.sty files. Formerly we needed here the ! of catcode 11 as in -% xintexpr.sty, which is set by \XINT_setcatcodes but does not apply now. +% \subsubsection{\csh{xintPow}} +% \lverb|& +% +% This overloads the original $xintfracnameimp macro and uses it for integer +% exponents, under a criterion which guarantees output (numerator and +% denominator separately) does not exceed by much 10000 digits if at all. % -% See the remark above about importance of doing \xintexprRestoreCatcodes if -% \xintexprSafeCatcodes has been used...| +% | % \begin{macrocode} -\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname +\def\xintPow{\romannumeral0\xintpow}% +\def\xintpow#1#2% +{% + \expandafter\XINT_scipow_a\romannumeral0\xintrez{#2}\XINT_pow_int{#1}% +}% +\def\XINT_pow_int #1/1[#2]%#3 +{% + \expandafter\XINT_pow_int_a\romannumeral0\XINT_dsx_addzeros{#2}#1;.% +}% +\def\XINT_pow_int_a #1#2.#3% +{% + \ifnum\if-#1\xintLength{#2}\else\xintLength{#1#2}\fi>\xint_c_iv + \expandafter\XINT_pow_tosci + \fi + \expandafter\XINT_pow_int_b\romannumeral0\xintraw{#3}\xint:#1#2\xint: +}% +\def\XINT_pow_int_b#1#2/#3[#4]\xint:#5\xint: +{% + \if0\ifnum\numexpr\xint_c_x^iv/% + (\xintLength{#1#2}\if-#1-\xint_c_i\fi)<\XINT_Abs#5 % + 1\else + \ifnum\numexpr\xint_c_x^iv/\xintLength{#3}<\XINT_Abs#5 % + 1\else + 0\fi\fi + \expandafter\XINT_fpow_fork\else\expandafter\XINT_pow_tosci_i + \fi + #5\Z{#4}{#1#2}{#3}% +}% +\def\XINT_tmpa#1.{% +\def\XINT_pow_tosci##1\xintraw%##2%\xint:##3\xint: +{% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloatS[#1]% +}% +\def\XINT_pow_tosci_i##1\Z##2##3##4% +{% + \expandafter\XINT_scipow_d\romannumeral0\expandafter\XINT_infloatS_clean + \romannumeral0\XINT_infloat_a#1.{##2}{##3}{##4}\xint:##1\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\ifnum\XINTdigits<9 + \def\xintpow#1#2% + {% + \expandafter\XINT_poorpow_a\romannumeral0\xintrez{#2}\relax{#1}% + }% + \def\XINT_poorpow_a #1% + {% + \xint_gob_til_zero#1\XINT_scipow_Biszero0\XINT_poorpow_b#1% + }% + \def\XINT_poorpow_b #1#2/#3[#4]#5% + {% + \unless\if1\XINT_is_One#3XY\xint_dothis\XINT_poorpow_c\fi + \ifnum#4<\xint_c_\xint_dothis\XINT_poorpow_c\fi + \xint_orthat\XINT_pow_int#1#2/#3[#4]% + }% + \def\XINT_poorpow_c #1[#2]#3% + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]{#3}\xint:#1[#2]\xint: + }% + \def\XINT_pow_tosci#1\xintraw%#2%\xint:#3\xint: + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]% + }% + \def\XINT_pow_tosci_i#1\Z#2#3#4% + {% + \expandafter\XINT_scipow_d\romannumeral0\expandafter\XINT_infloat_clean + \romannumeral0\XINT_infloat_a9.{#2}{#3}{#4}\xint:#1\xint: + }% +\fi % \end{macrocode} -% \subsection{The \cshn{log10()} and \cshn{pow10()} functions} -% \lverb|The support macros from poormanlog v0.04 \PoorManLogBaseTen, -% \PoorManLogPowerOfTen, \PoorManPower got transferred into xintfrac.sty at -% 1.3f.| +% \subsubsection{\cshn{log10()} and \cshn{pow10()} functions} +% \lverb|& +% Up to 8 digits included we use the poormanlog based ones. +% | % \begin{macrocode} +\ifnum\XINTdigits<9 \expandafter\def\csname XINT_expr_func_log10\endcsname#1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\PoorManLogBaseTen#3}}% }% -\expandafter\let\csname XINT_flexpr_func_log10\expandafter\endcsname - \csname XINT_expr_func_log10\endcsname \expandafter\def\csname XINT_expr_func_pow10\endcsname#1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\PoorManPowerOfTen#3}}% }% +\else +\expandafter\def\csname XINT_expr_func_log10\endcsname#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINTinFloatLogTen#3}}% +}% +\expandafter\def\csname XINT_expr_func_pow10\endcsname#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINTinFloatPowTen#3}}% +}% +\fi +\expandafter\let\csname XINT_flexpr_func_log10\expandafter\endcsname + \csname XINT_expr_func_log10\endcsname \expandafter\let\csname XINT_flexpr_func_pow10\expandafter\endcsname \csname XINT_expr_func_pow10\endcsname % \end{macrocode} -% \subsection{The \cshn{log()}, \cshn{exp()}, and \cshn{pow()} functions} -% \lverb|The log10() and pow10() were defined by poormanlog v0.04 but have -% been moved here at xint 1.3f. The support macros are defined in -% xintfrac.sty.| +% \subsubsection{\cshn{log()}, \cshn{exp()}, and \cshn{pow()} functions} +% \lverb|The mapping of ** and ^ to \XINTinFloatPow and \xintPow respectively, +% i.e. to be like pow(,) function is done in $xintexprnameimp.| % \begin{macrocode} +\ifnum\XINTdigits<9 \def\XINT_expr_func_log #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\xintLog#3}}% + {\romannumeral`&&@\PoorManLog#3}}% }% -\def\XINT_flexpr_func_log #1#2#3% +\def\XINT_expr_func_exp #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatLog#3}}% + {\romannumeral`&&@\PoorManExp#3}}% }% -\def\XINT_expr_func_exp #1#2#3% +\let\XINT_flexpr_func_log\XINT_expr_func_log +\let\XINT_flexpr_func_exp\XINT_expr_func_exp +\else +\def\XINT_expr_func_log #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\xintExp#3}}% + {\romannumeral`&&@\XINTinFloatLog#3}}% }% -\def\XINT_flexpr_func_exp #1#2#3% +\def\XINT_expr_func_exp #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\XINTinFloatExp#3}}% }% +\let\XINT_flexpr_func_log\XINT_expr_func_log +\let\XINT_flexpr_func_exp\XINT_expr_func_exp +\fi \def\XINT_expr_func_pow #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower#3}}% + {\romannumeral`&&@\xintPow#3}}% +}% +\def\XINT_flexpr_func_pow #1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:two + {\romannumeral`&&@\XINTinFloatSciPow#3}}% +}% +% \end{macrocode} +% \subsection{End of package loading for low Digits} +% \begin{macrocode} +\ifnum\XINTdigits<9 \expandafter\XINTendxintloginput\fi% +% \end{macrocode} +% \subsection{Stored constants} +% \lverb|The constants were obtained from Maple at 80 digits: fractional power +% of 10, but only one logarithm log(10). +% +% Currently the code whether for exponential or logarihm will not screen out 0 +% digits and even will do silly multiplication par 10^0 = 1 in that case, and +% we need to store such silly values. +% +% We add the data for the 10^-0.i etc... because pre-computing them on the fly +% significantly adds overhead to the package loading. +% | +% \begin{macrocode} +\def\XINT_tmpa{1[0]}% +\expandafter\let\csname XINT_c_1_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_inv_x\endcsname\XINT_tmpa +\def\XINT_tmpa#1#2#3#4;% + {\expandafter\edef\csname XINT_c_#1_#2\endcsname{\XINTinFloat[\XINTdigits+5]{#3#4[-79]}}% + \expandafter\edef\csname XINT_c_#1_#2_x\endcsname{\XINTinFloat[\XINTdigits+10]{#3#4[-79]}}% + }% +% 10^0.i +\XINT_tmpa 1 1 12589254117941672104239541063958006060936174094669310691079230195266476157825020;% +\XINT_tmpa 1 2 15848931924611134852021013733915070132694421338250390683162968123166568636684540;% +\XINT_tmpa 1 3 19952623149688796013524553967395355579862743154053460992299136670049309106980490;% +\XINT_tmpa 1 4 25118864315095801110850320677993273941585181007824754286798884209082432477235613;% +\XINT_tmpa 1 5 31622776601683793319988935444327185337195551393252168268575048527925944386392382;% +\XINT_tmpa 1 6 39810717055349725077025230508775204348767703729738044686528414806022485386945804;% +\XINT_tmpa 1 7 50118723362727228500155418688494576806047198983281926392969745588901125568883069;% +\XINT_tmpa 1 8 63095734448019324943436013662234386467294525718822872452772952883349494329768681;% +\XINT_tmpa 1 9 79432823472428150206591828283638793258896063175548433209232392931695569719148754;% +% 10^0.0i +\XINT_tmpa 2 1 10232929922807541309662751748198778273411640572379813085994255856738296458625172;% +\XINT_tmpa 2 2 10471285480508995334645020315281400790567914715039292120056525299012577641023719;% +\XINT_tmpa 2 3 10715193052376064174083022246945087339158659633422172707894501914136771607653870;% +\XINT_tmpa 2 4 10964781961431850131437136061411270464271158762483023169080841607885740984711300;% +\XINT_tmpa 2 5 11220184543019634355910389464779057367223085073605529624450744481701033026862244;% +\XINT_tmpa 2 6 11481536214968827515462246116628360182562102373996119340874991068894793593040890;% +\XINT_tmpa 2 7 11748975549395295417220677651268442278134317971793124791953875805007912852226246;% +\XINT_tmpa 2 8 12022644346174129058326127151935204486942664354881189151104892745683155052368222;% +\XINT_tmpa 2 9 12302687708123815342415404364750907389955639574572144413097319170011637639124482;% +% 10^0.00i +\XINT_tmpa 3 1 10023052380778996719154048893281105540536684535421606464116348523047431367720401;% +\XINT_tmpa 3 2 10046157902783951424046519858132787392010166060319618489538315083825599423438638;% +\XINT_tmpa 3 3 10069316688518041699296607872661381368099438247964820601930206419324524707606686;% +\XINT_tmpa 3 4 10092528860766844119155277641202580844111492027373621434478800545314309618714957;% +\XINT_tmpa 3 5 10115794542598985244409323144543146957419235215102899054703546688078254946034250;% +\XINT_tmpa 3 6 10139113857366794119988279023017296985954042032867436525450889437280417044987125;% +\XINT_tmpa 3 7 10162486928706956276733661150135543062420167220622552197768982666050994284378619;% +\XINT_tmpa 3 8 10185913880541169240797988673338257820431768224957171297560936579346433061037662;% +\XINT_tmpa 3 9 10209394837076799554149033101487543990018213667630072574873723356334069913329713;% +% 10^0.000i +\XINT_tmpa 4 1 10002302850208247526835942556719413318678216124626534526963475845228205382579041;% +\XINT_tmpa 4 2 10004606230728403216239656646745503559081482371024284871882409614422496765669196;% +\XINT_tmpa 4 3 10006910141682589957025973521996241909035914023642264228577379693841345823180462;% +\XINT_tmpa 4 4 10009214583192958761081718336761022426385537997384755843291864010938378093197023;% +\XINT_tmpa 4 5 10011519555381688769842032367472488618040778885656970999331288116685029387850446;% +\XINT_tmpa 4 6 10013825058370987260768186632475607982636715641432550952229573271596547716373358;% +\XINT_tmpa 4 7 10016131092283089653826887255241073941084503769368844606021481400409002185558343;% +\XINT_tmpa 4 8 10018437657240259517971072914549205297136779497498835020699531587537662833033174;% +\XINT_tmpa 4 9 10020744753364788577622204725249622301332888222801030351604197113557132455165040;% +% 10^0.0000i +\XINT_tmpa 5 1 10000230261160268806710649793464495797824846841503180050673957122443571394978721;% +\XINT_tmpa 5 2 10000460527622557806255008596155855743730116854295068547616656160734125748005947;% +\XINT_tmpa 5 3 10000690799386989083565213461287219981856579552059660369243804541364501659468630;% +\XINT_tmpa 5 4 10000921076453684726384543254593368743049141124080210677706489564626675960578367;% +\XINT_tmpa 5 5 10001151358822766825267483384008265483772370538793312970508590203623535763866465;% +\XINT_tmpa 5 6 10001381646494357473579790530833073090516914490540536234536867917078761046656260;% +\XINT_tmpa 5 7 10001611939468578767498557382394677469502542123237272447312733350028467607076918;% +\XINT_tmpa 5 8 10001842237745552806012277366194752842273812293689190856411757410911882303011468;% +\XINT_tmpa 5 9 10002072541325401690920909385549403068574626162727745910217443397959031898734024;% +% 10^0.00000i +\XINT_tmpa 6 1 10000023025877439451356029805459000097926504781151663770980171880313737943886754;% +\XINT_tmpa 6 2 10000046051807898005897723104514851394069452605882077809669546315010724085277647;% +\XINT_tmpa 6 3 10000069077791375785706217087438809625967243923218032821061587553353589726808164;% +\XINT_tmpa 6 4 10000092103827872912862930047032391734439796534302560512742030066798473305401477;% +\XINT_tmpa 6 5 10000115129917389509449561379274639104559958866285946533811801963402821672829477;% +\XINT_tmpa 6 6 10000138156059925697548091583969382297005329013199894805417325991907389143667949;% +\XINT_tmpa 6 7 10000161182255481599240782265392507269793911275470978276390154932321984777772469;% +\XINT_tmpa 6 8 10000184208504057336610176132939223090407041937631374389422968832433217547184883;% +\XINT_tmpa 6 9 10000207234805653031739097001771331138303016031686764989867510425362339583809842;% +\def\XINT_tmpa#1#2#3#4;% + {\expandafter\edef\csname XINT_c_#1_#2_inv\endcsname{\XINTinFloat[\XINTdigits+5]{#3#4[-80]}}% + \expandafter\edef\csname XINT_c_#1_#2_inv_x\endcsname{\XINTinFloat[\XINTdigits+10]{#3#4[-80]}}% + }% +% 10^-0.i +\XINT_tmpa 1 1 79432823472428150206591828283638793258896063175548433209232392931695569719148754;% +\XINT_tmpa 1 2 63095734448019324943436013662234386467294525718822872452772952883349494329768681;% +\XINT_tmpa 1 3 50118723362727228500155418688494576806047198983281926392969745588901125568883069;% +\XINT_tmpa 1 4 39810717055349725077025230508775204348767703729738044686528414806022485386945804;% +\XINT_tmpa 1 5 31622776601683793319988935444327185337195551393252168268575048527925944386392382;% +\XINT_tmpa 1 6 25118864315095801110850320677993273941585181007824754286798884209082432477235613;% +\XINT_tmpa 1 7 19952623149688796013524553967395355579862743154053460992299136670049309106980490;% +\XINT_tmpa 1 8 15848931924611134852021013733915070132694421338250390683162968123166568636684540;% +\XINT_tmpa 1 9 12589254117941672104239541063958006060936174094669310691079230195266476157825020;% +% 10^-0.0i +\XINT_tmpa 2 1 97723722095581068269707600696156123863427170069897801526639004097175507042084888;% +\XINT_tmpa 2 2 95499258602143594972395937950148401513087269708053320302465127242741421479104601;% +\XINT_tmpa 2 3 93325430079699104353209661168364840720225485199736026149257155811788093771138272;% +\XINT_tmpa 2 4 91201083935590974212095940791872333509323858755696109214760361851771695487999100;% +\XINT_tmpa 2 5 89125093813374552995310868107829696398587478293004836994794349506746891059190135;% +\XINT_tmpa 2 6 87096358995608063751082742520877054774747128501284704090761796673224328569285177;% +\XINT_tmpa 2 7 85113803820237646781712631859248682794521725442067093899553745086385146367436049;% +\XINT_tmpa 2 8 83176377110267100616669140273840405263880767161887438462740286611379995442629360;% +\XINT_tmpa 2 9 81283051616409924654127879773132980187568851100062454636602325121954484722491710;% +% 10^-0.00i +\XINT_tmpa 3 1 99770006382255331719442194285376231055211861394573154624878230890945476532432225;% +\XINT_tmpa 3 2 99540541735152696244806147089510943107144177264574823668081299845609359857038344;% +\XINT_tmpa 3 3 99311604842093377157642607688515474663519162181123336122073822476734517364853150;% +\XINT_tmpa 3 4 99083194489276757440828314388392035249938006860819409201135652190410238171119287;% +\XINT_tmpa 3 5 98855309465693884028524792978202683686410726723055209558576898759166522286083202;% +\XINT_tmpa 3 6 98627948563121047157261523093421290951784086730437722805070296627452491731402556;% +\XINT_tmpa 3 7 98401110576113374484101831088824192144756194053451911515003663381199842081528019;% +\XINT_tmpa 3 8 98174794301998439937928161622872240632362817134775142288598128693131032909278350;% +\XINT_tmpa 3 9 97948998540869887269961493687844910565420716785032030061251916654655049965062649;% +% 10^-0.000i +\XINT_tmpa 4 1 99976976799815658635141604638981297541396466984477711459083930684685186989697929;% +\XINT_tmpa 4 2 99953958900308784552845777251512089759003230012954649234748668826546533498169555;% +\XINT_tmpa 4 3 99930946300258992168693777702512591351888960684418033717545524043693899420866954;% +\XINT_tmpa 4 4 99907938998446176870082987427724649318531547584410414997787083472394558389284098;% +\XINT_tmpa 4 5 99884936993650514951538205746462968844845952521633937925370747725933629958238429;% +\XINT_tmpa 4 6 99861940284652463550037839584112909891259691850983307437097305856727153967481065;% +\XINT_tmpa 4 7 99838948870232760580354983175435314251655958968480344701699631967048474751069525;% +\XINT_tmpa 4 8 99815962749172424670413384320528274471550942114263604264788586703624513163664479;% +\XINT_tmpa 4 9 99792981920252755096658293766085025870392854106037465990011216356523334125368417;% +% 10^-0.0000i +\XINT_tmpa 5 1 99997697441416293040019992468837639003787989306240470048763511538639048400765328;% +\XINT_tmpa 5 2 99995394935850346394065999228750187791584034668237852053859761641089829514536011;% +\XINT_tmpa 5 3 99993092483300939297147020491645017932348508508297743745039515152378182676736684;% +\XINT_tmpa 5 4 99990790083766851012380885556584619169980753943113396677545915245611923361705686;% +\XINT_tmpa 5 5 99988487737246860830993605587529673614422529030613405900998412734419982883669223;% +\XINT_tmpa 5 6 99986185443739748072318726405984801565268578044798475766025647187221659622450651;% +\XINT_tmpa 5 7 99983883203244292083796681298546635825139453823571398432959235283529730820181019;% +\XINT_tmpa 5 8 99981581015759272240974143839353881367972777961073357987943600347058023396510672;% +\XINT_tmpa 5 9 99979278881283467947503380727439017235290006415950636109257677645557027950744160;% +% 10^-0.00000i +\XINT_tmpa 6 1 99999769741755795297487775997495948154386159348543852707438213487494386559762090;% +\XINT_tmpa 6 2 99999539484041779185217876175552674518572114763104546143049036309870762496098218;% +\XINT_tmpa 6 3 99999309226857950442387361668529812394860404492721699528707852590634886516924591;% +\XINT_tmpa 6 4 99999078970204307848196104610199226516866442484686906173860803560254163287393673;% +\XINT_tmpa 6 5 99998848714080850181846788127272455158309917012010320554498356105168896062430977;% +\XINT_tmpa 6 6 99998618458487576222544906332928167145404344730731751204389698696345970645201375;% +\XINT_tmpa 6 7 99998388203424484749498764320339633772810463403640242228131015918494067456365331;% +\XINT_tmpa 6 8 99998157948891574541919478156202215623119146605983303201215215949834619332550929;% +\XINT_tmpa 6 9 99997927694888844379020974874260864289829523807763942234420930258187873904191138;% +% log(10) +\edef\XINT_c_logten + {\XINTinFloat[\XINTdigits+4] + {23025850929940456840179914546843642076011014886287729760333279009675726096773525[-79]}}% +\edef\XINT_c_oneoverlogten + {\XINTinFloat[\XINTdigits+4] + {43429448190325182765112891891660508229439700580366656611445378316586464920887077[-80]}}% +\edef\XINT_c_oneoverlogten_xx + {\XINTinFloat[\XINTdigits+14] + {43429448190325182765112891891660508229439700580366656611445378316586464920887077[-80]}}% +% \end{macrocode} +% \subsection{April 2021: at last, \csh{XINTinFloatPowTen}, \csh{XINTinFloatExp}} +% \lverb|Done April 2021. I have procrastinated (or did not have time to +% devote to this) at least 5 years, even more. +% +% Speed improvements will have to wait to long delayed refactoring of core +% floating point support which is still in the 2013 primitive state ! +% +% I did not try to optimize for say 16 digits, as I was more focused on +% reaching 60 digits in a reasonably efficient manner (trigonometric functions +% achieved this since 2019) in the same coding framework. Finally, up to 62 digits. +% +% The stored constants are log(10) at P+4 digits and the powers 10^0.d, +% 10^0.0d, etc, up to 10^0.00000d for d=1..9, as well as their inverses, at +% P+5 and P+10 digits. The constants were obtained from Maple at 80 digits. +% +% Initially I constructed the exponential series exp(h) as one big unique nested +% macro. It contained pre-rounded values of the 1/i! but would float-round h +% to various numbers of digits, with always the full initial h as input. +% +% After having experimented with the logarithm, I redid exp(h) = 1 + h(1 + +% h(1/2 + ...)) with many macros in order to have more readable code, and to +% dynamically cut-off more and more digits from h the deeper it is used. See +% the logarithm code for (perhaps) more comments. +% +% The thresholds have been obtained from considerations including an hmax +% (a bit more than 0.5 log(10) 10^-6). Here is the table: +% +%( - maximal value of P: 8, 15, 21, 28, 35, 42, 48, 55, 62 +%: - last included term: /1, /2, /6, /4!, /5!, /6!, /7!, /8!, /9! +%) +% +% Computations are done morally targeting P+4 fractional fixed point digits, +% with a stopping criteria at say about 5e(-P-4), which was used for the table +% above using only the worst case. As the used macros are a mix of exact +% operations and floating point reductions this is in practice a bit +% different. The h will be initially float rounded to P-1 digits. It is +% cut-off more and more, the deeper nested it is used. +% +% The code for this evaluation of 10^x is very poor with x very near zero: it +% does silly multiplication by 1, and uses more terms of exponential series +% than would then be necessary. +% +% For the computation of exp(x) as 10^(c*x) with c=log(10)^-1, we need more +% precise c the larger abs(x) is. For abs(x)<1 (or 2), the c with P+4 +% fractional digits is sufficient. But decimal exponents are more or less +% allowed to be near the TeX maximum 2^31-1, which means that abs(x) could be +% as big as 0.5e10, and we then need c with P+14 digits to cover that range. +% +% I am hesitating whether to first examine integral part of abs(x) and for +% example to use c with either P+4, P+9 or P+14 digits, and also take this +% opportunity to inject an error message if x is too big before TeX arithmetic +% overflow happens later on. For time being I will use overhead of +% oneoverlogten having ample enough digits... +% +% The exponent received as input is float rounded to P + 14 digits. In +% practice the input will be already a P-digits float. The motivation here is +% for low Digits situation: but this done so that for example with Digits=4, +% we want exp(12345) not to be evaluated as exp(12350) which would have no +% meaning at all. The +14 is because we have prepared 1/log(10) with that many +% significant digits. This conundrum is due to the inadequation of the world +% of floating point numbers with exp() and log(): clearly exp() goes from +% fixed point to floating point and log() goes from floating point to fixed +% point, and coercing them to work inside the sole floating point domain is +% not mathematically natural. Although admittedly it does create interesting +% mathematical questions! A similar situatoin applies to functions such as +% cos() and sin(), what sense is there in the expression cos(exp(50)) for +% example with 16 digits precision? My opinion is that it does not make ANY +% sense. Anyway, I shall obide. +% +% As \XINTinFloatS will not add unnecessarily trailing zeros, the +% \XINTdigits+14 is not really an enormous overhead for integer exponents, +% such as in the example above the 12345, or more realistically small integer +% exponents, and if the input is already float rounded to P digits, the +% overhead is also not enormous (float-rounding is costly when the input is a +% fraction). +% +% \XINTinfloatpowten will receive an input with at least P+14 and up to 2P+28 +% digits... fortunaltely with no fraction part and will start rounding it in +% the fixed point sense of its input to P+4 digits after decimal point, which +% is not enormously costly. +% +% Of course all these things pile up... +% | +% \begin{macrocode} +\def\XINTinFloatExp{\romannumeral0\XINTinfloatexp}% +\def\XINT_tmpa#1.{% +\def\XINTinfloatexp##1% +{% + \XINTinfloatpowten + {\xintMul{\XINT_c_oneoverlogten_xx}{\XINTinFloatS[#1]{##1}}}% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+14.% +% \end{macrocode} +% \lverb|& +% Here is how the reduction to computations of an exp(h) via series is done. +% +% Starting from x, after initial argument normalization, it is fixed-point +% rounded to 6 fractional digits giving x'' = ±n.d_1...d_6 (which may be 0). +% +% I have to resist temptation using very low level routines here and wisely +% will employ the available user-level stuff. One computes then the +% difference x-x'' which gives some eta, and the h will be log(10).eta. The +% subtraction and multiplication are done exactly then float rounded to P-1 +% digits to obtain the h. +% +% Then exp(h) is computed. And to finish it is multiplied with the stored +% 10^±0.d_1, 10^±0.0d_2, etc...., constants and its decimal exponent is +% increased by ±n. These operations are done at P+5 floating point digits. The +% final result is then float-rounded to the target P digits. +% +% Currently I may use nested macros for some operations but will perhaps +% revise in future (it makes tracing very complicated if one does not have +% intermediate macros). The exponential series itself was initially only one +% single macro, but as commented above I have now modified it.| +% \begin{macrocode} +\def\XINTinFloatPowTen{\romannumeral0\XINTinfloatpowten}% +\def\XINT_tmpa#1.{% +\def\XINTinfloatpowten##1% +{% + \expandafter\XINT_powten_fork + \romannumeral0\xintiround{#1}{##1}[-#1]% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+4.% +\def\XINT_powten_fork#1% +{% + \xint_UDzerominusfork + #1-\XINT_powten_zero + 0#1\XINT_powten_neg + 0-\XINT_powten_pos + \krof #1% }% -\let\XINT_flexpr_func_pow\XINT_expr_func_pow +\def\XINT_powten_zero #1[#2]{ 1[0]}% +% \end{macrocode} +% \lverb|This rounding may produce 0.000000 but will always have 6 exactly +% fractional digits, because the special case of a zero input was filtered out +% preventively. +% | +% \begin{macrocode} +\def\XINT_powten_pos#1[#2]% +{% + \expandafter\XINT_powten_pos_a\romannumeral0\xintround{6}{#1[#2]}#1[#2]% +}% +\def\XINT_tmpa #1.#2.{% +\def\XINT_powten_pos_a ##1.##2##3##4##5##6##7##8[##9]% +{% + \expandafter\XINT_infloate + \romannumeral0\XINTinfloat[\XINTdigits]{% + \xintMul{\csname XINT_c_1_##2\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7\endcsname}{% + \xintAdd{1[0]}{% + \expandafter\XINT_Exp_series_a_ii + \romannumeral0\XINTinfloat[#2]{% + \xintMul{\XINT_c_logten}% + {\xintAdd{-##1.##2##3##4##5##6##7}{##8[##9]}}% + }% + \xint: + }% + }}}}}}}}}}}}{##1}% +}}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.% + \the\numexpr\XINTdigits-1.% +% \end{macrocode} +% \lverb|This rounding may produce -0.000000 but will always have 6 exactly +% fractional digits and a leading minus sign.| +% \begin{macrocode} +\def\XINT_powten_neg#1[#2]% +{% + \expandafter\XINT_powten_neg_a\romannumeral0\xintround{6}{#1[#2]}#1[#2]% +}% +\def\XINT_tmpa #1.#2.{% +\def\XINT_powten_neg_a -##1.##2##3##4##5##6##7##8[##9]% +{% + \expandafter\XINT_infloate + \romannumeral0\XINTinfloat[\XINTdigits]{% + \xintMul{\csname XINT_c_1_##2_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7_inv\endcsname}{% + \xintAdd{1[0]}{% + \expandafter\XINT_Exp_series_a_ii + \romannumeral0\XINTinfloat[#2]{% + \xintMul{\XINT_c_logten}% + {\xintAdd{##1.##2##3##4##5##6##7}{##8[##9]}}% + }% + \xint: + }% + }}}}}}}}}}}}{-##1}% +}}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.% + \the\numexpr\XINTdigits-1.% % \end{macrocode} -% \subsection{\csh{poormanloghack}} -% \lverb|With \poormanloghack{**}, the ** operator will use pow10(y*log10(x)). -% Same for ^. Sync'd with xintexpr 1.4. +% \subsubsection{Exponential series} +% \lverb|Or rather here h(1 + h(1/2 + h (1/6 + ....))). Upto at most h^9/9! +% term. % -% MEMO: the reason why I need to redefine a lot of stuff is that xintexpr.sty -% does the job only for ^ and then does a \let for exec_** only. So if now -% ^ and ** possibly act differently all must be duplicated.| +% The used initial h has been float rounded to P-1 digits.| % \begin{macrocode} -\catcode`\* 11 -\def\poormanloghack** +\def\XINT_tmpa#1.#2.{% +\def\XINT_Exp_series_a_ii##1\xint: {% - \def\XINT_tmpa ##1##2##3##4##5##6% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_ + \romannumeral0\xintadd{1}{\xintHalf{##10}[##2-1]}\xint: +}% +\def\XINT_Exp_series_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-6\expandafter.% + \the\numexpr\XINTdigits-1.% +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_Exp_series_a_ii##1\xint: +{% + \expandafter\XINT_Exp_series_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_a_iii##1\xint: +{% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_i + \romannumeral0\xintadd{#3}{##1/6[##2]}\xint: +}% +\def\XINT_Exp_series_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_Exp_series_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-6.% + {5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_Exp_series_a_iii##1\xint: +{% + \expandafter\XINT_Exp_series_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_a_iv##1\xint: +{% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_ii + \romannumeral0\xintadd{#3}{##1/24[##2]}\xint: +}% +\def\XINT_Exp_series_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_Exp_series_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-13]{1/6[0]}.% + {5[-1]}.% +\fi +\ifnum\XINTdigits>28 +\def\XINT_tmpa #1 #2 #3 #4 #5 #6 #7 % +{% + \def\XINT_tmpb ##1##2##3##4% {% - \def ##3####1% \XINT_expr_op_<op> + \def\XINT_tmpc####1.####2.####3.####4.% {% - \expanded{\unexpanded{##4{####1}}\expandafter}% - \romannumeral`&&@\expandafter##2\romannumeral`&&@\XINT_expr_getnext + \def##2########1\xint: + {% + \expandafter##1% + \romannumeral0\XINTinfloatS[####2]{########1}\xint:########1\xint: + }% + \def##1########1\xint: + {% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[####1]{########1}\xint:########1\xint: + }% + \def\XINT_Exp_series_b########1[########2]\xint: + {% + \expandafter##3% + \romannumeral0\xintadd{####3}{########1/#5[########2]}\xint: + }% + \def##3########1\xint:########2\xint: + {% + \expandafter##4% + \romannumeral0\xintadd{####4}{\XINTinFloat[####2]{\xintMul{########1}{########2}}}\xint: + }% }% - \def##2####1% \XINT_expr_check-_<op> - {% + }% + \expandafter\XINT_tmpb + \csname XINT_Exp_series_a_\romannumeral\numexpr#1\expandafter\endcsname + \csname XINT_Exp_series_a_\romannumeral\numexpr#1-1\expandafter\endcsname + \csname XINT_Exp_series_c_\romannumeral\numexpr#1-2\expandafter\endcsname + \csname XINT_Exp_series_c_\romannumeral\numexpr#1-3\endcsname + \expandafter\XINT_tmpc + \the\numexpr\XINTdigits-#2\expandafter.% + \the\numexpr\XINTdigits-#3\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-#3]{1/#6[0]}.% + \XINTinFloat[\XINTdigits-#4]{1/#7[0]}.% + }% +}% +\XINT_tmpa 5 26 19 13 120 24 6 %<-- keep space +\ifnum\XINTdigits>35 \XINT_tmpa 6 33 26 19 720 120 24 \fi +\ifnum\XINTdigits>42 \XINT_tmpa 7 40 33 26 5040 720 120 \fi +\ifnum\XINTdigits>48 \XINT_tmpa 8 46 40 33 40320 5040 720 \fi +\ifnum\XINTdigits>55 \XINT_tmpa 9 53 46 40 362880 40320 5040 \fi +\fi +% \end{macrocode} +% \subsection{April 2021: at last \csh{XINTinFloagLogTen}, \csh{XINTinFloatLog}} +% \lverb?& +% Attention that this is not supposed to be used with \XINTdigits at +% 8 or less, it will crash if that is the case. The log10() and log() +% functions in case \XINTdigits is at most 8 are mapped to \PoormanLogBaseTen +% respectively \PoormanLog macros. +% +% In the explications here I use the function names rather than the macro +% names. +% +% Both log(x) and log10(x) are on top of an underlying macro which will +% produce z and h such that x is about 10^z e^h (with h being small is +% obtained via a log series). Then log(x) computes log(10)z+h whereas log10(x) +% computes as z+h/log(10). +% +% There will be three branches +% according to situation of x relative to 1. Let y be the math value log10(x) +% that we want to approximate to target precision P digits. P is assumed at +% least 9. +% +% I will describe the algorithm roughly, but skip its underlying support +% analysis; at some point I mention "fixed point calculations", but in +% practice it is not done exactly that way, but describing it would be +% complicated so look at the code which is very readable (by the author, at +% the present time). +% +% First we compute z = ±n.d_1d_2...d_6 as the rounded to 6 fractional digits +% approximation of y=log10(x) obtained by first using the poormanlog macros on x +% (float rounded to 9 digits) then rounding as above. +% +% Warning: this description is not in sync with the code, now the case where +% d_1d_2...d_6 is 000000 is filtered out and one jumps directly either to case +% I if n≠0 or to case III if n=0. There is also a preventive step to recognize +% when the rounding produces a z exactly zero (\xintRound has bad pratice of +% outputting a 0 with no decimal point if the input was exactly zero, and this +% can happen here as the input is some approximation to actual logarithm). +% +% CASE I: either n is NOT zero or d_1d_2....d_6 is at least 100001. Then we +% compute X = 10^(-z)*x which is near 1, by using the table of powers of +% 10, using P+5 digits significands. Then we compute (exactly) eta = X-1, +% (which is in absolute value less than 0.0000012) +% and obtain +% y as z + log(10)^(-1) times log(1+eta) +% where log(1+eta) = eta - eta^2/2 + eta^3/3- ... is "computed with +% P+4 fractional fixed point digits" [1]_ according to the following table: +% +%( - maximal value of P: 9, 15, 21, 27, 33, 39, 45, 51, 57, 63 +%: - last included term: /1, /2, /3, /4, /5, /6, /7, /8, /9, /10 +%) +% +% .. [1] this "P+4" includes leading fractional zeroes so in practice it will +% rather be done as eta(1 - eta(1/2 + eta(1/3-...))), and the inner sums will +% be done in various precisions, the top level (external) eta probably at P-1 +% digits, the first inner eta at P-7 digits, the next at P-13, something in +% this style. The heuristics is simple: at P=9 we don't need the first inner +% eta, so let's use there P-9 or rather P-7 digits by security. Similarly at +% P=3 we would not need at all the eta, so let's use the top level one rounded +% at P-3+2 = P-1 digits. And there is a shift by 6 less digits at each inner +% level. RÉFLÉCHIR SI C'EST PAS PLUTÔT P-2 ICI, suffisant au regard de la +% précision par ailleurs pour la réduction près de 1. +% +% The sequence of maximal P's is simply an arithmetic progression. +% +% The addition of z will trigger the final rounding to P digits. +% The inverse of log(10) is precomputed with P+4 digits. +% +% This case I essentially handles x such as max(x,1/x)>10^0.1=1.2589... +% +% CASE II: n is zero and d_1d_2....d_6 is not zero. We operate as in CASE I, +% up to the following differences: +%( - the table of fractional powers of 10 is used with P+10 significands. +%: - the X is also computed with P+10 digits, i.e. eta = X-1 (which obeys& +% the given estimate) is estimated with P+9 [2]_ fractional fixed points digits& +% and the log series will be evaluated in this sense. +%: - the constant log(10)^(-1) is still used with only P+4 digits +%) +% +% The log series is terminated according to the following table: +%( - maximal value of P: 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64 +%: - last included term: /1, /2, /3, /4, /5, /6, /7, /8, /9, /10 +%) +% +% Again the P's are in arithmetic progression, the same as before shifted by +% 5. +% +% .. [2] same remark as above. The top level eta in eta(1 - eta(1/2 - +% eta(...))) will use P+4 significant digits, but the first inner eta will be +% used with only P-2 digits, the next inner one with P-8 digits etc... +% +% This case II handles the x which are near 1, but not as close as 10^±0.000001. +% +% CASE III: z=0. In this case X = x = 1+eta and we use the log series in +% this sense : log(10)^(-1)*eta*(1 - eta/2 + eta^2/3-....) +% where again log(10)^(-1) has been precomputed with P+4 digits +% and morally the series uses P+4 fractional digits (P+3 would probably +% be enough for the precision I want, need to check my notes) +% and the thresholds table is: +%( - maximal value of P: 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63 +%: - last included term: /1, /2, /3, /4, /5, /6, /7, /8, /9, /10, /11 +%) +% +% This is same progression but shifted by one. +% +% To summarize some relevant aspects: +%( - this algorithm uses only log(10)^(-1) as precomputed logarithm +%: - in particular the logarithms of small integers 2, 3, 5,... are& +% not pre-computed. Added note: I have now tested at 16, 32, 48 and 62& +% digits that all of the log10(n), for n = 1..1000, are computed with& +% correct rounding. In fact, generally speaking, random testing of a& +% about 20000 inputs has failed to reveal a single non-correct& +% rounding. Naturally, randomly testing is not the way to corner& +% the software into its weak points... +%: - it uses two tables of fractional powers of ten: one with P+5 digits and& +% another one with extended precision at P+10 digits. +%: - it needs three distinct implementations of the log series. +%: - it does not use the well-known trick reducing to using only odd powers& +% in the log series (somehow I have come to dread divisions, even though& +% here as is well-known it could be replaced with some product, my& +% impression was that what is gained on one side is lost on the other,& +% for the range of P I am targeting, i.e. P up to about 60.) +%: - all of this is experimental (in particular the previous item was not& +% done perhaps out of sheer laziness) +%) +% +% Absolutely no error check is done whether the input x is really positive. +% As seen above the maximal target precision is 63 (not 64). +% +% ? +% \begin{macrocode} +\def\XINT_tmpa#1.{% +\def\XINTinFloatLog{\romannumeral0\XINTinfloatlog}% +\def\XINTinfloatlog +{% + \expandafter\XINT_log_out + \romannumeral0\expandafter\XINT_logten_a + \romannumeral0\XINTinfloat[#1]%{##1} +}% +\def\XINT_log_out ##1\xint:##2\xint: +{% + \XINTinfloat[#1]% + {\xintAdd{\xintMul{\XINT_c_logten}{##1}}{##2}}% +}% +\def\XINTinFloatLogTen{\romannumeral0\XINTinfloatlogten}% +\def\XINTinfloatlogten +{% + \expandafter\XINT_logten_out + \romannumeral0\expandafter\XINT_logten_a + \romannumeral0\XINTinfloat[#1]%{##1} +}% +\def\XINT_logten_out ##1\xint:##2\xint: +{% + \XINTinfloat[#1]% + {\xintAdd{##1}{\xintMul{\XINT_c_oneoverlogten}{##2}}}% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\def\XINTinFloatLogTen_xdgout%#1[#2] +{% + \romannumeral0\expandafter\XINT_logten_xdgout\romannumeral0\XINT_logten_a +}% +\def\XINT_logten_xdgout #1\xint:#2\xint: +{% + \xintadd{#1}{\xintMul{\XINT_c_oneoverlogten_xx}{#2}}% +}% +% \end{macrocode} +% \lverb|No check is done whether input is negative or vanishes. We apply +% \XINTinfloat[9] which if input is not zero always produces 9 digits (and +% perhaps a minus sign) the first digit is non-zero. This is the expected +% input to \numexpr\PML@<digits><dot>.\relax| +% \begin{macrocode} +\def\XINT_logten_a#1[#2]% +{% + \expandafter\XINT_logten_b + \romannumeral0\XINTinfloat[9]{#1[#2]}#1[#2]% +}% +\def\XINT_logten_b#1[#2]% +{% + \expandafter\XINT_logten_c + \romannumeral0\xintround{6}% + {\xintiiAdd{\xintDSx{-9}{\the\numexpr#2+8\relax}}% + {\the\numexpr\PML@#1.\relax}% + [-9]}% + \xint: +}% +% \end{macrocode} +% \lverb|If we were either in 100000000[0] or 999999999[-1] for the #1[#2] +% \XINT_logten_b input, and only in those cases, the \xintRound{6} produced +% "0". We are very near 1 and will treat this as case III, but this is +% sub-optimal.| +% \begin{macrocode} +\def\XINT_logten_c #1#2% +{% + \xint_gob_til_xint:#2\XINT_logten_IV\xint: + \XINT_logten_d #1#2% +}% +\def\XINT_logten_IV\xint:\XINT_logten_d0{\XINT_logten_f_III}% +% \end{macrocode} +% \lverb|Here we are certain that \xintRound{6} produced a decimal point and +% 6 fractional digit tokens #2, but they can be zeros. +% +% If #1 vanishes and #2>100000 we are in case I. +% +% If #1 vanishes and 100000>=#2>0 we are in case II. +% +% If #1 and #2 vanish we are in case III. +% +% If #1 does not vanish we are in case I with a direct quicker access if #2 vanishes. +% +% Attention to the sign of #1, it is checked later on. +% +% A bit tired today of expandafter or afterfi or dothis/orthat etc... (which +% is one level). Somehow there are very very few \ifcase use in all of +% xint... I don't know why. +% +% | +% \begin{macrocode} +\def\XINT_logten_d #1.#2\xint: +{% + \ifcase + \ifnum#1=\xint_c_ + \ifnum #2>100000 \xint_c_i\else + \ifnum #2>\xint_c_ \xint_c_ii\else \xint_c_iii\fi\fi + \else + \ifnum#2>\xint_c_ \xint_c_i\else \xint_c_\fi + \fi + \expandafter\XINT_logten_f_Isp + \or\expandafter\XINT_logten_f_I + \or\expandafter\XINT_logten_f_II + \else\expandafter\XINT_logten_f_III + \fi + #1.#2\xint: +}% +\def\XINT_logten_f_I#1% +{% \xint_UDsignfork - ####1{\expandafter##2\romannumeral`&&@##1}% - -{##5####1}% - \krof + #1\XINT_logten_f_I_neg + -\XINT_logten_f_I_pos + \krof #1% +}% +\def\XINT_logten_f_II#1% +{% + \xint_UDsignfork + #1\XINT_logten_f_II_neg + -\XINT_logten_f_II_pos + \krof #1% +}% +\def\XINT_tmpa#1.{% +\def\XINT_logten_f_Isp##1.000000\xint:##2[##3]% +{% + {##1[0]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloatS[#1]{\xintAdd{##2[##3-##1]}{-1[0]}}% + \xint: + }\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits-2.% +\def\XINT_tmpa#1.{% +\def\XINT_logten_f_III##1\xint:##2[##3]% +{% + {0[0]}\xint: + {\expandafter\XINT_LogTen_serIII_a_ii + \romannumeral0\XINTinfloatS[#1]{\xintAdd{##2[##3]}{-1[0]}}% + \xint: + }\xint: +}}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+4.% +\def\XINT_tmpa#1.#2.{% +\def\XINT_logten_f_I_pos##1.##2##3##4##5##6##7\xint:##8[##9]% +{% + {\the\numexpr##1##2##3##4##5##6##7[-6]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##2_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7_inv\endcsname} + {##8[##9-##1]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +\def\XINT_logten_f_I_neg##1.##2##3##4##5##6##7\xint:##8[##9]% +{% + {\the\numexpr##1##2##3##4##5##6##7[-6]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##2\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7\endcsname} + {##8[##9-##1]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.\the\numexpr\XINTdigits-1.% +\def\XINT_tmpa#1.#2.{% +\def\XINT_logten_f_II_pos0.##1##2##3##4##5##6\xint:##7[##8]% +{% + {\the\numexpr##1##2##3##4##5##6[-6]}\xint: + {\expandafter\XINT_LogTen_serII_a_ii + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##1_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##2_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##3_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##4_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##5_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##6_inv_x\endcsname} + {##7[##8]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +\def\XINT_logten_f_II_neg-0.##1##2##3##4##5##6\xint:##7[##8]% +{% + {\the\numexpr-##1##2##3##4##5##6[-6]}\xint: + {\expandafter\XINT_LogTen_serII_a_ii + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##1_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##2_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##3_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##4_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##5_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##6_x\endcsname} + {##7[##8]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+10\expandafter.\the\numexpr\XINTdigits+4.% +% \end{macrocode} +% \lverb|Initially all of this was done in a single big nested macro but the +% float-rounding of argument to less digits worked again each time from +% initial long input; the advantage on the other hand was that the 1/i +% constants were all pre-computed and rounded. +% +% Pre-coding the successive rounding to six digits less at each stage could be +% done via a single loop which would then walk back up inserting coeffs like +% 1/#1 having no special optimizing tricks. Pre-computing the 1/#1 too is +% possible but then one would have to copy the full set of such constants +% (which would be pre-computed depending on P), and this will add grabbing +% overhead in the loop expansion. Or one defines macros to hold the +% pre-rounded constants. +% +% Finally I do define macros, not only to hold the constants but to hold the +% whole build-up. Sacrificing brevity of code to benefit of expansion "speed". +% +% Firts one prepares eta, with P+4 digits for mantissa, and then hands it over +% to the log series. This will proceed via first preparing eta\xint: eta\xint: +% .... eta\xint:, the leftmost ones being more and more reduced in number of +% digits. Finally one goes back up to the right, the hard-coded number of +% steps depending on value of P=\XINTdigits at time of reloading of +% package. This number of steps is hard-coded in the number of macros which +% get defined. +% +% Descending (leftwards) chain: _a, Turning point: _b, Ascending: _c. +% +% As it is very easy to make silly typing mistakes in the numerous macros I +% have refactored a number of times the set-up to make manual verification +% straightforward. Automatization is possible but the _b macros complicate +% things, each one is its own special case. In the end the set-up will define +% then redefine some _a and the (finally unique) _b macro, this allows easier +% to read code, with no nesting of conditionals or else branches. +% +% Actually series III and series II differ by only a shift by and we could use +% always the slightly more costly series III in place of series II. But that +% would add one un-needed term and a bit overhead to the default P which is +% 16... +% | +% +% \subsubsection{Log series, case I} +% \begin{macrocode} +\def\XINT_LogTen_serI_a_i#1\xint:{#1}% +\ifnum\XINTdigits>9 +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serI_a_i##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_ii + \romannumeral0\XINTinfloatS[#2]{##1}\xint: +}% +\def\XINT_LogTen_serI_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{##10}[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-7\expandafter.% + \the\numexpr\XINTdigits-1.% +\fi +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-7.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serI_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-13]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>27 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-25\expandafter.% + \the\numexpr\XINTdigits-19\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-13]{1/3[0]}.% }% - \def##5####1####2% \XINT_expr_checkp_<op> - {% - \ifnum ####1>\XINT_expr_precedence_** - \expandafter##5% - \romannumeral`&&@\csname XINT_##6_op_####2\expandafter\endcsname - \else - \expandafter ####1\expandafter ####2% - \fi +\fi +\ifnum\XINTdigits>33 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-31\expandafter.% + \the\numexpr\XINTdigits-25.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>39 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-37\expandafter.% + \the\numexpr\XINTdigits-31\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-31]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>45 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serI_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-43\expandafter.% + \the\numexpr\XINTdigits-37\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-37]{1/7[0]}.% + \XINTinFloat[\XINTdigits-31]{-1/6[0]}.% }% - }% - \expandafter\XINT_tmpa - \csname XINT_expr_op_-ix\expandafter\endcsname - \csname XINT_expr_check-_**\endcsname - \XINT_expr_op_** - \XINT_expr_exec_** - \XINT_expr_checkp_** {expr}% - \expandafter\XINT_tmpa - \csname XINT_flexpr_op_-ix\expandafter\endcsname - \csname XINT_flexpr_check-_**\endcsname - \XINT_flexpr_op_** - \XINT_flexpr_exec_** - \XINT_flexpr_checkp_** {flexpr}% - \def\XINT_expr_exec_** ##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower##1##4}}% +\fi +\ifnum\XINTdigits>51 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-49\expandafter.% + \the\numexpr\XINTdigits-43\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-37]{1/7[0]}.% }% - \let\XINT_flexpr_exec_**\XINT_expr_exec_** +\fi +\ifnum\XINTdigits>57 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: }% -\def\poormanloghack^ +\def\XINT_LogTen_serI_a_x##1\xint: {% - \def\XINT_tmpa ##1##2##3##4##5##6% - {% - \def ##3####1% \XINT_expr_op_<op> - {% - \expanded{\unexpanded{##4{####1}}\expandafter}% - \romannumeral`&&@\expandafter##2\romannumeral`&&@\XINT_expr_getnext + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-55\expandafter.% + \the\numexpr\XINTdigits-49\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-49]{1/9[0]}.% + {-125[-3]}.% +\fi +% \end{macrocode} +% \subsubsection{Log series, case II} +% \begin{macrocode} +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b#1[#2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{#10}[#2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-2\expandafter.% + \the\numexpr\XINTdigits+4.% +\ifnum\XINTdigits>10 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-8\expandafter.% + \the\numexpr\XINTdigits-2.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>16 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serII_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-14\expandafter.% + \the\numexpr\XINTdigits-8\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-8]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>22 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-20\expandafter.% + \the\numexpr\XINTdigits-14\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-8]{1/3[0]}.% }% - \def##2####1% \XINT_expr_check-_<op> - {% - \xint_UDsignfork - ####1{\expandafter##2\romannumeral`&&@##1}% - -{##5####1}% - \krof +\fi +\ifnum\XINTdigits>28 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-26\expandafter.% + \the\numexpr\XINTdigits-20.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>34 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-32\expandafter.% + \the\numexpr\XINTdigits-26\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-26]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>40 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serII_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-38\expandafter.% + \the\numexpr\XINTdigits-32\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-32]{1/7[0]}.% + \XINTinFloat[\XINTdigits-26]{-1/6[0]}.% }% - \def##5####1####2% \XINT_expr_checkp_<op> - {% - \ifnum ####1>\XINT_expr_precedence_^ - \expandafter##5% - \romannumeral`&&@\csname XINT_##6_op_####2\expandafter\endcsname - \else - \expandafter ####1\expandafter ####2% - \fi +\fi +\ifnum\XINTdigits>46 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-44\expandafter.% + \the\numexpr\XINTdigits-38\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-32]{1/7[0]}.% }% - }% - \expandafter\XINT_tmpa - \csname XINT_expr_op_-ix\expandafter\endcsname - \csname XINT_expr_check-_^\endcsname - \XINT_expr_op_^ - \XINT_expr_exec_^ - \XINT_expr_checkp_^ {expr}% - \expandafter\XINT_tmpa - \csname XINT_flexpr_op_-ix\expandafter\endcsname - \csname XINT_flexpr_check-_^\endcsname - \XINT_flexpr_op_^ - \XINT_flexpr_exec_^ - \XINT_flexpr_checkp_^ {flexpr}% - \def\XINT_expr_exec_^ ##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower##1##4}}% +\fi +\ifnum\XINTdigits>52 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-50\expandafter.% + \the\numexpr\XINTdigits-44\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-44]{1/9[0]}.% + {-125[-3]}.% +\fi +\ifnum\XINTdigits>58 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_xi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_xi##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ix + \romannumeral0\xintadd{#3}{##1/11[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_ix##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_viii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-56\expandafter.% + \the\numexpr\XINTdigits-50\expandafter.\expanded{% + {-1[-1]}.% + \XINTinFloat[\XINTdigits-44]{1/9[0]}.% }% - \let\XINT_flexpr_exec_^\XINT_expr_exec_^ +\fi +% \end{macrocode} +% \subsubsection{Log series, case III} +% \begin{macrocode} +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serIII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b#1[#2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{#10}[#2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% }% -\def\poormanloghack#1{\csname poormanloghack#1\endcsname}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-1\expandafter.% + \the\numexpr\XINTdigits+4.% +\ifnum\XINTdigits>9 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-7\expandafter.% + \the\numexpr\XINTdigits-1.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serIII_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-7\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-7]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-7]{1/3[0]}.% + }% +\fi +\ifnum\XINTdigits>27 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-25\expandafter.% + \the\numexpr\XINTdigits-19.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>33 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-31\expandafter.% + \the\numexpr\XINTdigits-25\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-25]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>39 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serIII_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-37\expandafter.% + \the\numexpr\XINTdigits-31\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-31]{1/7[0]}.% + \XINTinFloat[\XINTdigits-25]{-1/6[0]}.% + }% +\fi +\ifnum\XINTdigits>45 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-43\expandafter.% + \the\numexpr\XINTdigits-37\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-31]{1/7[0]}.% + }% +\fi +\ifnum\XINTdigits>51 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-49\expandafter.% + \the\numexpr\XINTdigits-43\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-43]{1/9[0]}.% + {-125[-3]}.% +\fi +\ifnum\XINTdigits>57 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_xi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_xi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ix + \romannumeral0\xintadd{#3}{##1/11[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_ix##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_viii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-55\expandafter.% + \the\numexpr\XINTdigits-49\expandafter.\expanded{% + {-1[-1]}.% + \XINTinFloat[\XINTdigits-43]{1/9[0]}.% + }% +\fi +\XINTendxintloginput% % \end{macrocode} -% \lverb|IMPORTANT: We don't worry about resetting catcodes now as this file is -% theoretically only loadable from xintexpr.sty itself which will take care of -% the needed restore.| % \StoreCodelineNo {xintlog} % \cleardoublepage\let\xintlognameUp\undefined % \MakePercentComment @@ -43309,34 +46342,34 @@ xint.sty:205 xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:272 -xintexpr.sty:428 -xintfrac.sty:507 +xintexpr.sty:431 +xintfrac.sty:506 xintgcd.sty:41 xintkernel.sty:17 -xintlog.sty:9 +xintlog.sty:187 xintseries.sty:48 xinttools.sty:157 -xinttrig.sty:31 +xinttrig.sty:65 \fi % grep -o "^{%" xint*sty | wc -l -\def\totala{ 1951} +\def\totala{ 2165} \iffalse % grep -c -e "^}%" xint*sty xint.sty:204 xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:269 -xintexpr.sty:412 -xintfrac.sty:510 +xintexpr.sty:415 +xintfrac.sty:508 xintgcd.sty:43 xintkernel.sty:18 -xintlog.sty:9 +xintlog.sty:189 xintseries.sty:48 xinttools.sty:156 -xinttrig.sty:32 +xinttrig.sty:64 \fi % grep -o "^}%" xint*sty | wc -l -\def\totalb{ 1936} +\def\totalb{ 2149} \cleardoublepage \section{Cumulative line count} @@ -43360,7 +46393,8 @@ xinttrig.sty:32 \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -\CheckSum {35184}% 1.4d +\CheckSum {38813}% 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 % 31069 pour 1.3b, 30482 pour 1.3a, 30621 pour 1.3, 30988 pour 1.2q, diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty index 731eec9eba8..a0c06cb0417 100644 --- a/Master/texmf-dist/tex/generic/xint/xint.sty +++ b/Master/texmf-dist/tex/generic/xint/xint.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xint: Expandable operations on big integers %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) \XINT_providespackage \ProvidesPackage{xint}% - [2021/03/29 v1.4d Expandable operations on big integers (JFB)]% + [2021/05/05 v1.4e 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}% @@ -1646,7 +1646,7 @@ {No uniformdeviate at engine level, returning 0.} 0% }% \fi -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xint.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty index ef4b736636f..7482824c7ec 100644 --- a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty +++ b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintbinhex: Expandable binary and hexadecimal conversions %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2021/03/29 v1.4d Expandable binary and hexadecimal conversions (JFB)]% + [2021/05/05 v1.4e 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 @@ -496,7 +496,7 @@ }% \def\XINT_chtb_N {\expandafter-\romannumeral0\XINT_chtb_main }% \def\XINT_chtb_main {\csname space\csname\XINT_htb_loop}% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintbinhex.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty index 19f31a35d06..dc8b8838729 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2021/03/29 v1.4d Expandable continued fractions with xint package (JFB)]% + [2021/05/05 v1.4e Expandable continued fractions with xint package (JFB)]% \def\xintCFrac {\romannumeral0\xintcfrac }% \def\xintcfrac #1% {% @@ -1053,7 +1053,7 @@ \expandafter\XINT_gctgc_end_b }% \def\XINT_gctgc_end_b #1#2#3{ #3{#1}}% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintcfrac.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintcore.sty b/Master/texmf-dist/tex/generic/xint/xintcore.sty index c6690c5fd00..b1e52e326fd 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcore.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcore.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintcore: Expandable arithmetic on big integers %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcore}% - [2021/03/29 v1.4d Expandable arithmetic on big integers (JFB)]% + [2021/05/05 v1.4e Expandable arithmetic on big integers (JFB)]% \csname XINT_Clamped_istrapped\endcsname \csname XINT_ConversionSyntax_istrapped\endcsname \csname XINT_DivisionByZero_istrapped\endcsname @@ -2194,7 +2194,7 @@ (load xintfrac or use \@backslashchar xintii\xint_gobble_iv#1!)\MessageBreak}% {}% }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintcore.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintexpr.sty b/Master/texmf-dist/tex/generic/xint/xintexpr.sty index c6889155f66..baf227ba966 100644 --- a/Master/texmf-dist/tex/generic/xint/xintexpr.sty +++ b/Master/texmf-dist/tex/generic/xint/xintexpr.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintexpr: Expandable expression parser %% --------------------------------------------------------------- @@ -82,17 +82,27 @@ \XINTsetupcatcodes% \XINT_providespackage \ProvidesPackage{xintexpr}% - [2021/03/29 v1.4d Expandable expression parser (JFB)]% + [2021/05/05 v1.4e Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% -\def\xintDigits {\futurelet\XINT_token\xintDigitss}% -\def\xintDigitss #1={\afterassignment\xintDigitsss\mathchardef\XINTdigits=}% -\def\xintDigitsss#1{\ifx*\XINT_token\expandafter\xintreloadxinttrig\fi}% +\def\xintreloadscilibs{\xintreloadxintlog\xintreloadxinttrig}% +\def\xintDigits {\futurelet\XINT_token\xintDigits_i}% +\def\xintDigits_i#1={\afterassignment\xintDigits_j\mathchardef\XINT_digits=}% +\def\xintDigits_j#1% +{% + \let\XINTdigits=\XINT_digits + \ifx*\XINT_token\expandafter\xintreloadscilibs\fi +}% \let\xintfracSetDigits\xintSetDigits -\def\xintSetDigits#1#{\if\relax\detokenize{#1}\relax - \else\afterassignment\xintreloadxinttrig\fi - \xintfracSetDigits}% +\def\xintSetDigits#1#{\if\relax\detokenize{#1}\relax\expandafter\xintfracSetDigits + \else\expandafter\xintSetDigits_a\fi}% +\def\xintSetDigits_a#1% +{% + \mathchardef\XINT_digits=\numexpr#1\relax + \let\XINTdigits\XINT_digits + \xintreloadscilibs +}% \def\XINT:expr:toblistwith#1#2% {% {\expandafter\XINT:expr:toblist_checkempty @@ -252,9 +262,9 @@ {% \expandafter\XINT_expr_wrap \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracediRoundzero}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTiRoundzero_braced}% }% -\def\XINTbracediRoundzero#1{{\xintiRound{0}{#1}}}% +\def\XINTiRoundzero_braced#1{{\xintiRound{0}{#1}}}% \def\XINT_iexpr_withopt [#1]% {% \expandafter\XINT_iexpr_round @@ -268,11 +278,11 @@ }% \def\XINT_iexpr_round_a #1.% {% - \expandafter\XINT_expr_wrap + \expandafter\XINT_iexpr_wrap \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracedRound{#1}}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTiRound_braced{#1}}% }% -\def\XINTbracedRound#1#2{{\xintRound{#1}{#2}}}% +\def\XINTiRound_braced#1#2{{\xintiRound{#1}{#2}[\the\numexpr-#1]}}% \def\xintfloatexpro #1% {% \ifx [#1\expandafter\XINT_flexpr_withopt\else\expandafter\XINT_flexpr_noopt @@ -298,23 +308,26 @@ \expandafter\XINT_flexpr_wrap \the\numexpr#1\expandafter.% \expanded - \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTbracedinFloat[#1]}% + \XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTinFloat_braced[#1]}% }% -\def\XINTbracedinFloat[#1]#2{{\XINTinFloat[#1]{#2}}}% +\def\XINTinFloat_braced[#1]#2{{\XINTinFloat[#1]{#2}}}% \def\XINT_expr_wrap {\XINTfstop\XINTexprprint.}% +\def\XINT_iexpr_wrap {\XINTfstop\XINTiexprprint.}% \def\XINT_iiexpr_wrap {\XINTfstop\XINTiiexprprint.}% \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 \def\xintexprEmptyItem{[]}% \protected\def\XINTiiexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintiiexprPrintOne}% \let\xintiiexprPrintOne\xint_firstofone \protected\def\XINTflexprprint #1.% - {\XINT:NEhook:x:toblist\XINT:expr:toblistwith{\xintfloatexprPrintOne{#1}}}% -\def\xintfloatexprPrintOne#1% - {\romannumeral0\XINT_pfloat_opt [\xint:#1]}% bad direct jump + {\XINT:NEhook:x:toblist\XINT:expr:toblistwith{\xintfloatexprPrintOne[#1]}}% +\let\xintfloatexprPrintOne\xintPFloat_wopt \protected\def\XINTboolexprprint.% {\XINT:NEhook:x:toblist\XINT:expr:toblistwith\xintboolexprPrintOne}% \def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% @@ -339,9 +352,20 @@ \def\xintbareeval {\XINT_expr_start }% \def\xintbarefloateval{\XINT_flexpr_start}% \def\xintbareiieval {\XINT_iiexpr_start}% +\def\XINT_expr_unlock {\expandafter\xint_firstofone\romannumeral`&&@}% \def\xintthebareeval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbareeval}% -\def\xintthebarefloateval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbarefloateval}% \def\xintthebareiieval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbareiieval}% +\def\xintthebarefloateval {\romannumeral0\expandafter\xint_stop_atfirstofone\romannumeral0\xintbarefloateval}% +\def\xintthebareroundedfloateval +{% + \romannumeral0\expandafter\xintthebareroundedfloateval_a\romannumeral0\xintbarefloateval +}% +\def\xintthebareroundedfloateval_a +{% + \expandafter\xint_stop_atfirstofone + \expanded\XINT:NEhook:x:mapwithin\XINT:expr:mapwithin{\XINTinFloatSdigits_braced}% +}% +\def\XINTinFloatSdigits_braced#1{{\XINTinFloatS[\XINTdigits]{#1}}}% \def\xinteval #1% {\expanded\expandafter\XINTexprprint\expandafter.\romannumeral0\xintbareeval#1\relax}% \def\xintieval #1% @@ -624,7 +648,7 @@ {% \expandafter\XINT_expr_scanexp_main_b\romannumeral`&&@#1% }% -\def\XINT_expr_scanexpr_hit_cs\ifnum#1\fi#2\XINT_expr_scanexp_again +\def\XINT_expr_scanexp_hit_cs\ifnum#1\fi#2\XINT_expr_scanexp_again {% ]\iffalse{{{\fi}}\expandafter}\romannumeral`&&@\XINT_expr_getop#2% }% @@ -1134,7 +1158,7 @@ \XINT_expr_defbin_b {flexpr} / {xiv}{xiv}{XINTinFloatDiv}% \XINT_expr_defbin_b {iiexpr} / {xiv}{xiv}{xintiiDivRound}% \XINT_expr_defbin_b {expr} ^ {xviii}{xviii}{xintPow}% -\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatPowerH}% +\XINT_expr_defbin_b {flexpr} ^ {xviii}{xviii}{XINTinFloatSciPow}% \XINT_expr_defbin_b {iiexpr} ^ {xviii}{xviii}{xintiiPow}% \catcode`& 12 \xintFor #1 in {and,or,xor,mod} \do @@ -1817,7 +1841,7 @@ {% \expandafter\XINT_expr_put_op_first \expanded{{\romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatFac#1}}\expandafter}\romannumeral`&&@\XINT_expr_getop + {\romannumeral`&&@\XINTinFloatFacdigits#1}}\expandafter}\romannumeral`&&@\XINT_expr_getop }% \def\XINT_iiexpr_op_! #1% {% @@ -1860,7 +1884,8 @@ \def\XINT_expr_defvar #1#2% {% \def\XINT_defvar_tmpa{#2}% - \expandafter\XINT_expr_defvar_a\expandafter#1\romannumeral\XINT_expr_fetch_to_semicolon + \expandafter\XINT_expr_defvar_a\expanded{\unexpanded{{#1}}\expandafter}% + \romannumeral\XINT_expr_fetch_to_semicolon }% \def\XINT_expr_defvar_a #1#2% {% @@ -1875,11 +1900,11 @@ {Aborting: not allowed to declare variable with empty name.}% \or \XINT_global - \expandafter\edef\csname XINT_expr_varvalue_\XINT_defvar_tmpa\endcsname - {\romannumeral0#1#2\relax}% + \expandafter + \edef\csname XINT_expr_varvalue_\XINT_defvar_tmpa\endcsname{#1#2\relax}% \XINT_expr_defvar_one_b\XINT_defvar_tmpa \else - \edef\XINT_defvar_tmpb{\romannumeral0#1#2\relax}% + \edef\XINT_defvar_tmpb{#1#2\relax}% \edef\XINT_defvar_tmpd{\expandafter\xintLength\expandafter{\XINT_defvar_tmpb}}% \let\XINT_defvar_tmpe\empty \if1\XINT_defvar_tmpd @@ -1913,12 +1938,12 @@ }% \catcode`~ 3 \catcode`: 11 -\def\xintdefvar {\xintexprSafeCatcodes\xintdefvar_a}% -\def\xintdefiivar {\xintexprSafeCatcodes\xintdefiivar_a}% -\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}% -\def\xintdefvar_a #1={\XINT_expr_defvar\xintthebareeval {#1}}% -\def\xintdefiivar_a #1={\XINT_expr_defvar\xintthebareiieval {#1}}% -\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintthebarefloateval {#1}}% +\def\xintdefvar {\xintexprSafeCatcodes\xintdefvar_a}% +\def\xintdefvar_a#1={\XINT_expr_defvar\xintthebareeval{#1}}% +\def\xintdefiivar {\xintexprSafeCatcodes\xintdefiivar_a}% +\def\xintdefiivar_a#1={\XINT_expr_defvar\xintthebareiieval{#1}}% +\def\xintdeffloatvar {\xintexprSafeCatcodes\xintdeffloatvar_a}% +\def\xintdeffloatvar_a #1={\XINT_expr_defvar\xintthebareroundedfloateval{#1}}% \def\xintunassignvar #1{% \edef\XINT_unvar_tmpa{#1}% \edef\XINT_unvar_tmpa {\xint_zapspaces_o\XINT_unvar_tmpa}% @@ -2791,7 +2816,7 @@ {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatFracdigits#3}}% + {\romannumeral`&&@\XINTinFloatFrac#3}}% }% \def\XINT_expr_func_floor #1#2#3% {% @@ -2825,7 +2850,6 @@ \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\xintSqr#3}}% }% -\def\XINTinFloatSqr#1{\XINTinFloatMul{#1}{#1}}% \def\XINT_flexpr_func_sqr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% @@ -2942,13 +2966,6 @@ }}% }% \let\XINT_flexpr_func_sqrt\XINT_expr_func_sqrt -\def\XINT_expr_func_sqrt_ #1#2#3% -{% - \expandafter #1\expandafter #2\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatSqrtdigits#3}}% -}% -\let\XINT_flexpr_func_sqrt_\XINT_expr_func_sqrt_ \def\XINT_iiexpr_func_sqrt #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% @@ -4284,13 +4301,14 @@ \fi}@ }@ \catcode`% 14 -\XINT_setcatcodes % clean up to avoid surprises if something changes +\XINTsetcatcodes % clean up to avoid surprises if something changes \newif\ifxintexprsafecatcodes \let\xintexprRestoreCatcodes\empty \def\xintexprSafeCatcodes {% \unless\ifxintexprsafecatcodes \edef\xintexprRestoreCatcodes {% + \endlinechar=\the\endlinechar \catcode59=\the\catcode59 % ; \catcode34=\the\catcode34 % " \catcode63=\the\catcode63 % ? @@ -4319,6 +4337,7 @@ }% \fi \xintexprsafecatcodestrue + \endlinechar=13 % \catcode59=12 % ; \catcode34=12 % " \catcode63=12 % ? @@ -4352,7 +4371,7 @@ {\input xinttrig.sty \input xintlog.sty }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintexpr.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty index a10aa57392a..9da94186939 100644 --- a/Master/texmf-dist/tex/generic/xint/xintfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintfrac.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintfrac: Expandable operations on fractions %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintfrac}% - [2021/03/29 v1.4d Expandable operations on fractions (JFB)]% + [2021/05/05 v1.4e Expandable operations on fractions (JFB)]% \def\XINT_cntSgnFork #1% {% \ifcase #1\expandafter\xint_secondofthree @@ -458,59 +458,37 @@ \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}}% -\edef\xintFracToSci #1% - {\unexpanded{\expandafter\XINT_FracToSci\romannumeral`&&@}#1\string e% - \unexpanded{\Z/\W[\R]}}% +\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% \def\XINT_FracToSci #1/#2#3[#4% {% - \xint_gob_til_W #2\XINT_FracToSci_no\W - \xint_gob_til_R #4\XINT_FracToSci_yesno\R - \XINT_FracToSci_yesyes #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_no #1\XINT_FracToSci_yesyes #2[#3% +\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% {% - \xint_gob_til_R #3\XINT_FracToSci_nono\R - \XINT_FracToSci_noyes #2[#3% + \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R + \XINT_FracToSci_noslash_N #2[#3% }% -\edef\XINT_tmpa{##1\string e##2}% -\def\XINT_tmpb{\def\XINT_FracToSci_nono\R\XINT_FracToSci_noyes}% -\expandafter -\XINT_tmpb\XINT_tmpa +\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% {% - #1\xint_gob_til_Z #2\XINT_FracToSci_nonono\Z - \XINT_FracToSci_nonoyes #2% -}% -\edef\XINT_tmpa{##1\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_nonoyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]{\xintFracToSciE#1}% -\def\XINT_FracToSci_nonono\Z\XINT_FracToSci_nonoyes\Z/\W[\R]{}% -\edef\XINT_tmpa{##1##2[##3]\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_noyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% -{% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\ifnum #3=\xint_c_\else\xintFracToSciE#3\fi\fi + \ifnum#2=\xint_c_ #1\else + \romannumeral0\expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1[#2]}% + \fi }% -\edef\XINT_tmpa{##1##2/##3\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_yesno\R\XINT_FracToSci_yesyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% +\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 }% -\edef\XINT_tmpa{##1##2/##3[##4]\string e}% - \def\XINT_tmpb{\def\XINT_FracToSci_yesyes}% -\expandafter -\XINT_tmpb\XINT_tmpa\Z/\W[\R]% +\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% {% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\ifnum #4=\xint_c_\else\xintFracToSciE#4\fi - \if\XINT_isOne{#3}1\else/#3\fi\fi + \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\xintFracToSciE{e}% \def\xintRawWithZeros {\romannumeral0\xintrawwithzeros }% \def\xintrawwithzeros {% @@ -547,6 +525,8 @@ \ifnum#3<\xint_c_\xint_dothis{\xinttrunc{-#3}{#1[#3]}/#2}\fi \xint_orthat{\xintiie{#1}{#3}/#2}% }% +\def\xintDecToStringREZ{\romannumeral0\xintdectostringrez}% +\def\xintdectostringrez#1{\expandafter\XINT_dectostr\romannumeral0\xintrez{#1}}% \def\xintFloor {\romannumeral0\xintfloor }% \def\xintfloor #1% devrais-je faire \xintREZ? {\expandafter\XINT_ifloor \romannumeral0\xintrawwithzeros {#1}./1[0]}% @@ -2096,11 +2076,20 @@ \xint_gob_til_zero#1\XINT_flcmof_zero0\XINT_flcmof_loop#1% }% \def\XINT_flcmof_zero#1^{ 0/1[0]}% -\mathchardef\XINTdigits 16 -\def\xintDigits #1=% - {\afterassignment \xint_gobble_i \mathchardef\XINTdigits=}% -\def\xinttheDigits {\number\XINTdigits }% -\def\xintSetDigits #1{\mathchardef\XINTdigits=\numexpr#1\relax}% +\mathchardef\XINTdigits 16 +\chardef\XINTguarddigits 0 +\def\xinttheDigits {\number\XINTdigits}% +\def\xinttheGuardDigits{0}% in case used in some of my test files +\def\xintDigits #1={\afterassignment\xintDigits_i\mathchardef\XINT_digits=}% +\def\xintDigits_i#1% +{% + \let\XINTdigits\XINT_digits +}% +\def\xintSetDigits #1% +{% + \mathchardef\XINT_digits=\numexpr#1\relax + \let\XINTdigits=\XINT_digits +}% \def\xintFloat {\romannumeral0\xintfloat }% \def\xintfloat #1{\XINT_float_chkopt #1\xint:}% \def\XINT_float_chkopt #1% @@ -2159,6 +2148,7 @@ \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 @@ -2350,8 +2340,12 @@ \expandafter\XINT_infloat_ZZ\the\numexpr#4+\xint_c_i.#3.% }% \def\XINT_infloat_ZZ #1.#2.{ 1#2[#1]}% -\def\xintPFloat {\romannumeral0\xintpfloat }% +\def\xintPFloat {\romannumeral0\xintpfloat }% \def\xintpfloat #1{\XINT_pfloat_chkopt #1\xint:}% +\def\xintPFloat_wopt +{% + \romannumeral0\expandafter\XINT_pfloat\romannumeral0\XINTinfloatS +}% \def\XINT_pfloat_chkopt #1% {% \ifx [#1\expandafter\XINT_pfloat_opt @@ -2360,53 +2354,64 @@ }% \def\XINT_pfloat_noopt #1\xint:% {% - \expandafter\XINT_pfloat_a - \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% }% \def\XINT_pfloat_opt [\xint:#1]% {% - \expandafter\XINT_pfloat_opt_a \the\numexpr #1.% + \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]% }% -\def\XINT_pfloat_opt_a #1.#2% +\def\XINT_pfloat#1]% {% - \expandafter\XINT_pfloat_a\romannumeral0\xintfloat [#1]{#2};#1.% + \expandafter\XINT_pfloat_fork\romannumeral0\xintrez{#1]}% }% -\def\XINT_pfloat_a #1% +\def\XINT_pfloat_fork#1% {% \xint_UDzerominusfork - #1-\XINT_pfloat_zero - 0#1\XINT_pfloat_neg + #1-\XINT_pfloat_zero + 0#1\XINT_pfloat_neg 0-\XINT_pfloat_pos \krof #1% }% -\def\XINT_pfloat_zero #1;#2.{ 0.}% -\def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos }% -\def\XINT_pfloat_pos #1.#2e#3;#4.% +\def\XINT_pfloat_zero#1]{ 0.0}% +\def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos}% +\def\XINT_pfloat_pos#1/1[#2]% +{% + \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.% + #2.#1.% +}% +\def\XINT_pfloat_a #1.#2#3.% +{% + \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% + #2#1.% +}% +\def\XINT_pfloat_b #1.#2% {% - \ifnum #3>\xint_c_v \xint_dothis\XINT_pfloat_no\fi - \ifnum #3<-\xint_c_v \xint_dothis\XINT_pfloat_no\fi - \ifnum #3<\xint_c_ \xint_dothis\XINT_pfloat_N\fi - \ifnum #3>\numexpr #4-\xint_c_i\relax \xint_dothis\XINT_pfloat_Ps\fi - \xint_orthat\XINT_pfloat_P #1{#2}{#3}% + \ifnum #1>\xint_c_v \xint_dothis\XINT_pfloat_sci\fi + \ifnum #1<-\xint_c_iv \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 + #1.% }% -\def\XINT_pfloat_no +\def\XINT_pfloat_sci #1.#2.% {% - \expandafter\XINT_pfloat_no_e\expandafter{\xintPFloatE}% + \ifnum#2=\xint_c_i\expandafter\XINT_pfloat_sci_i\expandafter\fi + \expandafter\XINT_pfloat_sci_a\romannumeral`&&@\xintPFloatE #1.% }% -\def\XINT_pfloat_no_e #1#2#3#4{ #2.#3#1#4}% +\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_N #1#2#3% +\def\XINT_pfloat_N#1.#2.#3.% {% - \csname XINT_pfloat_N_\romannumeral-#3\endcsname #1#2% + \csname XINT_pfloat_N_\romannumeral-#1\endcsname #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_v { 0.0000}% -\def\XINT_pfloat_P #1#2#3% +\def\XINT_pfloat_P #1.#2.#3.% {% - \csname XINT_pfloat_P_\romannumeral#3\endcsname #1#2% + \csname XINT_pfloat_P_\romannumeral#1\endcsname #3% }% \def\XINT_pfloat_P_ #1{ #1.}% \def\XINT_pfloat_P_i #1#2{ #1#2.}% @@ -2414,25 +2419,28 @@ \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#3\endcsname #1#200000;% -}% -\def\XINT_pfloat_Psi #1#2#3;{ #1#2.}% -\def\XINT_pfloat_Psii #1#2#3#4;{ #1#2#3.}% -\def\XINT_pfloat_Psiii#1#2#3#4#5;{ #1#2#3#4.}% -\def\XINT_pfloat_Psiv #1#2#3#4#5#6;{ #1#2#3#4#5.}% -\def\XINT_pfloat_Psv #1#2#3#4#5#6#7;{ #1#2#3#4#5#6.}% -\def\XINTinFloatFracdigits {\romannumeral0\XINTinfloatfracdigits }% -\def\XINTinfloatfracdigits #1% -{% - \expandafter\XINT_infloatfracdg_a\expandafter {\romannumeral0\xinttfrac{#1}}% -}% -\def\XINT_infloatfracdg_a {\XINTinfloat [\XINTdigits]}% -\def\xintFloatAdd {\romannumeral0\xintfloatadd }% -\def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatAdd {\romannumeral0\XINTinfloatadd }% -\def\XINTinfloatadd #1{\XINT_fladd_chkopt \XINTinfloatS #1\xint:}% +\def\XINT_pfloat_Ps #1.#2.#3.% +{% + \csname XINT_pfloat_Ps_\romannumeral#1\endcsname #300000.% +}% +\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% +{% + \expandafter\XINT_infloatfrac_a\expandafter {\romannumeral0\xinttfrac{#1}}% +}% +\def\XINT_infloatfrac_a {\XINTinfloat[\XINTdigits]}% +\def\xintFloatAdd {\romannumeral0\xintfloatadd}% +\def\xintfloatadd #1{\XINT_fladd_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatAdd{\romannumeral0\XINTinfloatadd }% +\def\XINTinfloatadd{\XINT_fladd_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatAdd_wopt{\romannumeral0\XINTinfloatadd_wopt}% +\def\XINTinfloatadd_wopt[#1]{\expandafter\XINT_fladd_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_fladd_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fladd_opt @@ -2472,10 +2480,12 @@ \ifnum\numexpr #5-#3-#2>\xint_c_\xint_dothis\xint_secondoftwo\fi \xint_orthat\xintAdd {#1[#2]}{#4[#5]}% }% -\def\xintFloatSub {\romannumeral0\xintfloatsub }% -\def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatSub {\romannumeral0\XINTinfloatsub }% -\def\XINTinfloatsub #1{\XINT_flsub_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatSub {\romannumeral0\xintfloatsub}% +\def\xintfloatsub #1{\XINT_flsub_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSub{\romannumeral0\XINTinfloatsub}% +\def\XINTinfloatsub{\XINT_flsub_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatSub_wopt{\romannumeral0\XINTinfloatsub_wopt}% +\def\XINTinfloatsub_wopt[#1]{\expandafter\XINT_flsub_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flsub_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsub_opt @@ -2496,10 +2506,12 @@ {% #2[#1]{\expandafter\XINT_FL_add_a\romannumeral0\XINTinfloat[#1]{#3}#1.{\xintOpp{#4}}}% }% -\def\xintFloatMul {\romannumeral0\xintfloatmul }% -\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatMul {\romannumeral0\XINTinfloatmul }% -\def\XINTinfloatmul #1{\XINT_flmul_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatMul {\romannumeral0\xintfloatmul}% +\def\xintfloatmul #1{\XINT_flmul_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatMul{\romannumeral0\XINTinfloatmul}% +\def\XINTinfloatmul{\XINT_flmul_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatMul_wopt{\romannumeral0\XINTinfloatmul_wopt}% +\def\XINTinfloatmul_wopt[#1]{\expandafter\XINT_flmul_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flmul_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flmul_opt @@ -2525,11 +2537,38 @@ \expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloatS[#3]{#4}#1[#2]% }% \def\XINT_FL_mul_b #1[#2]#3[#4]{\xintiiMul{#3}{#1}/1[#4+#2]}% +\def\xintFloatSqr {\romannumeral0\xintfloatsqr}% +\def\xintfloatsqr #1{\XINT_flsqr_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSqr{\romannumeral0\XINTinfloatsqr}% +\def\XINTinfloatsqr{\XINT_flsqr_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINT_flsqr_chkopt #1#2% +{% + \ifx [#2\expandafter\XINT_flsqr_opt + \else\expandafter\XINT_flsqr_noopt + \fi #1#2% +}% +\def\XINT_flsqr_noopt #1#2\xint: +{% + #1[\XINTdigits]% + {\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[\XINTdigits]{#2}}% +}% +\def\XINT_flsqr_opt #1[\xint:#2]% +{% + \expandafter\XINT_flsqr_opt_a\the\numexpr #2.#1% +}% +\def\XINT_flsqr_opt_a #1.#2#3% +{% + #2[#1]{\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[#1]{#3}}% +}% +\def\XINT_FL_sqr_a #1[#2]{\xintiiSqr{#1}/1[#2+#2]}% +\def\XINTinFloatSqr_wopt[#1]#2{\XINTinFloatS[#1]{\expandafter\XINT_FL_sqr_a\romannumeral0\XINTinfloatS[#1]{#2}}}% \def\XINTinFloatInv#1{\XINTinFloatS[\XINTdigits]{\xintInv{#1}}}% -\def\xintFloatDiv {\romannumeral0\xintfloatdiv }% -\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatDiv {\romannumeral0\XINTinfloatdiv }% -\def\XINTinfloatdiv #1{\XINT_fldiv_chkopt \XINTinfloatS #1\xint:}% +\def\XINTinFloatInv_wopt[#1]#2{\XINTinFloatS[#1]{\xintInv{#2}}}% +\def\xintFloatDiv {\romannumeral0\xintfloatdiv}% +\def\xintfloatdiv #1{\XINT_fldiv_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatDiv{\romannumeral0\XINTinfloatdiv}% +\def\XINTinfloatdiv{\XINT_fldiv_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinFloatDiv_wopt[#1]{\romannumeral0\XINT_fldiv_opt_a#1.\XINTinfloatS}% \def\XINT_fldiv_chkopt #1#2% {% \ifx [#2\expandafter\XINT_fldiv_opt @@ -2555,10 +2594,11 @@ \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloatS[#3]{#4}/#1e#2% }% \def\XINT_FL_div_b #1[#2]{#1e#2}% -\def\xintFloatPow {\romannumeral0\xintfloatpow}% -\def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPow {\romannumeral0\XINTinfloatpow }% -\def\XINTinfloatpow #1{\XINT_flpow_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatPow {\romannumeral0\xintfloatpow}% +\def\xintfloatpow #1{\XINT_flpow_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPow{\romannumeral0\XINTinfloatpow }% +\def\XINTinfloatpow{\XINT_flpow_opt_a\XINTdigits.\XINTinfloatS}% +\def\XINTinfloatpow_wopt[#1]{\expandafter\XINT_flpow_opt_a\the\numexpr#1.\XINTinfloatS}% \def\XINT_flpow_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpow_opt @@ -2710,47 +2750,10 @@ }% \def\XINT_flpow_IIIend #1#2#3% {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}% -\def\xintFloatPower {\romannumeral0\xintfloatpower}% -\def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPower {\romannumeral0\XINTinfloatpower }% -\def\XINTinfloatpower #1{\XINT_flpower_chkopt \XINTinfloatS #1\xint:}% -\def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerh }% -\def\XINTinfloatpowerh #1#2% -{% - \expandafter\XINT_flpowerh_a\romannumeral0\xintitrunc1{#2};% - \XINTdigits.{#1}{\XINTinfloatS[\XINTdigits]}% -}% -\def\XINT_flpowerh_a #1;% -{% - \if0\xintLDg{#1}\expandafter\XINT_flpowerh_int - \else\expandafter\XINT_flpowerh_b - \fi #1.% -}% -\def\XINT_flpowerh_int #1% -{% - \if0#1\expandafter\XINT_flpower_BisZero - \else\expandafter\XINT_flpowerh_i - \fi #1% -}% -\def\XINT_flpowerh_i #10.{\expandafter\XINT_flpower_checkB_a#1.}% -\def\XINT_flpowerh_b #1.% -{% - \expandafter\XINT_flpowerh_c\romannumeral0\xintdsrr{\xintDouble{#1}}.% -}% -\def\XINT_flpowerh_c #1.% -{% - \ifodd\xintLDg{#1} %<- intentional space - \expandafter\XINT_flpowerh_d\else\expandafter\XINT_flpowerh_e - \fi #1.% -}% -\def\XINT_flpowerh_d #1.\XINTdigits.#2#3% -{% - \XINT_flpower_checkB_a #1.\XINTdigits.{#2}\XINT_flpowerh_finish -}% -\def\XINT_flpowerh_finish #1% - {\XINTinfloatS[\XINTdigits]{\XINTinFloatSqrt[\XINTdigits+\xint_c_iii]{#1}}}% -\def\XINT_flpowerh_e #1.% - {\expandafter\XINT_flpower_checkB_a\romannumeral0\xinthalf{#1}.}% +\def\xintFloatPower {\romannumeral0\xintfloatpower}% +\def\xintfloatpower #1{\XINT_flpower_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPower{\romannumeral0\XINTinfloatpower }% +\def\XINTinfloatpower{\XINT_flpower_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flpower_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpower_opt @@ -2877,10 +2880,11 @@ \the\numexpr\expandafter\XINT_flpow_truncate \the\numexpr#2+#5\expandafter.\romannumeral0\xintiimul{#3}{#6}.#4.% }% -\def\xintFloatFac {\romannumeral0\xintfloatfac}% -\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatFac {\romannumeral0\XINTinfloatfac }% -\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloatS #1\xint:}% +\def\xintFloatFac {\romannumeral0\xintfloatfac}% +\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatFac{\romannumeral0\XINTinfloatfac}% +\def\XINTinfloatfac[#1]{\expandafter\XINT_flfac_opt_a\the\numexpr#1.\XINTinfloatS}% +\def\XINTinFloatFacdigits{\romannumeral0\XINT_flfac_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flfac_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flfac_opt @@ -3100,10 +3104,10 @@ {1#2\expandafter!\expandafter-\expandafter1\expandafter [\the\numexpr #4+\xint_c_viii]}% }% -\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% -\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatPFactorial {\romannumeral0\XINTinfloatpfactorial }% -\def\XINTinfloatpfactorial #1{\XINT_flpfac_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatPFactorial {\romannumeral0\xintfloatpfactorial}% +\def\xintfloatpfactorial #1{\XINT_flpfac_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatPFactorial{\romannumeral0\XINTinfloatpfactorial }% +\def\XINTinfloatpfactorial{\XINT_flpfac_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flpfac_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flpfac_opt @@ -3119,9 +3123,9 @@ }% \def\XINT_flpfac_opt #1[\xint:#2]% {% - \expandafter\XINT_flpfac_opt_b\the\numexpr #2.#1% + \expandafter\XINT_flpfac_opt_a\the\numexpr #2.#1% }% -\def\XINT_flpfac_opt_b #1.#2#3#4% +\def\XINT_flpfac_opt_a #1.#2#3#4% {% \expandafter\XINT_FL_pfac_fork \the\numexpr \xintNum{#3}\expandafter.% @@ -3282,10 +3286,10 @@ \romannumeral0\expandafter\XINT_FL_fac_mul \the\numexpr \xint_c_x^viii+#1!% }% -\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% -\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatBinomial {\romannumeral0\XINTinfloatbinomial }% -\def\XINTinfloatbinomial #1{\XINT_flbinom_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatBinomial {\romannumeral0\xintfloatbinomial}% +\def\xintfloatbinomial #1{\XINT_flbinom_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatBinomial{\romannumeral0\XINTinfloatbinomial }% +\def\XINTinfloatbinomial{\XINT_flbinom_opt\XINTinfloatS[\xint:\XINTdigits]}% \def\XINT_flbinom_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flbinom_opt @@ -3345,10 +3349,11 @@ {\XINT_FL_fac_fork_b #2.\xint_c_iv{#4+\xint_c_i}\XINT_FL_fac_out{\XINTinfloat[#4+\xint_c_iii]}}}% }% -\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt }% -\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}% -\def\XINTinFloatSqrt {\romannumeral0\XINTinfloatsqrt }% -\def\XINTinfloatsqrt #1{\XINT_flsqrt_chkopt \XINTinfloat #1\xint:}% +\def\xintFloatSqrt {\romannumeral0\xintfloatsqrt}% +\def\xintfloatsqrt #1{\XINT_flsqrt_chkopt \xintfloat #1\xint:}% +\def\XINTinFloatSqrt{\romannumeral0\XINTinfloatsqrt}% +\def\XINTinfloatsqrt[#1]{\expandafter\XINT_flsqrt_opt_a\the\numexpr#1.\XINTinfloatS}% +\def\XINTinFloatSqrtdigits{\romannumeral0\XINT_flsqrt_opt_a\XINTdigits.\XINTinfloatS}% \def\XINT_flsqrt_chkopt #1#2% {% \ifx [#2\expandafter\XINT_flsqrt_opt @@ -3504,7 +3509,7 @@ \def\XINT_infloatdivmod #1#2#3{\expanded{{#1}{\XINTinFloat[#3]{#2}}}}% \def\xintifFloatInt {\romannumeral0\xintiffloatint}% \def\xintiffloatint #1{\expandafter\XINT_iffloatint - \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}}% + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}}% \def\XINT_iffloatint #1#2/1[#3]% {% \if 0#1\xint_dothis\xint_stop_atfirstoftwo\fi @@ -3513,12 +3518,23 @@ }% \def\xintFloatIsInt {\romannumeral0\xintfloatisint}% \def\xintfloatisint #1{\expandafter\XINT_iffloatint - \romannumeral0\xintrez{\XINTinFloat[\XINTdigits]{#1}}10}% -\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% -\def\XINTinFloatSdigits {\XINTinFloatS [\XINTdigits]}% -\def\XINTinFloatSqrtdigits {\XINTinFloatSqrt[\XINTdigits]}% -\def\XINTinFloatFacdigits {\XINTinFloatFac [\XINTdigits]}% -\def\XINTFloatiLogTendigits{\XINTFloatiLogTen[\XINTdigits]}% + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}10}% +\def\xintFloatIntType {\romannumeral`&&@\xintfloatinttype}% +\def\xintfloatinttype #1% +{% + \expandafter\XINT_floatinttype + \romannumeral0\xintrez{\XINTinFloatS[\XINTdigits]{#1}}% +}% +\def\XINT_floatinttype #1#2/1[#3]% +{% + \if 0#1\xint_dothis\xint_c_\fi + \ifnum#3<\xint_c_\xint_dothis\xint_c_mone\fi + \ifnum#3>\xint_c_\xint_dothis\xint_c_\fi + \ifodd\xintLDg{#1#2} \xint_dothis\xint_c_i\fi + \xint_orthat\xint_c_ +}% +\def\XINTinFloatdigits {\XINTinFloat [\XINTdigits]}% +\def\XINTinFloatSdigits{\XINTinFloatS[\XINTdigits]}% \def\XINTinRandomFloatS{\romannumeral0\XINTinrandomfloatS}% \def\XINTinRandomFloatSdigits{\XINTinRandomFloatS[\XINTdigits]}% \def\XINTinrandomfloatS[#1]% @@ -3548,54 +3564,11 @@ \romannumeral`&&@\expandafter\XINT_eightrandomdigits \romannumeral`&&@\XINT_eightrandomdigits[-16]% }% -\def\PoorManLogBaseTen{\romannumeral0\poormanlogbaseten}% -\def\poormanlogbaseten #1% - {\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]{#1}}% -\def\PML@logbaseten#1[#2]% -{% - \xintiiadd{\xintDSx{-9}{\the\numexpr#2+8\relax}}{\the\numexpr\PML@#1.}% - [-9]% -}% -\def\PoorManPowerOfTen{\the\numexpr\poormanpoweroften}% -\def\poormanpoweroften #1% - {\expandafter\PML@powoften\romannumeral0\xintraw{#1}}% -\def\PML@powoften#1% -{% - \xint_UDzerominusfork - #1-\PML@powoften@zero - 0#1\PML@powoften@neg - 0-\PML@powoften@pos - \krof #1% -}% -\def\PML@powoften@zero 0{1\relax}%/1[0] -\def\PML@powoften@pos#1[#2]% -{% - \expandafter\PML@powoften@pos@a\romannumeral0\xintround{9}{#1[#2]}.% -}% -\def\PML@powoften@pos@a#1.#2.{\PML@Pa#2.\expandafter[\the\numexpr-8+#1]}% -\def\PML@powoften@neg#1[#2]% -{% - \expandafter\PML@powoften@neg@a\romannumeral0\xintround{9}{#1[#2]}.% -}% -\def\PML@powoften@neg@a#1.#2.% -{\ifnum#2=\xint_c_ \xint_afterfi{1\relax/1[#1]}\else - \expandafter\expandafter\expandafter - \PML@Pa\expandafter\xint_gobble_i\the\numexpr2000000000-#2.% - \expandafter[\the\numexpr-9+#1\expandafter]\fi -}% -\def\PoorManPower#1#2% -{% - \PoorManPowerOfTen{\xintMul{#2}{\PoorManLogBaseTen{#1}}}% -}% -\def\xintLog#1{\xintMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}% -\def\XINTinFloatLog#1{\XINTinFloatMul{\PoorManLogBaseTen{#1}}{23025850923[-10]}}% -\def\xintExp#1{\PoorManPowerOfTen{\xintMul{#1}{434294481903[-12]}}}% -\def\XINTinFloatExp#1{\PoorManPowerOfTen{\XINTinFloatMul{#1}{434294481903[-12]}}}% \let\XINTinFloatMaxof\XINT_Maxof \let\XINTinFloatMinof\XINT_Minof \let\XINTinFloatSum\XINT_Sum \let\XINTinFloatPrd\XINT_Prd -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintfrac.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty index 4ecd9df5c00..83821ea8815 100644 --- a/Master/texmf-dist/tex/generic/xint/xintgcd.sty +++ b/Master/texmf-dist/tex/generic/xint/xintgcd.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintgcd: Euclidean algorithm with xint package %% --------------------------------------------------------------- @@ -77,7 +77,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintgcd}% - [2021/03/29 v1.4d Euclide algorithm with xint package (JFB)]% + [2021/05/05 v1.4e Euclide algorithm with xint package (JFB)]% \def\xintBezout {\romannumeral0\xintbezout }% \def\xintbezout #1% {% @@ -392,7 +392,7 @@ \par \endgroup }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintgcd.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty index b94e724b17a..19fcfed741d 100644 --- a/Master/texmf-dist/tex/generic/xint/xintkernel.sty +++ b/Master/texmf-dist/tex/generic/xint/xintkernel.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintkernel: Paraphernalia for the xint packages %% --------------------------------------------------------------- @@ -59,7 +59,7 @@ \def\PrepareCatcodes {% \endgroup - \def\XINT_restorecatcodes + \def\XINTrestorecatcodes {% takes care of all, to allow more economical code in modules \catcode0=\the\catcode0 % \catcode59=\the\catcode59 % ; xintexpr @@ -73,7 +73,7 @@ \catcode33=\the\catcode33 % ! xintexpr \catcode93=\the\catcode93 % ] -, xintfrac, xintseries, xintcfrac \catcode91=\the\catcode91 % [ -, xintfrac, xintseries, xintcfrac - \catcode36=\the\catcode36 % $ xintgcd only + \catcode36=\the\catcode36 % $ xintgcd only $ \catcode94=\the\catcode94 % ^ \catcode96=\the\catcode96 % ` \catcode47=\the\catcode47 % / @@ -96,11 +96,11 @@ \catcode32=\the\catcode32 % \catcode61=\the\catcode61\relax % = }% - \edef\XINT_restorecatcodes_endinput + \edef\XINTrestorecatcodesendinput {% - \XINT_restorecatcodes\noexpand\endinput % + \XINTrestorecatcodes\noexpand\endinput % }% - \def\XINT_setcatcodes + \def\XINTsetcatcodes {% \catcode61=12 % = \catcode32=10 % space @@ -138,15 +138,17 @@ \catcode0=12 % for \romannumeral`&&@ trick \catcode1=3 % for ultra-safe séparateur &&A }% - \XINT_setcatcodes + \let\XINT_setcatcodes\XINTsetcatcodes + \let\XINT_restorecatcodes\XINTrestorecatcodes + \XINTsetcatcodes }% \PrepareCatcodes \def\XINTsetupcatcodes {% for use by other modules - \edef\XINT_restorecatcodes_endinput + \edef\XINTrestorecatcodesendinput {% - \XINT_restorecatcodes\noexpand\endinput % + \XINTrestorecatcodes\noexpand\endinput % }% - \XINT_setcatcodes + \XINTsetcatcodes }% \ifdefined\ProvidesPackage \let\XINT_providespackage\relax @@ -157,7 +159,7 @@ \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2021/03/29 v1.4d Paraphernalia for the xint packages (JFB)]% + [2021/05/05 v1.4e Paraphernalia for the xint packages (JFB)]% \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 @@ -262,7 +264,7 @@ \long\def\xint_gob_til_xint:#1\xint:{}% \long\def\xint_gob_til_^#1^{}% \def\xint_bracedstopper{\xint:}% -\long\def\xint_gob_til_exclam #1!{}% documenter le catcode de ! ici +\long\def\xint_gob_til_exclam #1!{}% This ! has catcode 12 \long\def\xint_gob_til_sc #1;{}% \long\def\xint_afterfi #1#2\fi {\fi #1}% \long\def\xint_bye #1\xint_bye {}% @@ -622,7 +624,7 @@ }% \begingroup\lccode`$ 32 \catcode`/ 11 % $ \lowercase{\endgroup\XINT_expandableerror$\xint/\let\xint/\xint_undefined}% $ -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintkernel.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintlog.sty b/Master/texmf-dist/tex/generic/xint/xintlog.sty index 5b4877cd764..e20e40bebcc 100644 --- a/Master/texmf-dist/tex/generic/xint/xintlog.sty +++ b/Master/texmf-dist/tex/generic/xint/xintlog.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintlog: Logarithms and exponentials for xintexpr %% --------------------------------------------------------------- @@ -40,7 +40,6 @@ \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname - \expandafter\let\expandafter\x\csname ver@xintlog.sty\endcsname \expandafter \ifx\csname PackageInfo\endcsname\relax \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% @@ -59,169 +58,1681 @@ \else\string\input\space xintexpr.sty \fi rather, aborting}% \aftergroup\endinput - \else - \ifx\x\relax % first loading (initiated from xintexpr.sty) - \else - \ifx\x\empty % LaTeX first loading, \ProvidesPackage not yet seen - \else - \y{xintlog}{Already loaded, aborting}% - \aftergroup\endinput - \fi - \fi \fi \fi \z% -\xintexprSafeCatcodes\catcode`_ 11 +\edef\XINTendxintloginput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\ifcsname xintlibver@log\endcsname + \expandafter\xint_firstoftwo +\else + \expandafter\xint_secondoftwo +\fi +{\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2021/05/05 v1.4e}% \XINT_providespackage \ProvidesPackage{xintlog}% -[2021/03/29 v1.4d Logarithms and exponentials for xintexpr (JFB)]% +[2021/05/05 v1.4e Logarithms and exponentials for xintexpr (JFB)]% +}% +\def\xintreloadxintlog{\input xintlog.sty }% +\xintexprSafeCatcodes\catcode`_ 11 +\unless\ifdefined\XINTinFloatPowTen \ifdefined\RequirePackage \RequirePackage{poormanlog}% \else \input poormanlog.tex +\fi\fi +\xintexprRestoreCatcodes\XINTsetcatcodes +\def\PoorManLogBaseTen{\romannumeral0\poormanlogbaseten}% +\def\poormanlogbaseten #1% +{% + \XINTinfloat[\XINTdigits]% + {\romannumeral0\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]{#1}}% +}% +\def\PoorManLogBaseTen_raw%#1 +{% + \romannumeral0\expandafter\PML@logbaseten\romannumeral0\XINTinfloat[9]%{#1}% +}% +\def\PML@logbaseten#1[#2]% +{% + \xintiiadd{\xintDSx{-9}{\the\numexpr#2+8\relax}}{\the\numexpr\PML@#1.}[-9]% +}% +\def\PoorManLog#1% +{% + \XINTinFloat[\XINTdigits]{\xintMul{\PoorManLogBaseTen_raw{#1}}{23025850923[-10]}}% +}% +\def\PoorManPowerOfTen{\romannumeral0\poormanpoweroften}% +\def\poormanpoweroften #1% +{% + \expandafter\PML@powoften@out + \the\numexpr\expandafter\PML@powoften\romannumeral0\xintraw{#1}% +}% +\def\PML@powoften@out#1[#2]{\XINTinfloat[\XINTdigits]{#1[#2]}}% +\def\PML@powoften#1% +{% + \xint_UDzerominusfork + #1-\PML@powoften@zero + 0#1\PML@powoften@neg + 0-\PML@powoften@pos + \krof #1% +}% +\def\PML@powoften@zero 0/1[0]{1\relax/1[0]}% +\def\PML@powoften@pos#1[#2]% +{% + \expandafter\PML@powoften@pos@a\romannumeral0\xintround{9}{#1[#2]}.% +}% +\def\PML@powoften@pos@a#1.#2.{\PML@Pa#2.\expandafter[\the\numexpr-8+#1]}% +\def\PML@powoften@neg#1[#2]% +{% + \expandafter\PML@powoften@neg@a\romannumeral0\xintround{9}{#1[#2]}.% +}% +\def\PML@powoften@neg@a#1.#2.% +{% + \ifnum#2=\xint_c_ \xint_afterfi{1\relax/1[#1]}\else + \expandafter\expandafter\expandafter + \PML@Pa\expandafter\xint_gobble_i\the\numexpr2000000000-#2.% + \expandafter[\the\numexpr-9+#1\expandafter]\fi +}% +\def\PoorManExp#1{\PoorManPowerOfTen{\xintMul{#1}{43429448190325182765[-20]}}}% +\def\poormanloghack#1% +{% + \xintMessage{xintexpr}{Warning}% + {\string\poormanloghack\space is a no-op since 1.4e and will be removed at next major release}% +}% +\def\XINTinFloatSciPow{\romannumeral0\XINTinfloatscipow}% +\def\XINTinfloatscipow#1#2% +{% + \expandafter\XINT_scipow_a\romannumeral0\xintrez{#2}\XINT_scipow_int{#1}% +}% +\def\XINT_scipow_a #1% +{% + \xint_gob_til_zero#1\XINT_scipow_Biszero0\XINT_scipow_b#1% +}% +\def\XINT_scipow_Biszero#1]#2#3{ 1[0]}% +\def\XINT_scipow_b #1#2/#3[#4]#5% +{% + \unless\if1\XINT_is_One#3XY\xint_dothis\XINT_scipow_c\fi + \ifnum#4<\xint_c_mone\xint_dothis\XINT_scipow_c\fi + \ifnum#4=\xint_c_mone + \if5\xintLDg{#1#2} % + \xint_afterfi{\xint_dothis\XINT_scipow_halfint}\else + \xint_afterfi{\xint_dothis\XINT_scipow_c}% + \fi + \fi + \xint_orthat#5#1#2/#3[#4]% +}% +\def\XINT_scipow_int #1/1[#2]#3% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\XINT_dsx_addzeros{#2}#1;.\XINTdigits.{#3}{\XINTinfloatS[\XINTdigits]}% +}% +\def\XINT_scipow_halfint#1/1[#2]#3% +{% + \expandafter\XINT_flpower_checkB_a + \romannumeral0\xintdsr{\xintDouble{#1}}.\XINTdigits.{#3}\XINT_flpowerh_finish +}% +\def\XINT_flpowerh_finish #1% + {\XINTinfloatS[\XINTdigits]{\XINTinFloatSqrt[\XINTdigits+\xint_c_iii]{#1}}}% +\def\XINT_tmpa#1.{% +\def\XINT_scipow_c ##1[##2]##3% +{% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloatS[#1]{##3}\xint:##1[##2]\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\def\XINT_scipow_d #1% +{% + \xint_UDzerominusfork + #1-\XINT_scipow_Aiszero + 0#1\XINT_scipow_Aisneg + 0-\XINT_scipow_Aispos + \krof #1% +}% +\def\XINT_scipow_Aiszero #1\xint:#2#3\xint: +{% + \if-#2\xint_dothis + {\XINT_signalcondition{InvalidOperation}{Zero to negative power #2#3}{}{1["7FFF8000]}}\fi + \xint_orthat{ 0[0]}% +}% +\def\XINT_scipow_Aispos #1\xint:#2\xint: +{% + \XINTinfloatpowten{\xintMul{#2}{\XINTinFloatLogTen_xdgout#1}}% +}% +\def\XINT_scipow_Aisneg #1#2\xint:#3\xint: +{% + \XINT_signalcondition{InvalidOperation}{Fractional power of negative argument}{}{0[0]} +}% +\ifnum\XINTdigits<9 + \def\XINTinfloatscipow#1#2% + {% + \expandafter\XINT_scipow_a\romannumeral0\xintraw{#2}\relax{#1}% + }% + \def\XINT_scipow_b #1[#2]#3#4% + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]{#4}\xint:#1[#2]\xint: + }% + \def\XINT_scipow_Aispos #1\xint:#2\xint: + {% + \poormanpoweroften{\xintMul{#2}{\romannumeral0\expandafter\PML@logbaseten#1}}% + }% + \def\XINT_scipow_Aisneg #1#2\xint:#3\xint: + {% + \ifcase\xintFloatIntType{#3}% + \or\expandafter-\romannumeral0% + \else + \expandafter\XINT_scipow_AnegBfrac + \fi + \poormanpoweroften{\xintMul{#3}{\romannumeral0\expandafter\PML@logbaseten#2}}% + }% +\fi +\def\xintPow{\romannumeral0\xintpow}% +\def\xintpow#1#2% +{% + \expandafter\XINT_scipow_a\romannumeral0\xintrez{#2}\XINT_pow_int{#1}% +}% +\def\XINT_pow_int #1/1[#2]%#3 +{% + \expandafter\XINT_pow_int_a\romannumeral0\XINT_dsx_addzeros{#2}#1;.% +}% +\def\XINT_pow_int_a #1#2.#3% +{% + \ifnum\if-#1\xintLength{#2}\else\xintLength{#1#2}\fi>\xint_c_iv + \expandafter\XINT_pow_tosci + \fi + \expandafter\XINT_pow_int_b\romannumeral0\xintraw{#3}\xint:#1#2\xint: +}% +\def\XINT_pow_int_b#1#2/#3[#4]\xint:#5\xint: +{% + \if0\ifnum\numexpr\xint_c_x^iv/% + (\xintLength{#1#2}\if-#1-\xint_c_i\fi)<\XINT_Abs#5 % + 1\else + \ifnum\numexpr\xint_c_x^iv/\xintLength{#3}<\XINT_Abs#5 % + 1\else + 0\fi\fi + \expandafter\XINT_fpow_fork\else\expandafter\XINT_pow_tosci_i + \fi + #5\Z{#4}{#1#2}{#3}% +}% +\def\XINT_tmpa#1.{% +\def\XINT_pow_tosci##1\xintraw%##2%\xint:##3\xint: +{% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloatS[#1]% +}% +\def\XINT_pow_tosci_i##1\Z##2##3##4% +{% + \expandafter\XINT_scipow_d\romannumeral0\expandafter\XINT_infloatS_clean + \romannumeral0\XINT_infloat_a#1.{##2}{##3}{##4}\xint:##1\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\ifnum\XINTdigits<9 + \def\xintpow#1#2% + {% + \expandafter\XINT_poorpow_a\romannumeral0\xintrez{#2}\relax{#1}% + }% + \def\XINT_poorpow_a #1% + {% + \xint_gob_til_zero#1\XINT_scipow_Biszero0\XINT_poorpow_b#1% + }% + \def\XINT_poorpow_b #1#2/#3[#4]#5% + {% + \unless\if1\XINT_is_One#3XY\xint_dothis\XINT_poorpow_c\fi + \ifnum#4<\xint_c_\xint_dothis\XINT_poorpow_c\fi + \xint_orthat\XINT_pow_int#1#2/#3[#4]% + }% + \def\XINT_poorpow_c #1[#2]#3% + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]{#3}\xint:#1[#2]\xint: + }% + \def\XINT_pow_tosci#1\xintraw%#2%\xint:#3\xint: + {% + \expandafter\XINT_scipow_d\romannumeral0\XINTinfloat[9]% + }% + \def\XINT_pow_tosci_i#1\Z#2#3#4% + {% + \expandafter\XINT_scipow_d\romannumeral0\expandafter\XINT_infloat_clean + \romannumeral0\XINT_infloat_a9.{#2}{#3}{#4}\xint:#1\xint: + }% \fi -\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname +\ifnum\XINTdigits<9 \expandafter\def\csname XINT_expr_func_log10\endcsname#1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\PoorManLogBaseTen#3}}% }% -\expandafter\let\csname XINT_flexpr_func_log10\expandafter\endcsname - \csname XINT_expr_func_log10\endcsname \expandafter\def\csname XINT_expr_func_pow10\endcsname#1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\PoorManPowerOfTen#3}}% }% +\else +\expandafter\def\csname XINT_expr_func_log10\endcsname#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINTinFloatLogTen#3}}% +}% +\expandafter\def\csname XINT_expr_func_pow10\endcsname#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINTinFloatPowTen#3}}% +}% +\fi +\expandafter\let\csname XINT_flexpr_func_log10\expandafter\endcsname + \csname XINT_expr_func_log10\endcsname \expandafter\let\csname XINT_flexpr_func_pow10\expandafter\endcsname \csname XINT_expr_func_pow10\endcsname +\ifnum\XINTdigits<9 \def\XINT_expr_func_log #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\xintLog#3}}% + {\romannumeral`&&@\PoorManLog#3}}% }% -\def\XINT_flexpr_func_log #1#2#3% +\def\XINT_expr_func_exp #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\XINTinFloatLog#3}}% + {\romannumeral`&&@\PoorManExp#3}}% }% -\def\XINT_expr_func_exp #1#2#3% +\let\XINT_flexpr_func_log\XINT_expr_func_log +\let\XINT_flexpr_func_exp\XINT_expr_func_exp +\else +\def\XINT_expr_func_log #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one - {\romannumeral`&&@\xintExp#3}}% + {\romannumeral`&&@\XINTinFloatLog#3}}% }% -\def\XINT_flexpr_func_exp #1#2#3% +\def\XINT_expr_func_exp #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one {\romannumeral`&&@\XINTinFloatExp#3}}% }% +\let\XINT_flexpr_func_log\XINT_expr_func_log +\let\XINT_flexpr_func_exp\XINT_expr_func_exp +\fi \def\XINT_expr_func_pow #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower#3}}% + {\romannumeral`&&@\xintPow#3}}% +}% +\def\XINT_flexpr_func_pow #1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:two + {\romannumeral`&&@\XINTinFloatSciPow#3}}% +}% +\ifnum\XINTdigits<9 \expandafter\XINTendxintloginput\fi% +\def\XINT_tmpa{1[0]}% +\expandafter\let\csname XINT_c_1_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_inv\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_1_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_2_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_3_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_4_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_5_0_inv_x\endcsname\XINT_tmpa +\expandafter\let\csname XINT_c_6_0_inv_x\endcsname\XINT_tmpa +\def\XINT_tmpa#1#2#3#4;% + {\expandafter\edef\csname XINT_c_#1_#2\endcsname{\XINTinFloat[\XINTdigits+5]{#3#4[-79]}}% + \expandafter\edef\csname XINT_c_#1_#2_x\endcsname{\XINTinFloat[\XINTdigits+10]{#3#4[-79]}}% + }% +\XINT_tmpa 1 1 12589254117941672104239541063958006060936174094669310691079230195266476157825020;% +\XINT_tmpa 1 2 15848931924611134852021013733915070132694421338250390683162968123166568636684540;% +\XINT_tmpa 1 3 19952623149688796013524553967395355579862743154053460992299136670049309106980490;% +\XINT_tmpa 1 4 25118864315095801110850320677993273941585181007824754286798884209082432477235613;% +\XINT_tmpa 1 5 31622776601683793319988935444327185337195551393252168268575048527925944386392382;% +\XINT_tmpa 1 6 39810717055349725077025230508775204348767703729738044686528414806022485386945804;% +\XINT_tmpa 1 7 50118723362727228500155418688494576806047198983281926392969745588901125568883069;% +\XINT_tmpa 1 8 63095734448019324943436013662234386467294525718822872452772952883349494329768681;% +\XINT_tmpa 1 9 79432823472428150206591828283638793258896063175548433209232392931695569719148754;% +\XINT_tmpa 2 1 10232929922807541309662751748198778273411640572379813085994255856738296458625172;% +\XINT_tmpa 2 2 10471285480508995334645020315281400790567914715039292120056525299012577641023719;% +\XINT_tmpa 2 3 10715193052376064174083022246945087339158659633422172707894501914136771607653870;% +\XINT_tmpa 2 4 10964781961431850131437136061411270464271158762483023169080841607885740984711300;% +\XINT_tmpa 2 5 11220184543019634355910389464779057367223085073605529624450744481701033026862244;% +\XINT_tmpa 2 6 11481536214968827515462246116628360182562102373996119340874991068894793593040890;% +\XINT_tmpa 2 7 11748975549395295417220677651268442278134317971793124791953875805007912852226246;% +\XINT_tmpa 2 8 12022644346174129058326127151935204486942664354881189151104892745683155052368222;% +\XINT_tmpa 2 9 12302687708123815342415404364750907389955639574572144413097319170011637639124482;% +\XINT_tmpa 3 1 10023052380778996719154048893281105540536684535421606464116348523047431367720401;% +\XINT_tmpa 3 2 10046157902783951424046519858132787392010166060319618489538315083825599423438638;% +\XINT_tmpa 3 3 10069316688518041699296607872661381368099438247964820601930206419324524707606686;% +\XINT_tmpa 3 4 10092528860766844119155277641202580844111492027373621434478800545314309618714957;% +\XINT_tmpa 3 5 10115794542598985244409323144543146957419235215102899054703546688078254946034250;% +\XINT_tmpa 3 6 10139113857366794119988279023017296985954042032867436525450889437280417044987125;% +\XINT_tmpa 3 7 10162486928706956276733661150135543062420167220622552197768982666050994284378619;% +\XINT_tmpa 3 8 10185913880541169240797988673338257820431768224957171297560936579346433061037662;% +\XINT_tmpa 3 9 10209394837076799554149033101487543990018213667630072574873723356334069913329713;% +\XINT_tmpa 4 1 10002302850208247526835942556719413318678216124626534526963475845228205382579041;% +\XINT_tmpa 4 2 10004606230728403216239656646745503559081482371024284871882409614422496765669196;% +\XINT_tmpa 4 3 10006910141682589957025973521996241909035914023642264228577379693841345823180462;% +\XINT_tmpa 4 4 10009214583192958761081718336761022426385537997384755843291864010938378093197023;% +\XINT_tmpa 4 5 10011519555381688769842032367472488618040778885656970999331288116685029387850446;% +\XINT_tmpa 4 6 10013825058370987260768186632475607982636715641432550952229573271596547716373358;% +\XINT_tmpa 4 7 10016131092283089653826887255241073941084503769368844606021481400409002185558343;% +\XINT_tmpa 4 8 10018437657240259517971072914549205297136779497498835020699531587537662833033174;% +\XINT_tmpa 4 9 10020744753364788577622204725249622301332888222801030351604197113557132455165040;% +\XINT_tmpa 5 1 10000230261160268806710649793464495797824846841503180050673957122443571394978721;% +\XINT_tmpa 5 2 10000460527622557806255008596155855743730116854295068547616656160734125748005947;% +\XINT_tmpa 5 3 10000690799386989083565213461287219981856579552059660369243804541364501659468630;% +\XINT_tmpa 5 4 10000921076453684726384543254593368743049141124080210677706489564626675960578367;% +\XINT_tmpa 5 5 10001151358822766825267483384008265483772370538793312970508590203623535763866465;% +\XINT_tmpa 5 6 10001381646494357473579790530833073090516914490540536234536867917078761046656260;% +\XINT_tmpa 5 7 10001611939468578767498557382394677469502542123237272447312733350028467607076918;% +\XINT_tmpa 5 8 10001842237745552806012277366194752842273812293689190856411757410911882303011468;% +\XINT_tmpa 5 9 10002072541325401690920909385549403068574626162727745910217443397959031898734024;% +\XINT_tmpa 6 1 10000023025877439451356029805459000097926504781151663770980171880313737943886754;% +\XINT_tmpa 6 2 10000046051807898005897723104514851394069452605882077809669546315010724085277647;% +\XINT_tmpa 6 3 10000069077791375785706217087438809625967243923218032821061587553353589726808164;% +\XINT_tmpa 6 4 10000092103827872912862930047032391734439796534302560512742030066798473305401477;% +\XINT_tmpa 6 5 10000115129917389509449561379274639104559958866285946533811801963402821672829477;% +\XINT_tmpa 6 6 10000138156059925697548091583969382297005329013199894805417325991907389143667949;% +\XINT_tmpa 6 7 10000161182255481599240782265392507269793911275470978276390154932321984777772469;% +\XINT_tmpa 6 8 10000184208504057336610176132939223090407041937631374389422968832433217547184883;% +\XINT_tmpa 6 9 10000207234805653031739097001771331138303016031686764989867510425362339583809842;% +\def\XINT_tmpa#1#2#3#4;% + {\expandafter\edef\csname XINT_c_#1_#2_inv\endcsname{\XINTinFloat[\XINTdigits+5]{#3#4[-80]}}% + \expandafter\edef\csname XINT_c_#1_#2_inv_x\endcsname{\XINTinFloat[\XINTdigits+10]{#3#4[-80]}}% + }% +\XINT_tmpa 1 1 79432823472428150206591828283638793258896063175548433209232392931695569719148754;% +\XINT_tmpa 1 2 63095734448019324943436013662234386467294525718822872452772952883349494329768681;% +\XINT_tmpa 1 3 50118723362727228500155418688494576806047198983281926392969745588901125568883069;% +\XINT_tmpa 1 4 39810717055349725077025230508775204348767703729738044686528414806022485386945804;% +\XINT_tmpa 1 5 31622776601683793319988935444327185337195551393252168268575048527925944386392382;% +\XINT_tmpa 1 6 25118864315095801110850320677993273941585181007824754286798884209082432477235613;% +\XINT_tmpa 1 7 19952623149688796013524553967395355579862743154053460992299136670049309106980490;% +\XINT_tmpa 1 8 15848931924611134852021013733915070132694421338250390683162968123166568636684540;% +\XINT_tmpa 1 9 12589254117941672104239541063958006060936174094669310691079230195266476157825020;% +\XINT_tmpa 2 1 97723722095581068269707600696156123863427170069897801526639004097175507042084888;% +\XINT_tmpa 2 2 95499258602143594972395937950148401513087269708053320302465127242741421479104601;% +\XINT_tmpa 2 3 93325430079699104353209661168364840720225485199736026149257155811788093771138272;% +\XINT_tmpa 2 4 91201083935590974212095940791872333509323858755696109214760361851771695487999100;% +\XINT_tmpa 2 5 89125093813374552995310868107829696398587478293004836994794349506746891059190135;% +\XINT_tmpa 2 6 87096358995608063751082742520877054774747128501284704090761796673224328569285177;% +\XINT_tmpa 2 7 85113803820237646781712631859248682794521725442067093899553745086385146367436049;% +\XINT_tmpa 2 8 83176377110267100616669140273840405263880767161887438462740286611379995442629360;% +\XINT_tmpa 2 9 81283051616409924654127879773132980187568851100062454636602325121954484722491710;% +\XINT_tmpa 3 1 99770006382255331719442194285376231055211861394573154624878230890945476532432225;% +\XINT_tmpa 3 2 99540541735152696244806147089510943107144177264574823668081299845609359857038344;% +\XINT_tmpa 3 3 99311604842093377157642607688515474663519162181123336122073822476734517364853150;% +\XINT_tmpa 3 4 99083194489276757440828314388392035249938006860819409201135652190410238171119287;% +\XINT_tmpa 3 5 98855309465693884028524792978202683686410726723055209558576898759166522286083202;% +\XINT_tmpa 3 6 98627948563121047157261523093421290951784086730437722805070296627452491731402556;% +\XINT_tmpa 3 7 98401110576113374484101831088824192144756194053451911515003663381199842081528019;% +\XINT_tmpa 3 8 98174794301998439937928161622872240632362817134775142288598128693131032909278350;% +\XINT_tmpa 3 9 97948998540869887269961493687844910565420716785032030061251916654655049965062649;% +\XINT_tmpa 4 1 99976976799815658635141604638981297541396466984477711459083930684685186989697929;% +\XINT_tmpa 4 2 99953958900308784552845777251512089759003230012954649234748668826546533498169555;% +\XINT_tmpa 4 3 99930946300258992168693777702512591351888960684418033717545524043693899420866954;% +\XINT_tmpa 4 4 99907938998446176870082987427724649318531547584410414997787083472394558389284098;% +\XINT_tmpa 4 5 99884936993650514951538205746462968844845952521633937925370747725933629958238429;% +\XINT_tmpa 4 6 99861940284652463550037839584112909891259691850983307437097305856727153967481065;% +\XINT_tmpa 4 7 99838948870232760580354983175435314251655958968480344701699631967048474751069525;% +\XINT_tmpa 4 8 99815962749172424670413384320528274471550942114263604264788586703624513163664479;% +\XINT_tmpa 4 9 99792981920252755096658293766085025870392854106037465990011216356523334125368417;% +\XINT_tmpa 5 1 99997697441416293040019992468837639003787989306240470048763511538639048400765328;% +\XINT_tmpa 5 2 99995394935850346394065999228750187791584034668237852053859761641089829514536011;% +\XINT_tmpa 5 3 99993092483300939297147020491645017932348508508297743745039515152378182676736684;% +\XINT_tmpa 5 4 99990790083766851012380885556584619169980753943113396677545915245611923361705686;% +\XINT_tmpa 5 5 99988487737246860830993605587529673614422529030613405900998412734419982883669223;% +\XINT_tmpa 5 6 99986185443739748072318726405984801565268578044798475766025647187221659622450651;% +\XINT_tmpa 5 7 99983883203244292083796681298546635825139453823571398432959235283529730820181019;% +\XINT_tmpa 5 8 99981581015759272240974143839353881367972777961073357987943600347058023396510672;% +\XINT_tmpa 5 9 99979278881283467947503380727439017235290006415950636109257677645557027950744160;% +\XINT_tmpa 6 1 99999769741755795297487775997495948154386159348543852707438213487494386559762090;% +\XINT_tmpa 6 2 99999539484041779185217876175552674518572114763104546143049036309870762496098218;% +\XINT_tmpa 6 3 99999309226857950442387361668529812394860404492721699528707852590634886516924591;% +\XINT_tmpa 6 4 99999078970204307848196104610199226516866442484686906173860803560254163287393673;% +\XINT_tmpa 6 5 99998848714080850181846788127272455158309917012010320554498356105168896062430977;% +\XINT_tmpa 6 6 99998618458487576222544906332928167145404344730731751204389698696345970645201375;% +\XINT_tmpa 6 7 99998388203424484749498764320339633772810463403640242228131015918494067456365331;% +\XINT_tmpa 6 8 99998157948891574541919478156202215623119146605983303201215215949834619332550929;% +\XINT_tmpa 6 9 99997927694888844379020974874260864289829523807763942234420930258187873904191138;% +\edef\XINT_c_logten + {\XINTinFloat[\XINTdigits+4] + {23025850929940456840179914546843642076011014886287729760333279009675726096773525[-79]}}% +\edef\XINT_c_oneoverlogten + {\XINTinFloat[\XINTdigits+4] + {43429448190325182765112891891660508229439700580366656611445378316586464920887077[-80]}}% +\edef\XINT_c_oneoverlogten_xx + {\XINTinFloat[\XINTdigits+14] + {43429448190325182765112891891660508229439700580366656611445378316586464920887077[-80]}}% +\def\XINTinFloatExp{\romannumeral0\XINTinfloatexp}% +\def\XINT_tmpa#1.{% +\def\XINTinfloatexp##1% +{% + \XINTinfloatpowten + {\xintMul{\XINT_c_oneoverlogten_xx}{\XINTinFloatS[#1]{##1}}}% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+14.% +\def\XINTinFloatPowTen{\romannumeral0\XINTinfloatpowten}% +\def\XINT_tmpa#1.{% +\def\XINTinfloatpowten##1% +{% + \expandafter\XINT_powten_fork + \romannumeral0\xintiround{#1}{##1}[-#1]% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+4.% +\def\XINT_powten_fork#1% +{% + \xint_UDzerominusfork + #1-\XINT_powten_zero + 0#1\XINT_powten_neg + 0-\XINT_powten_pos + \krof #1% +}% +\def\XINT_powten_zero #1[#2]{ 1[0]}% +\def\XINT_powten_pos#1[#2]% +{% + \expandafter\XINT_powten_pos_a\romannumeral0\xintround{6}{#1[#2]}#1[#2]% +}% +\def\XINT_tmpa #1.#2.{% +\def\XINT_powten_pos_a ##1.##2##3##4##5##6##7##8[##9]% +{% + \expandafter\XINT_infloate + \romannumeral0\XINTinfloat[\XINTdigits]{% + \xintMul{\csname XINT_c_1_##2\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7\endcsname}{% + \xintAdd{1[0]}{% + \expandafter\XINT_Exp_series_a_ii + \romannumeral0\XINTinfloat[#2]{% + \xintMul{\XINT_c_logten}% + {\xintAdd{-##1.##2##3##4##5##6##7}{##8[##9]}}% + }% + \xint: + }% + }}}}}}}}}}}}{##1}% +}}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.% + \the\numexpr\XINTdigits-1.% +\def\XINT_powten_neg#1[#2]% +{% + \expandafter\XINT_powten_neg_a\romannumeral0\xintround{6}{#1[#2]}#1[#2]% +}% +\def\XINT_tmpa #1.#2.{% +\def\XINT_powten_neg_a -##1.##2##3##4##5##6##7##8[##9]% +{% + \expandafter\XINT_infloate + \romannumeral0\XINTinfloat[\XINTdigits]{% + \xintMul{\csname XINT_c_1_##2_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7_inv\endcsname}{% + \xintAdd{1[0]}{% + \expandafter\XINT_Exp_series_a_ii + \romannumeral0\XINTinfloat[#2]{% + \xintMul{\XINT_c_logten}% + {\xintAdd{##1.##2##3##4##5##6##7}{##8[##9]}}% + }% + \xint: + }% + }}}}}}}}}}}}{-##1}% +}}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.% + \the\numexpr\XINTdigits-1.% +\def\XINT_tmpa#1.#2.{% +\def\XINT_Exp_series_a_ii##1\xint: +{% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_ + \romannumeral0\xintadd{1}{\xintHalf{##10}[##2-1]}\xint: +}% +\def\XINT_Exp_series_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% }% -\let\XINT_flexpr_func_pow\XINT_expr_func_pow -\catcode`\* 11 -\def\poormanloghack** +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-6\expandafter.% + \the\numexpr\XINTdigits-1.% +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_Exp_series_a_ii##1\xint: +{% + \expandafter\XINT_Exp_series_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_a_iii##1\xint: +{% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_i + \romannumeral0\xintadd{#3}{##1/6[##2]}\xint: +}% +\def\XINT_Exp_series_c_i##1\xint:##2\xint: {% - \def\XINT_tmpa ##1##2##3##4##5##6% + \expandafter\XINT_Exp_series_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-6.% + {5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_Exp_series_a_iii##1\xint: +{% + \expandafter\XINT_Exp_series_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_a_iv##1\xint: +{% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Exp_series_b##1[##2]\xint: +{% + \expandafter\XINT_Exp_series_c_ii + \romannumeral0\xintadd{#3}{##1/24[##2]}\xint: +}% +\def\XINT_Exp_series_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_Exp_series_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-13]{1/6[0]}.% + {5[-1]}.% +\fi +\ifnum\XINTdigits>28 +\def\XINT_tmpa #1 #2 #3 #4 #5 #6 #7 % +{% + \def\XINT_tmpb ##1##2##3##4% {% - \def ##3####1% \XINT_expr_op_<op> + \def\XINT_tmpc####1.####2.####3.####4.% {% - \expanded{\unexpanded{##4{####1}}\expandafter}% - \romannumeral`&&@\expandafter##2\romannumeral`&&@\XINT_expr_getnext + \def##2########1\xint: + {% + \expandafter##1% + \romannumeral0\XINTinfloatS[####2]{########1}\xint:########1\xint: + }% + \def##1########1\xint: + {% + \expandafter\XINT_Exp_series_b + \romannumeral0\XINTinfloatS[####1]{########1}\xint:########1\xint: + }% + \def\XINT_Exp_series_b########1[########2]\xint: + {% + \expandafter##3% + \romannumeral0\xintadd{####3}{########1/#5[########2]}\xint: + }% + \def##3########1\xint:########2\xint: + {% + \expandafter##4% + \romannumeral0\xintadd{####4}{\XINTinFloat[####2]{\xintMul{########1}{########2}}}\xint: + }% }% - \def##2####1% \XINT_expr_check-_<op> - {% + }% + \expandafter\XINT_tmpb + \csname XINT_Exp_series_a_\romannumeral\numexpr#1\expandafter\endcsname + \csname XINT_Exp_series_a_\romannumeral\numexpr#1-1\expandafter\endcsname + \csname XINT_Exp_series_c_\romannumeral\numexpr#1-2\expandafter\endcsname + \csname XINT_Exp_series_c_\romannumeral\numexpr#1-3\endcsname + \expandafter\XINT_tmpc + \the\numexpr\XINTdigits-#2\expandafter.% + \the\numexpr\XINTdigits-#3\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-#3]{1/#6[0]}.% + \XINTinFloat[\XINTdigits-#4]{1/#7[0]}.% + }% +}% +\XINT_tmpa 5 26 19 13 120 24 6 %<-- keep space +\ifnum\XINTdigits>35 \XINT_tmpa 6 33 26 19 720 120 24 \fi +\ifnum\XINTdigits>42 \XINT_tmpa 7 40 33 26 5040 720 120 \fi +\ifnum\XINTdigits>48 \XINT_tmpa 8 46 40 33 40320 5040 720 \fi +\ifnum\XINTdigits>55 \XINT_tmpa 9 53 46 40 362880 40320 5040 \fi +\fi +\def\XINT_tmpa#1.{% +\def\XINTinFloatLog{\romannumeral0\XINTinfloatlog}% +\def\XINTinfloatlog +{% + \expandafter\XINT_log_out + \romannumeral0\expandafter\XINT_logten_a + \romannumeral0\XINTinfloat[#1]%{##1} +}% +\def\XINT_log_out ##1\xint:##2\xint: +{% + \XINTinfloat[#1]% + {\xintAdd{\xintMul{\XINT_c_logten}{##1}}{##2}}% +}% +\def\XINTinFloatLogTen{\romannumeral0\XINTinfloatlogten}% +\def\XINTinfloatlogten +{% + \expandafter\XINT_logten_out + \romannumeral0\expandafter\XINT_logten_a + \romannumeral0\XINTinfloat[#1]%{##1} +}% +\def\XINT_logten_out ##1\xint:##2\xint: +{% + \XINTinfloat[#1]% + {\xintAdd{##1}{\xintMul{\XINT_c_oneoverlogten}{##2}}}% +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits.% +\def\XINTinFloatLogTen_xdgout%#1[#2] +{% + \romannumeral0\expandafter\XINT_logten_xdgout\romannumeral0\XINT_logten_a +}% +\def\XINT_logten_xdgout #1\xint:#2\xint: +{% + \xintadd{#1}{\xintMul{\XINT_c_oneoverlogten_xx}{#2}}% +}% +\def\XINT_logten_a#1[#2]% +{% + \expandafter\XINT_logten_b + \romannumeral0\XINTinfloat[9]{#1[#2]}#1[#2]% +}% +\def\XINT_logten_b#1[#2]% +{% + \expandafter\XINT_logten_c + \romannumeral0\xintround{6}% + {\xintiiAdd{\xintDSx{-9}{\the\numexpr#2+8\relax}}% + {\the\numexpr\PML@#1.\relax}% + [-9]}% + \xint: +}% +\def\XINT_logten_c #1#2% +{% + \xint_gob_til_xint:#2\XINT_logten_IV\xint: + \XINT_logten_d #1#2% +}% +\def\XINT_logten_IV\xint:\XINT_logten_d0{\XINT_logten_f_III}% +\def\XINT_logten_d #1.#2\xint: +{% + \ifcase + \ifnum#1=\xint_c_ + \ifnum #2>100000 \xint_c_i\else + \ifnum #2>\xint_c_ \xint_c_ii\else \xint_c_iii\fi\fi + \else + \ifnum#2>\xint_c_ \xint_c_i\else \xint_c_\fi + \fi + \expandafter\XINT_logten_f_Isp + \or\expandafter\XINT_logten_f_I + \or\expandafter\XINT_logten_f_II + \else\expandafter\XINT_logten_f_III + \fi + #1.#2\xint: +}% +\def\XINT_logten_f_I#1% +{% \xint_UDsignfork - ####1{\expandafter##2\romannumeral`&&@##1}% - -{##5####1}% - \krof + #1\XINT_logten_f_I_neg + -\XINT_logten_f_I_pos + \krof #1% +}% +\def\XINT_logten_f_II#1% +{% + \xint_UDsignfork + #1\XINT_logten_f_II_neg + -\XINT_logten_f_II_pos + \krof #1% +}% +\def\XINT_tmpa#1.{% +\def\XINT_logten_f_Isp##1.000000\xint:##2[##3]% +{% + {##1[0]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloatS[#1]{\xintAdd{##2[##3-##1]}{-1[0]}}% + \xint: + }\xint: +}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits-2.% +\def\XINT_tmpa#1.{% +\def\XINT_logten_f_III##1\xint:##2[##3]% +{% + {0[0]}\xint: + {\expandafter\XINT_LogTen_serIII_a_ii + \romannumeral0\XINTinfloatS[#1]{\xintAdd{##2[##3]}{-1[0]}}% + \xint: + }\xint: +}}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+4.% +\def\XINT_tmpa#1.#2.{% +\def\XINT_logten_f_I_pos##1.##2##3##4##5##6##7\xint:##8[##9]% +{% + {\the\numexpr##1##2##3##4##5##6##7[-6]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##2_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6_inv\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7_inv\endcsname} + {##8[##9-##1]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +\def\XINT_logten_f_I_neg##1.##2##3##4##5##6##7\xint:##8[##9]% +{% + {\the\numexpr##1##2##3##4##5##6##7[-6]}\xint: + {\expandafter\XINT_LogTen_serI_a_i + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##2\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##3\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##4\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##5\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##6\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##7\endcsname} + {##8[##9-##1]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+5\expandafter.\the\numexpr\XINTdigits-1.% +\def\XINT_tmpa#1.#2.{% +\def\XINT_logten_f_II_pos0.##1##2##3##4##5##6\xint:##7[##8]% +{% + {\the\numexpr##1##2##3##4##5##6[-6]}\xint: + {\expandafter\XINT_LogTen_serII_a_ii + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##1_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##2_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##3_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##4_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##5_inv_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##6_inv_x\endcsname} + {##7[##8]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +\def\XINT_logten_f_II_neg-0.##1##2##3##4##5##6\xint:##7[##8]% +{% + {\the\numexpr-##1##2##3##4##5##6[-6]}\xint: + {\expandafter\XINT_LogTen_serII_a_ii + \romannumeral0\XINTinfloat[#2]% + {\xintAdd{-1[0]}% + {\xintMul{\csname XINT_c_1_##1_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_2_##2_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_3_##3_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_4_##4_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_5_##5_x\endcsname}{% + \XINTinFloat[#1]{% + \xintMul{\csname XINT_c_6_##6_x\endcsname} + {##7[##8]}% + }}}}}}}}}}% + }% + }\xint: + }\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+10\expandafter.\the\numexpr\XINTdigits+4.% +\def\XINT_LogTen_serI_a_i#1\xint:{#1}% +\ifnum\XINTdigits>9 +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serI_a_i##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_ii + \romannumeral0\XINTinfloatS[#2]{##1}\xint: +}% +\def\XINT_LogTen_serI_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{##10}[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-7\expandafter.% + \the\numexpr\XINTdigits-1.% +\fi +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-7.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serI_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-13]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>27 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-25\expandafter.% + \the\numexpr\XINTdigits-19\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-13]{1/3[0]}.% }% - \def##5####1####2% \XINT_expr_checkp_<op> - {% - \ifnum ####1>\XINT_expr_precedence_** - \expandafter##5% - \romannumeral`&&@\csname XINT_##6_op_####2\expandafter\endcsname - \else - \expandafter ####1\expandafter ####2% - \fi +\fi +\ifnum\XINTdigits>33 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-31\expandafter.% + \the\numexpr\XINTdigits-25.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>39 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-37\expandafter.% + \the\numexpr\XINTdigits-31\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-31]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>45 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serI_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-43\expandafter.% + \the\numexpr\XINTdigits-37\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-37]{1/7[0]}.% + \XINTinFloat[\XINTdigits-31]{-1/6[0]}.% }% - }% - \expandafter\XINT_tmpa - \csname XINT_expr_op_-ix\expandafter\endcsname - \csname XINT_expr_check-_**\endcsname - \XINT_expr_op_** - \XINT_expr_exec_** - \XINT_expr_checkp_** {expr}% - \expandafter\XINT_tmpa - \csname XINT_flexpr_op_-ix\expandafter\endcsname - \csname XINT_flexpr_check-_**\endcsname - \XINT_flexpr_op_** - \XINT_flexpr_exec_** - \XINT_flexpr_checkp_** {flexpr}% - \def\XINT_expr_exec_** ##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower##1##4}}% +\fi +\ifnum\XINTdigits>51 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serI_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-49\expandafter.% + \the\numexpr\XINTdigits-43\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-37]{1/7[0]}.% }% - \let\XINT_flexpr_exec_**\XINT_expr_exec_** +\fi +\ifnum\XINTdigits>57 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serI_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serI_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: }% -\def\poormanloghack^ +\def\XINT_LogTen_serI_a_x##1\xint: {% - \def\XINT_tmpa ##1##2##3##4##5##6% - {% - \def ##3####1% \XINT_expr_op_<op> - {% - \expanded{\unexpanded{##4{####1}}\expandafter}% - \romannumeral`&&@\expandafter##2\romannumeral`&&@\XINT_expr_getnext + \expandafter\XINT_LogTen_serI_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serI_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serI_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serI_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serI_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-55\expandafter.% + \the\numexpr\XINTdigits-49\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-49]{1/9[0]}.% + {-125[-3]}.% +\fi +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b#1[#2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{#10}[#2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-2\expandafter.% + \the\numexpr\XINTdigits+4.% +\ifnum\XINTdigits>10 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-8\expandafter.% + \the\numexpr\XINTdigits-2.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>16 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serII_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-14\expandafter.% + \the\numexpr\XINTdigits-8\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-8]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>22 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-20\expandafter.% + \the\numexpr\XINTdigits-14\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-8]{1/3[0]}.% }% - \def##2####1% \XINT_expr_check-_<op> - {% - \xint_UDsignfork - ####1{\expandafter##2\romannumeral`&&@##1}% - -{##5####1}% - \krof +\fi +\ifnum\XINTdigits>28 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-26\expandafter.% + \the\numexpr\XINTdigits-20.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>34 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-32\expandafter.% + \the\numexpr\XINTdigits-26\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-26]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>40 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serII_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-38\expandafter.% + \the\numexpr\XINTdigits-32\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-32]{1/7[0]}.% + \XINTinFloat[\XINTdigits-26]{-1/6[0]}.% }% - \def##5####1####2% \XINT_expr_checkp_<op> - {% - \ifnum ####1>\XINT_expr_precedence_^ - \expandafter##5% - \romannumeral`&&@\csname XINT_##6_op_####2\expandafter\endcsname - \else - \expandafter ####1\expandafter ####2% - \fi +\fi +\ifnum\XINTdigits>46 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-44\expandafter.% + \the\numexpr\XINTdigits-38\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-32]{1/7[0]}.% }% - }% - \expandafter\XINT_tmpa - \csname XINT_expr_op_-ix\expandafter\endcsname - \csname XINT_expr_check-_^\endcsname - \XINT_expr_op_^ - \XINT_expr_exec_^ - \XINT_expr_checkp_^ {expr}% - \expandafter\XINT_tmpa - \csname XINT_flexpr_op_-ix\expandafter\endcsname - \csname XINT_flexpr_check-_^\endcsname - \XINT_flexpr_op_^ - \XINT_flexpr_exec_^ - \XINT_flexpr_checkp_^ {flexpr}% - \def\XINT_expr_exec_^ ##1##2##3##4% \XINT_expr_exec_<op> - {% - \expandafter##2\expandafter##3\expandafter{% - \romannumeral`&&@\XINT:NEhook:f:one:from:two - {\romannumeral`&&@\PoorManPower##1##4}}% +\fi +\ifnum\XINTdigits>52 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serII_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-50\expandafter.% + \the\numexpr\XINTdigits-44\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-44]{1/9[0]}.% + {-125[-3]}.% +\fi +\ifnum\XINTdigits>58 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serII_a_xi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_a_xi##1\xint: +{% + \expandafter\XINT_LogTen_serII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serII_c_ix + \romannumeral0\xintadd{#3}{##1/11[##2]}\xint: +}% +\def\XINT_LogTen_serII_c_ix##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serII_c_viii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-56\expandafter.% + \the\numexpr\XINTdigits-50\expandafter.\expanded{% + {-1[-1]}.% + \XINTinFloat[\XINTdigits-44]{1/9[0]}.% }% - \let\XINT_flexpr_exec_^\XINT_expr_exec_^ +\fi +\def\XINT_tmpa#1.#2.{% +\def\XINT_LogTen_serIII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: }% -\def\poormanloghack#1{\csname poormanloghack#1\endcsname}% +\def\XINT_LogTen_serIII_b#1[#2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ + \romannumeral0\xintadd{1}{\xintiiOpp\xintHalf{#10}[#2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_##1\xint:##2\xint: +{% + \XINTinFloat[#2]{\xintMul{##1}{##2}}% +}% +}% +\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-1\expandafter.% + \the\numexpr\XINTdigits+4.% +\ifnum\XINTdigits>9 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_ii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_iii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_i + \romannumeral0\xintadd{#3}{##1/3[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_i##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-7\expandafter.% + \the\numexpr\XINTdigits-1.% + {-5[-1]}.% + {1[0]}.% +\fi +\ifnum\XINTdigits>15 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_iii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_iv + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ii + \romannumeral0\xintadd{#3}{\xintiiMul{-25}{##1}[##2-2]}\xint: +}% +\def\XINT_LogTen_serIII_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_i + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-13\expandafter.% + \the\numexpr\XINTdigits-7\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-7]{1/3[0]}.% + {-5[-1]}.% +\fi +\ifnum\XINTdigits>21 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_iv##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_v + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iii + \romannumeral0\xintadd{#3}{\xintDouble{##1}[##2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_iii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-19\expandafter.% + \the\numexpr\XINTdigits-13\expandafter.\expanded{% + {-25[-2]}.% + \XINTinFloat[\XINTdigits-7]{1/3[0]}.% + }% +\fi +\ifnum\XINTdigits>27 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_v##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_vi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iv + \romannumeral0\xintadd{#3}{\xintiiOpp##1/6[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_iv##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-25\expandafter.% + \the\numexpr\XINTdigits-19.% + {2[-1]}.% + {-25[-2]}.% +\fi +\ifnum\XINTdigits>33 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_vi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_vii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_v + \romannumeral0\xintadd{#3}{##1/7[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_v##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_iv + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-31\expandafter.% + \the\numexpr\XINTdigits-25\expandafter.% + \romannumeral0\XINTinfloatS[\XINTdigits-25]{-1/6[0]}.% + {2[-1]}.% +\fi +\ifnum\XINTdigits>39 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_vii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_viii + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vi + \romannumeral0\xintadd{#3}{\xintiiMul{-125}{##1}[##2-3]}\xint: +}% +\def\XINT_LogTen_serIII_c_vi##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_v + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-37\expandafter.% + \the\numexpr\XINTdigits-31\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-31]{1/7[0]}.% + \XINTinFloat[\XINTdigits-25]{-1/6[0]}.% + }% +\fi +\ifnum\XINTdigits>45 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_viii##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_ix + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vii + \romannumeral0\xintadd{#3}{##1/9[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_vii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vi + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-43\expandafter.% + \the\numexpr\XINTdigits-37\expandafter.\expanded{% + {-125[-3]}.% + \XINTinFloat[\XINTdigits-31]{1/7[0]}.% + }% +\fi +\ifnum\XINTdigits>51 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_ix##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_x + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_viii + \romannumeral0\xintadd{#3}{\xintiiOpp##1[##2-1]}\xint: +}% +\def\XINT_LogTen_serIII_c_viii##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_vii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-49\expandafter.% + \the\numexpr\XINTdigits-43\expandafter.% + \romannumeral0\XINTinfloat[\XINTdigits-43]{1/9[0]}.% + {-125[-3]}.% +\fi +\ifnum\XINTdigits>57 +\def\XINT_tmpa#1.#2.#3.#4.{% +\def\XINT_LogTen_serIII_a_x##1\xint: +{% + \expandafter\XINT_LogTen_serIII_a_xi + \romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_a_xi##1\xint: +{% + \expandafter\XINT_LogTen_serIII_b + \romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_LogTen_serIII_b##1[##2]\xint: +{% + \expandafter\XINT_LogTen_serIII_c_ix + \romannumeral0\xintadd{#3}{##1/11[##2]}\xint: +}% +\def\XINT_LogTen_serIII_c_ix##1\xint:##2\xint: +{% + \expandafter\XINT_LogTen_serIII_c_viii + \romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{##1}{##2}}}\xint: +}% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits-55\expandafter.% + \the\numexpr\XINTdigits-49\expandafter.\expanded{% + {-1[-1]}.% + \XINTinFloat[\XINTdigits-43]{1/9[0]}.% + }% +\fi +\XINTendxintloginput% \endinput %% %% End of file `xintlog.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty index 0e5bddb2246..60b32512bf9 100644 --- a/Master/texmf-dist/tex/generic/xint/xintseries.sty +++ b/Master/texmf-dist/tex/generic/xint/xintseries.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xintseries: Expandable partial sums with xint package %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintseries}% - [2021/03/29 v1.4d Expandable partial sums with xint package (JFB)]% + [2021/05/05 v1.4e Expandable partial sums with xint package (JFB)]% \def\xintSeries {\romannumeral0\xintseries }% \def\xintseries #1#2% {% @@ -335,7 +335,7 @@ \else \xint_afterfi {\expandafter\XINT_flpowseries_loop_pre\expandafter - {\romannumeral0\XINTinfloatpow [#3]{#5}{#1}}% + {\romannumeral0\XINTinfloatpow_wopt[#3]{#5}{#1}}% {#1}{#5}{#2}{#4}{#3}% }% \fi @@ -345,7 +345,7 @@ \ifnum #4>#2 \else\XINT_flpowseries_dont_i \fi \expandafter\XINT_flpowseries_loop_i\expandafter {\the\numexpr #2+\xint_c_i\expandafter}\expandafter - {\romannumeral0\XINTinfloatmul [#6]{#5{#2}}{#1}}% + {\romannumeral0\XINTinfloatmul_wopt[#6]{#5{#2}}{#1}}% {#1}{#3}{#4}{#5}{#6}% }% \def\XINT_flpowseries_dont_i \fi\expandafter\XINT_flpowseries_loop_i @@ -355,22 +355,22 @@ {% \ifnum #5>#1 \else \XINT_flpowseries_exit_i \fi \expandafter\XINT_flpowseries_loop_ii\expandafter - {\romannumeral0\XINTinfloatmul [#7]{#3}{#4}}% + {\romannumeral0\XINTinfloatmul_wopt[#7]{#3}{#4}}% {#1}{#4}{#2}{#5}{#6}{#7}% }% \def\XINT_flpowseries_loop_ii #1#2#3#4#5#6#7% {% \expandafter\XINT_flpowseries_loop_i\expandafter {\the\numexpr #2+\xint_c_i\expandafter}\expandafter - {\romannumeral0\XINTinfloatadd [#7]{#4}% - {\XINTinfloatmul [#7]{#6{#2}}{#1}}}% + {\romannumeral0\XINTinfloatadd_wopt[#7]{#4}% + {\XINTinfloatmul_wopt[#7]{#6{#2}}{#1}}}% {#1}{#3}{#5}{#6}{#7}% }% \def\XINT_flpowseries_exit_i\fi\expandafter\XINT_flpowseries_loop_ii {\fi \expandafter\XINT_flpowseries_exit_ii }% \def\XINT_flpowseries_exit_ii #1#2#3#4#5#6#7% {% - \xintfloatadd [#7]{#4}{\XINTinfloatmul [#7]{#6{#2}}{#1}}% + \xintfloatadd[#7]{#4}{\XINTinfloatmul_wopt[#7]{#6{#2}}{#1}}% }% \def\xintFloatPowerSeriesX {\romannumeral0\xintfloatpowerseriesx }% \def\xintfloatpowerseriesx #1{\XINT_flpowseriesx_chkopt #1\xint:}% @@ -407,10 +407,10 @@ \def\XINT_flpowseriesx_pre #1#2#3#4#5% {% \expandafter\XINT_flpowseries_loop_pre\expandafter - {\romannumeral0\XINTinfloatpow [#5]{#1}{#2}}% + {\romannumeral0\XINTinfloatpow_wopt[#5]{#1}{#2}}% {#2}{#1}{#3}{#4}{#5}% }% -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xintseries.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xinttools.sty b/Master/texmf-dist/tex/generic/xint/xinttools.sty index e35ba21b9c1..4d92f76819c 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttools.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttools.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xinttools: Expandable and non-expandable utilities %% --------------------------------------------------------------- @@ -70,7 +70,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xinttools}% - [2021/03/29 v1.4d Expandable and non-expandable utilities (JFB)]% + [2021/05/05 v1.4e Expandable and non-expandable utilities (JFB)]% \newtoks\XINT_toks \xint_firstofone{\let\XINT_sptoken= } %<- space here! \def\xintgodef {\global\xintodef }% @@ -1653,7 +1653,7 @@ \let\xintCSVFirstItem\xintFirstItem:f:csv \let\xintCSVLastItem \xintLastItem:f:csv \let\XINT_tmpa\relax \let\XINT_tmpb\relax \let\XINT_tmpc\relax -\XINT_restorecatcodes_endinput% +\XINTrestorecatcodesendinput% \endinput %% %% End of file `xinttools.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xinttrig.sty b/Master/texmf-dist/tex/generic/xint/xinttrig.sty index 563d14760da..c10106cb894 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttrig.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttrig.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4d 2021/03/29 +%% The xint bundle 1.4e 2021/05/05 %% Copyright (C) 2013-2021 by Jean-Francois Burnol %% xinttrig: Trigonometry for the xintexpr package %% --------------------------------------------------------------- @@ -61,137 +61,287 @@ \fi \fi \z% -\catcode`_ 11 \XINT_setcatcodes \catcode`? 12 +\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\catcode`? 12 \ifcsname xintlibver@trig\endcsname \expandafter\xint_firstoftwo \else \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/03/29 v1.4d}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/05/05 v1.4e}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2021/03/29 v1.4d Trigonometrical functions for xintexpr (JFB)]% +[2021/05/05 v1.4e Trigonometrical functions for xintexpr (JFB)]% }% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}% -\def\xintreloadxinttrig - {\edef\XINT_restorecatcodes_now{\XINT_restorecatcodes}% - \XINT_setcatcodes\catcode`? 12 - \input xinttrig.sty - \XINT_restorecatcodes_now}% -\xintdeffloatvar twoPi := 0 + - 6.28318530717958647692528676655900576839433879875021164194989;% -\xintdeffloatvar threePiover2 := 0 + - 4.71238898038468985769396507491925432629575409906265873146242;% -\xintdeffloatvar Pi := 0 + - 3.14159265358979323846264338327950288419716939937510582097494;% -\xintdeffloatvar Piover2 := 0 + - 1.57079632679489661923132169163975144209858469968755291048747;% -\xintdeffloatvar oneDegree := 0 + - 0.0174532925199432957692369076848861271344287188854172545609719;% Pi/180 -\xintdeffloatvar oneRadian := 0 + - 57.2957795130823208767981548141051703324054724665643215491602;% 180/Pi -\xintdeffloatvar invfact\xintListWithSep{, invfact}{\xintSeq{2}{44}}% - := \xintfloatexpr [\XINTdigits] % force float rounding after exact evaluations - \xintexpr rseq(1/2; @/i, i=3..44)\relax % no need to hide this inner ; - \relax;% -\xintdeffloatfunc sin_aux(X) := 1 - X(invfact3 - X(invfact5 -\ifnum\XINTdigits>4 - - X(invfact7 -\ifnum\XINTdigits>6 - - X(invfact9 +\def\xintreloadxinttrig{\input xinttrig.sty }% +\xintdefvar @twoPi := + float( +6.2831853071795864769252867665590057683943387987502116419498891846156328125724180 + ,\xinttheDigits+4);% +\xintdefvar @threePiover2 := + float( +4.7123889803846898576939650749192543262957540990626587314624168884617246094293135 + ,\xinttheDigits+4);% +\xintdefvar @Pi := + float( +3.1415926535897932384626433832795028841971693993751058209749445923078164062862090 + ,\xinttheDigits+4);% +\xintdefvar @Piover2 := + float( +1.5707963267948966192313216916397514420985846996875529104874722961539082031431045 + ,\xinttheDigits+4);% +\xintdefvar @oneDegree := + float( +0.017453292519943295769236907684886127134428718885417254560971914401710091146034494 + ,\xinttheDigits+4);% +\xintdefvar @oneRadian := + float( +57.295779513082320876798154814105170332405472466564321549160243861202847148321553 + ,\xinttheDigits+12);% +\catcode`~ 12 +\def\XINT_tmpa#1#2#3.#4.% +{% + \let #1#2% + \def #2##1##2##3##4{##2##3{{~expanded{~unexpanded{#4[#3]}~expandafter}~expanded{##1##4}}}}% +}% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_+_\expandafter\endcsname + \csname XINT_flexpr_exec_+\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatAdd_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_-_\expandafter\endcsname + \csname XINT_flexpr_exec_-\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSub_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_*_\expandafter\endcsname + \csname XINT_flexpr_exec_*\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatMul_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_exec_/_\expandafter\endcsname + \csname XINT_flexpr_exec_/\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatDiv_wopt.% +\def\XINT_tmpa#1#2#3.#4.% +{% + \let #1#2% + \def #2##1##2##3{##1##2{{~expanded{~unexpanded{#4[#3]}~expandafter}##3}}}% +}% +\expandafter\XINT_tmpa + \csname XINT_flexpr_sqrfunc\expandafter\endcsname + \csname XINT_flexpr_func_sqr\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSqr_wopt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_sqrtfunc\expandafter\endcsname + \csname XINT_flexpr_func_sqrt\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatSqrt.% +\expandafter\XINT_tmpa + \csname XINT_flexpr_invfunc\expandafter\endcsname + \csname XINT_flexpr_func_inv\expandafter\endcsname + \the\numexpr\XINTdigits+4.~XINTinFloatInv_wopt.% +\catcode`~ 3 \ifnum\XINTdigits>8 - - X(invfact11 -\ifnum\XINTdigits>10 - - X(invfact13 -\ifnum\XINTdigits>13 - - X(invfact15 -\ifnum\XINTdigits>15 - - X(invfact17 -\ifnum\XINTdigits>18 - - X(invfact19 -\ifnum\XINTdigits>21 - - X(invfact21 -\ifnum\XINTdigits>24 - - X(invfact23 -\ifnum\XINTdigits>27 - - X(invfact25 -\ifnum\XINTdigits>30 - - X(invfact27 -\ifnum\XINTdigits>33 - - X(invfact29 -\ifnum\XINTdigits>36 - - X(invfact31 -\ifnum\XINTdigits>39 - - X(invfact33 -\ifnum\XINTdigits>43 - - X(invfact35 -\ifnum\XINTdigits>46 - - X(invfact37 -\ifnum\XINTdigits>49 - - X(invfact39 -\ifnum\XINTdigits>53 - - X(invfact41 -\ifnum\XINTdigits>59 - - X(invfact43 - )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));% -\xintdeffloatfunc cos_aux(X) := 1 - X(invfact2 - X(invfact4 -\ifnum\XINTdigits>3 - - X(invfact6 -\ifnum\XINTdigits>5 - - X(invfact8 -\ifnum\XINTdigits>7 - - X(invfact10 -\ifnum\XINTdigits>9 - - X(invfact12 -\ifnum\XINTdigits>12 - - X(invfact14 -\ifnum\XINTdigits>14 - - X(invfact16 -\ifnum\XINTdigits>17 - - X(invfact18 -\ifnum\XINTdigits>20 - - X(invfact20 -\ifnum\XINTdigits>23 - - X(invfact22 -\ifnum\XINTdigits>25 - - X(invfact24 -\ifnum\XINTdigits>28 - - X(invfact26 -\ifnum\XINTdigits>32 - - X(invfact28 -\ifnum\XINTdigits>35 - - X(invfact30 -\ifnum\XINTdigits>38 - - X(invfact32 -\ifnum\XINTdigits>41 - - X(invfact34 -\ifnum\XINTdigits>44 - - X(invfact36 -\ifnum\XINTdigits>48 - - X(invfact38 -\ifnum\XINTdigits>51 - - X(invfact40 -\ifnum\XINTdigits>55 - - X(invfact42 -\ifnum\XINTdigits>58 - - X(invfact44 - )\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi)\fi));% -\expandafter\let\csname XINT_expr_func_sin_aux\expandafter\endcsname - \csname XINT_flexpr_func_sin_aux\endcsname -\expandafter\let\csname XINT_expr_func_cos_aux\expandafter\endcsname - \csname XINT_flexpr_func_cos_aux\endcsname -\xintdeffloatfunc sin_(x) := x * sin_aux(sqr(x));% -\xintdeffloatfunc cos_(x) := cos_aux(sqr(x));% -\def\XINT_mod_ccclx_i #1.% input <k>.<N>. k is a non-negative exponent +\edef\XINT_tmpG % 1/3! + {1\xintReplicate{\XINTdigits+2}{6}7[\the\numexpr-\XINTdigits-4]}% +\edef\XINT_tmpH % 1/5! + {8\xintReplicate{\XINTdigits+1}{3}[\the\numexpr-\XINTdigits-4]}% +\edef\XINT_tmpd % 1/5! + {8\xintReplicate{\XINTdigits+9}{3}[\the\numexpr-\XINTdigits-12]}% +\def\XINT_tmpe#1.#2.#3.#4.#5#6#7% +{% +\def#5##1\xint: +{% + \expandafter#6\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def#6##1\xint: +{% + \expandafter#7\romannumeral0\xintsub{#4}{\XINTinFloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def#7##1\xint:##2\xint: +{% + \xintSub{1/1[0]}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}% +}% +}% +\expandafter\XINT_tmpe + \the\numexpr\XINTdigits+4\expandafter.% + \the\numexpr\XINTdigits+2\expandafter.\expanded{% + \XINT_tmpH.% 1/5! + \XINT_tmpG.% 1/3! + \expandafter}% + \csname XINT_SinAux_series_a_iii\expandafter\endcsname + \csname XINT_SinAux_series_b\expandafter\endcsname + \csname XINT_SinAux_series_c_i\endcsname +\def\XINT_tmpa #1 #2 #3 #4 #5 #6 #7 #8 % +{% + \def\XINT_tmpb ##1##2##3##4##5% + {% + \def\XINT_tmpc####1.####2.####3.####4.####5.% + {% + \def##1########1\xint: + {% + \expandafter##2% + \romannumeral0\XINTinfloatS[####1]{########1}\xint:########1\xint: + }% + \def##2########1\xint: + {% + \expandafter##3% + \romannumeral0\XINTinfloatS[####2]{########1}\xint:########1\xint: + }% + \def##3########1\xint: + {% + \expandafter##4% + \romannumeral0\xintsub{####4}{\XINTinFloat[####2]{\xintMul{####3}{########1}}}\xint: + }% + \def##4########1\xint:########2\xint: + {% + \expandafter##5% + \romannumeral0\xintsub{####5}{\XINTinFloat[####1]{\xintMul{########1}{########2}}}\xint: + }% + }% + }% + \expandafter\XINT_tmpb + \csname XINT_#8Aux_series_a_\romannumeral\numexpr#1-1\expandafter\endcsname + \csname XINT_#8Aux_series_a_\romannumeral\numexpr#1\expandafter\endcsname + \csname XINT_#8Aux_series_b\expandafter\endcsname + \csname XINT_#8Aux_series_c_\romannumeral\numexpr#1-2\expandafter\endcsname + \csname XINT_#8Aux_series_c_\romannumeral\numexpr#1-3\endcsname + \edef\XINT_tmpd + {\XINTinFloat[\XINTdigits-#2+8]{\xintDiv{\XINT_tmpd}{\the\numexpr#5*(#5-1)\relax}}}% + \let\XINT_tmpF\XINT_tmpG + \let\XINT_tmpG\XINT_tmpH + \edef\XINT_tmpH{\XINTinFloat[\XINTdigits-#2]{\XINT_tmpd}}% + \expandafter\XINT_tmpc + \the\numexpr\XINTdigits-#3\expandafter.% + \the\numexpr\XINTdigits-#2\expandafter.\expanded{% + \XINT_tmpH.% + \XINT_tmpG.% + \XINT_tmpF.% + }% +}% +\XINT_tmpa 4 -1 -2 -4 7 5 3 Sin % +\ifnum\XINTdigits>3 \XINT_tmpa 5 1 -1 -2 9 7 5 Sin \fi +\ifnum\XINTdigits>5 \XINT_tmpa 6 3 1 -1 11 9 7 Sin \fi +\ifnum\XINTdigits>8 \XINT_tmpa 7 6 3 1 13 11 9 Sin \fi +\ifnum\XINTdigits>11 \XINT_tmpa 8 9 6 3 15 13 11 Sin \fi +\ifnum\XINTdigits>14 \XINT_tmpa 9 12 9 6 17 15 13 Sin \fi +\ifnum\XINTdigits>16 \XINT_tmpa 10 14 12 9 19 17 15 Sin \fi +\ifnum\XINTdigits>19 \XINT_tmpa 11 17 14 12 21 19 17 Sin \fi +\ifnum\XINTdigits>22 \XINT_tmpa 12 20 17 14 23 21 19 Sin \fi +\ifnum\XINTdigits>25 \XINT_tmpa 13 23 20 17 25 23 21 Sin \fi +\ifnum\XINTdigits>28 \XINT_tmpa 14 26 23 20 27 25 23 Sin \fi +\ifnum\XINTdigits>31 \XINT_tmpa 15 29 26 23 29 27 25 Sin \fi +\ifnum\XINTdigits>34 \XINT_tmpa 16 32 29 26 31 29 27 Sin \fi +\ifnum\XINTdigits>37 \XINT_tmpa 17 35 32 29 33 31 29 Sin \fi +\ifnum\XINTdigits>40 \XINT_tmpa 18 38 35 32 35 33 31 Sin \fi +\ifnum\XINTdigits>44 \XINT_tmpa 19 42 38 35 37 35 33 Sin \fi +\ifnum\XINTdigits>47 \XINT_tmpa 20 45 42 38 39 37 35 Sin \fi +\ifnum\XINTdigits>51 \XINT_tmpa 21 49 45 42 41 39 37 Sin \fi +\ifnum\XINTdigits>55 \XINT_tmpa 22 53 49 45 43 41 39 Sin \fi +\ifnum\XINTdigits>58 \XINT_tmpa 23 56 53 49 45 43 41 Sin \fi +\edef\XINT_tmpd % 1/4! + {41\xintReplicate{\XINTdigits+8}{6}7[\the\numexpr-\XINTdigits-12]}% +\edef\XINT_tmpH % 1/4! + {41\xintReplicate{\XINTdigits}{6}7[\the\numexpr-\XINTdigits-4]}% +\def\XINT_tmpG{5[-1]}% 1/2! +\expandafter\XINT_tmpe + \the\numexpr\XINTdigits+4\expandafter.% + \the\numexpr\XINTdigits+3\expandafter.\expanded{% + \XINT_tmpH.% + \XINT_tmpG.% + \expandafter}% + \csname XINT_CosAux_series_a_iii\expandafter\endcsname + \csname XINT_CosAux_series_b\expandafter\endcsname + \csname XINT_CosAux_series_c_i\endcsname +\XINT_tmpa 4 -2 -3 -4 6 4 2 Cos % +\ifnum\XINTdigits>2 \XINT_tmpa 5 0 -2 -3 8 6 4 Cos \fi +\ifnum\XINTdigits>4 \XINT_tmpa 6 2 0 -2 10 8 6 Cos \fi +\ifnum\XINTdigits>7 \XINT_tmpa 7 5 2 0 12 10 8 Cos \fi +\ifnum\XINTdigits>9 \XINT_tmpa 8 7 5 2 14 12 10 Cos \fi +\ifnum\XINTdigits>12 \XINT_tmpa 9 10 7 5 16 14 12 Cos \fi +\ifnum\XINTdigits>15 \XINT_tmpa 10 13 10 7 18 16 14 Cos \fi +\ifnum\XINTdigits>18 \XINT_tmpa 11 16 13 10 20 18 16 Cos \fi +\ifnum\XINTdigits>20 \XINT_tmpa 12 18 16 13 22 20 18 Cos \fi +\ifnum\XINTdigits>24 \XINT_tmpa 13 22 18 16 24 22 20 Cos \fi +\ifnum\XINTdigits>27 \XINT_tmpa 14 25 22 18 26 24 22 Cos \fi +\ifnum\XINTdigits>30 \XINT_tmpa 15 28 25 22 28 26 24 Cos \fi +\ifnum\XINTdigits>33 \XINT_tmpa 16 31 28 25 30 28 26 Cos \fi +\ifnum\XINTdigits>36 \XINT_tmpa 17 34 31 28 32 30 28 Cos \fi +\ifnum\XINTdigits>39 \XINT_tmpa 18 37 34 31 34 32 30 Cos \fi +\ifnum\XINTdigits>42 \XINT_tmpa 19 40 37 34 36 34 32 Cos \fi +\ifnum\XINTdigits>45 \XINT_tmpa 20 43 40 37 38 36 34 Cos \fi +\ifnum\XINTdigits>49 \XINT_tmpa 21 47 43 40 40 38 36 Cos \fi +\ifnum\XINTdigits>53 \XINT_tmpa 22 51 47 43 42 40 38 Cos \fi +\ifnum\XINTdigits>57 \XINT_tmpa 23 55 51 47 44 42 40 Cos \fi +\ifnum\XINTdigits>60 \XINT_tmpa 24 58 55 51 46 44 42 Cos \fi +\let\XINT_tmpH\xint_undefined\let\XINT_tmpG\xint_undefined\let\XINT_tmpF\xint_undefined +\let\XINT_tmpd\xint_undefined\let\XINT_tmpe\xint_undefined +\def\XINT_SinAux_series#1% +{% + \expandafter\XINT_SinAux_series_a_iii + \romannumeral0\XINTinfloatS[\XINTdigits+4]{#1}\xint: +}% +\def\XINT_CosAux_series#1% +{% + \expandafter\XINT_CosAux_series_a_iii + \romannumeral0\XINTinfloatS[\XINTdigits+4]{#1}\xint: +}% +\fi % end of \XINTdigits>8 +\ifnum\XINTdigits<9 +\def\XINT_SinAux_series#1% +{% + \the\numexpr\expandafter\XINT_SinAux_b\romannumeral0\xintiround9{#1}.[-9]% +}% +\def\XINT_SinAux_b#1.% +{% + ((((((((((((%(\xint_c_x^ix/-210) + -4761905*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -156)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -110)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -72)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -42)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -20)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -6)*#1/\xint_c_x^ix+\xint_c_x^ix +}% +\def\XINT_CosAux_series#1% +{% + \the\numexpr\expandafter\XINT_CosAux_b\romannumeral0\xintiround9{#1}.[-9]% +}% +\def\XINT_CosAux_b#1.% +{% + ((((((((((((((%(\xint_c_x^ix/-240) + -4166667*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -182)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -132)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -90)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -56)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -30)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -12)*#1/\xint_c_x^ix+\xint_c_x^ix)/% + -2)*#1/\xint_c_x^ix+\xint_c_x^ix +}% +\fi +\def\XINT_flexpr_func_@sin_aux#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_SinAux_series#3}}% +}% +\def\XINT_flexpr_func_@cos_aux#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_CosAux_series#3}}% +}% +\xintdeffloatfunc @sin_series(x) := x * @sin_aux(sqr(x));% +\xintdeffloatfunc @cos_series(x) := @cos_aux(sqr(x));% +\def\XINT_mod_ccclx_i #1.% {% \expandafter\XINT_mod_ccclx_e\the\numexpr \expandafter\XINT_mod_ccclx_j\the\numexpr1\ifcase#1 \or0\or00\else000\fi.% }% -\def\XINT_mod_ccclx_j 1#1.#2.% #2=N is a non-negative mantissa +\def\XINT_mod_ccclx_j 1#1.#2.% {% (\XINT_mod_ccclx_ja {++}#2#1\XINT_mod_ccclx_jb 0000000\relax -}% 1 2345678 +}% \def\XINT_mod_ccclx_ja #1#2#3#4#5#6#7#8#9% {% #9+#8+#7+#6+#5+#4+#3+#2\xint_firstoftwo{+\XINT_mod_ccclx_ja{+#9+#8+#7}}{#1}% @@ -200,32 +350,36 @@ \def\XINT_mod_ccclx_jc +#1+#2+#3#4\relax{+80*(#3+#2+#1)+#3#2#1.}% \def\XINT_mod_ccclx_e#1.{\expandafter\XINT_mod_ccclx_z\the\numexpr(#1+180)/360-1.#1.}% \def\XINT_mod_ccclx_z#1.#2.{#2-360*#1.}% -\def\XINT_flexpr_func_sind_ #1#2#3% +\def\XINT_flexpr_func_@sind_rr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one{\romannumeral`&&@\xintSind#3}}% }% -\def\XINT_expr_unlock{\expandafter\xint_firstofone\romannumeral`&&@}% -\def\xintSind#1{\romannumeral`&&@\expandafter\xintsind - \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}% +\def\XINT_tmpa #1.{% +\def\xintSind##1% +{% + \romannumeral`&&@\expandafter\xintsind\romannumeral0\XINTinfloatS[#1]{##1}}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+12.% \def\xintsind #1[#2#3]% {% \xint_UDsignfork #2\XINT_sind -\XINT_sind_int - \krof#2#3.#1..%<< attention extra dot + \krof#2#3.#1..% }% -\def\XINT_sind #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2. +\def\XINT_tmpa #1.{% +\def\XINT_sind ##1.##2.% {% \expandafter\XINT_sind_a - \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}% + \romannumeral0\xinttrunc{#1}{##2[##1]}% }% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+5.% \def\XINT_sind_a{\expandafter\XINT_sind_i\the\numexpr\XINT_mod_ccclx_i0.}% \def\XINT_sind_int {% \expandafter\XINT_sind_i\the\numexpr\expandafter\XINT_mod_ccclx_i }% -\def\XINT_sind_i #1.% range reduction inside [0, 360[ +\def\XINT_sind_i #1.% {% \ifcase\numexpr#1/90\relax \expandafter\XINT_sind_A @@ -235,83 +389,77 @@ \else\expandafter\XINT_sind_E\the\numexpr-360+% \fi#1.% }% -\def\XINT_sind_A#1{% +\def\XINT_tmpa #1.#2.{% \def\XINT_sind_A##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_sind_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_B#1{\xint_UDsignfork#1\XINT_sind_B_n-\XINT_sind_B_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_B_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_B_p##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_C#1{\xint_UDsignfork#1\XINT_sind_C_n-\XINT_sind_C_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_C_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_C_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_D#1{\xint_UDsignfork#1\XINT_sind_D_n-\XINT_sind_D_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_sind_D_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_sind_D_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_sind_E#1{% \def\XINT_sind_E-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% -}\expandafter -\XINT_sind_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_flexpr_func_cosd_ #1#2#3% +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+4\expandafter.% + \romannumeral`&&@\xintbarefloateval @oneDegree\relax.% +\def\XINT_sind_B#1{\xint_UDsignfork#1\XINT_sind_B_n-\XINT_sind_B_p\krof #1}% +\def\XINT_sind_C#1{\xint_UDsignfork#1\XINT_sind_C_n-\XINT_sind_C_p\krof #1}% +\def\XINT_sind_D#1{\xint_UDsignfork#1\XINT_sind_D_n-\XINT_sind_D_p\krof #1}% +\def\XINT_flexpr_func_@cosd_rr #1#2#3% {% \expandafter #1\expandafter #2\expandafter{% \romannumeral`&&@\XINT:NEhook:f:one:from:one{\romannumeral`&&@\xintCosd#3}}% }% -\def\xintCosd#1{\romannumeral`&&@\expandafter\xintcosd - \romannumeral0\XINTinfloatS[\XINTdigits]{#1}}% +\def\XINT_tmpa #1.{% +\def\xintCosd##1% +{% + \romannumeral`&&@\expandafter\xintcosd\romannumeral0\XINTinfloatS[#1]{##1}}% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+12.% \def\xintcosd #1[#2#3]% {% \xint_UDsignfork #2\XINT_cosd -\XINT_cosd_int - \krof#2#3.#1..%<< attention extra dot + \krof#2#3.#1..% }% -\def\XINT_cosd #1.#2.% NOT TO BE USED WITH VANISHING (OR NEGATIVE) #2. +\def\XINT_tmpa #1.{% +\def\XINT_cosd ##1.##2.% {% \expandafter\XINT_cosd_a - \romannumeral0\xinttrunc{\XINTdigits}{#2[#1]}% + \romannumeral0\xinttrunc{#1}{##2[##1]}% }% +}\expandafter\XINT_tmpa\the\numexpr\XINTdigits+5.% \def\XINT_cosd_a{\expandafter\XINT_cosd_i\the\numexpr\XINT_mod_ccclx_i0.}% \def\XINT_cosd_int {% @@ -327,259 +475,401 @@ \else\expandafter\XINT_cosd_E\the\numexpr-360+% \fi#1.% }% -\def\XINT_cosd_A#1{% +\def\XINT_tmpa#1.#2.{% \def\XINT_cosd_A##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_cosd_A\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_B#1{\xint_UDsignfork#1\XINT_cosd_B_n-\XINT_cosd_B_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_B_n-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_B_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_C#1{\xint_UDsignfork#1\XINT_cosd_C_n-\XINT_cosd_C_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_C_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_C_p##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_D#1{\xint_UDsignfork#1\XINT_cosd_D_n-\XINT_cosd_D_p\krof #1}% -\def\XINT_tmpa#1{% \def\XINT_cosd_D_n-##1.##2.% {% - \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \xintiiopp\XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% \def\XINT_cosd_D_p##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_sin_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{##1.##2}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@sin_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{##1.##2}#2}}% }% -}\expandafter -\XINT_tmpa\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\def\XINT_cosd_E#1{% \def\XINT_cosd_E-##1.##2.% {% - \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_cos_\expandafter - {\romannumeral0\XINTinfloat[\XINTdigits]{\xintMul{\xintSub{##1[0]}{.##2}}#1}}% + \XINT_expr_unlock\expandafter\XINT_flexpr_userfunc_@cos_series\expandafter + {\romannumeral0\XINTinfloat[#1]{\xintMul{\xintSub{##1[0]}{.##2}}#2}}% }% -}\expandafter -\XINT_cosd_E\expandafter{\romannumeral`&&@\xintthebarefloateval oneDegree\relax}% -\xintdeffloatfunc sind(x) := (x)?? - {(x>=-45)? - {sin_(x*oneDegree)} - {-sind_(-x)} +}\expandafter\XINT_tmpa + \the\numexpr\XINTdigits+4\expandafter.% + \romannumeral`&&@\xintbarefloateval @oneDegree\relax.% +\def\XINT_cosd_B#1{\xint_UDsignfork#1\XINT_cosd_B_n-\XINT_cosd_B_p\krof #1}% +\def\XINT_cosd_C#1{\xint_UDsignfork#1\XINT_cosd_C_n-\XINT_cosd_C_p\krof #1}% +\def\XINT_cosd_D#1{\xint_UDsignfork#1\XINT_cosd_D_n-\XINT_cosd_D_p\krof #1}% +\xintdeffloatfunc @sind(x) := (x)?? + {(x>=-\ifnum\XINTdigits>8 45\else60\fi)? + {@sin_series(x*@oneDegree)} + {-@sind_rr(-x)} } - {0} - {(x<=45)? - {sin_(x*oneDegree)} - {sind_(x)} + {0e0} + {(x<=\ifnum\XINTdigits>8 45\else60\fi e0)? + {@sin_series(x*@oneDegree)} + {@sind_rr(x)} } ;% -\xintdeffloatfunc cosd(x) := (x)?? - {(x>=-45)? - {cos_(x*oneDegree)} - {cosd_(-x)} +\xintdeffloatfunc @cosd(x) := (x)?? + {(x>=-\ifnum\XINTdigits>8 45\else60\fi)? + {@cos_series(x*@oneDegree)} + {@cosd_rr(-x)} } - {1} - {(x<=45)? - {cos_(x*oneDegree)} - {cosd_(x)} + {1e0} + {(x<=\ifnum\XINTdigits>8 45\else60\fi e0)? + {@cos_series(x*@oneDegree)} + {@cosd_rr(x)} } ;% -\xintdeffloatfunc sin(x):= (abs(x)<0.79)? - {sin_(x)} +\xintdeffloatfunc @sin(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin_series(x)} {(x)?? - {-sind_(-x*oneRadian)} + {-@sind_rr(-\xintexpr x*@oneRadian\relax)} {0} - {sind_(x*oneRadian)} + {@sind_rr(\xintexpr x*@oneRadian\relax)} } ;% -\xintdeffloatfunc cos(x):= (abs(x)<0.79)? - {cos_(x)} - {cosd_(abs(x*oneRadian))} +\xintdeffloatfunc @cos(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@cos_series(x)} + {@cosd_rr(abs(\xintexpr x*@oneRadian\relax))} ;% -\xintdeffloatfunc sinc(x):= (abs(x)<0.79) ? - {sin_aux(sqr(x))} - {sind_(abs(x)*oneRadian)/abs(x)} +\xintdeffloatfunc @sinc(x):= (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi) ? + {@sin_aux(sqr(x))} + {@sind_rr(\xintexpr abs(x)*@oneRadian\relax)/abs(x)} ;% -\xintdeffloatfunc tand(x):= sind(x)/cosd(x);% -\xintdeffloatfunc cotd(x):= cosd(x)/sind(x);% -\xintdeffloatfunc tan(x) := (x)?? - {(x>-0.79)? - {sin(x)/cos(x)} - {-cotd(90+x*oneRadian) +\xintdeffloatfunc @tand(x):= @sind(x)/@cosd(x);% +\xintdeffloatfunc @cotd(x):= @cosd(x)/@sind(x);% +\xintdeffloatfunc @tan(x) := (x)?? + {(x>-\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin(x)/@cos(x)} + {-@cotd(\xintexpr9e1+x*@oneRadian\relax) } } - {0} - {(x<0.79)? - {sin(x)/cos(x)} - {cotd(90-x*oneRadian)} + {0e0} + {(x<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@sin(x)/@cos(x)} + {@cotd(\xintexpr9e1-x*@oneRadian\relax)} } ;% -\xintdeffloatfunc cot(x) := (abs(x)<0.79)? - {cos(x)/sin(x)} +\xintdeffloatfunc @cot(x) := (abs(x)<\ifnum\XINTdigits>8 79e-2\else1e0\fi)? + {@cos(x)/@sin(x)} {(x)?? - {-tand(90+x*oneRadian)} - {0} - {tand(90-x*oneRadian)} + {-@tand(\xintexpr9e1+x*@oneRadian\relax)} + {0e0} + {@tand(\xintexpr9e1-x*@oneRadian\relax)} };% -\xintdeffloatfunc sec(x) := inv(cos(x));% -\xintdeffloatfunc csc(x) := inv(sin(x));% -\xintdeffloatfunc secd(x):= inv(cosd(x));% -\xintdeffloatfunc cscd(x):= inv(sind(x));% -\xintdeffloatfunc asin_aux(X) := 1 -\ifnum\XINTdigits>3 % actually 4 would achieve 1ulp in place of <0.5ulp - + X(1/6 -\ifnum\XINTdigits>9 - + X(3/40 +\xintdeffloatfunc @sec(x) := inv(@cos(x));% +\xintdeffloatfunc @csc(x) := inv(@sin(x));% +\xintdeffloatfunc @secd(x):= inv(@cosd(x));% +\xintdeffloatfunc @cscd(x):= inv(@sind(x));% +\expandafter\let\csname XINT_expr_func_@sin_aux\expandafter\endcsname + \csname XINT_flexpr_func_@sin_aux\endcsname +\expandafter\let\csname XINT_expr_func_@cos_aux\expandafter\endcsname + \csname XINT_flexpr_func_@cos_aux\endcsname +\ifnum\XINTdigits>16 +\def\XINT_flexpr_func_@asin_II#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_Arcsin_II_a#3}}% +}% +\def\XINT_tmpc#1.% +{% +\def\XINT_Arcsin_II_a##1% +{% + \expandafter\XINT_Arcsin_II_c_i\romannumeral0\XINTinfloatS[#1]{##1}% +}% +\def\XINT_Arcsin_II_c_i##1[##2]% +{% + \xintAdd{1/1[0]}{##1/6[##2]}% +}% +}% +\expandafter\XINT_tmpc\the\numexpr\XINTdigits-14.% +\fi +\ifnum\XINTdigits>34 +\def\XINT_tmpc#1.#2.#3.#4.% +{% +\def\XINT_Arcsin_II_a##1% +{% + \expandafter\XINT_Arcsin_II_a_iii\romannumeral0\XINTinfloatS[#1]{##1}\xint: +}% +\def\XINT_Arcsin_II_a_iii##1\xint: +{% + \expandafter\XINT_Arcsin_II_b\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_b##1\xint: +{% + \expandafter\XINT_Arcsin_II_c_i\romannumeral0\xintadd{#4}{\XINTinFloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def\XINT_Arcsin_II_c_i##1\xint:##2\xint: +{% + \xintAdd{1/1[0]}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}% +}% +}% +\expandafter\XINT_tmpc + \the\numexpr\XINTdigits-14\expandafter.% + \the\numexpr\XINTdigits-32\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-32]{3/40[0]}.% + \XINTinFloat[\XINTdigits-14]{1/6[0]}.% + }% +\fi +\ifnum\XINTdigits>52 +\def\XINT_tmpc#1.#2.#3.#4.#5.% +{% +\def\XINT_Arcsin_II_a_iii##1\xint: +{% + \expandafter\XINT_Arcsin_II_a_iv\romannumeral0\XINTinfloatS[#1]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_a_iv##1\xint: +{% + \expandafter\XINT_Arcsin_II_b\romannumeral0\XINTinfloatS[#2]{##1}\xint:##1\xint: +}% +\def\XINT_Arcsin_II_b##1\xint: +{% + \expandafter\XINT_Arcsin_II_c_ii + \romannumeral0\xintadd{#4}{\XINTinfloat[#2]{\xintMul{#3}{##1}}}\xint: +}% +\def\XINT_Arcsin_II_c_ii##1\xint:##2\xint: +{% + \expandafter\XINT_Arcsin_II_c_i + \romannumeral0\xintadd{#5}{\XINTinFloat[#1]{\xintMul{##1}{##2}}}\xint: +}% +}% +\expandafter\XINT_tmpc + \the\numexpr\XINTdigits-32\expandafter.% + \the\numexpr\XINTdigits-50\expandafter.\expanded{% + \XINTinFloat[\XINTdigits-50]{5/112[0]}.% + \XINTinFloat[\XINTdigits-32]{3/40[0]}.% + \XINTinFloat[\XINTdigits-14]{1/6[0]}.% + }% +\fi +\def\XINT_flexpr_func_@asin_I#1#2#3% +{% + \expandafter #1\expandafter #2\expandafter{% + \romannumeral`&&@\XINT:NEhook:f:one:from:one + {\romannumeral`&&@\XINT_Arcsin_I#3}}% +}% +\def\XINT_Arcsin_I#1{\the\numexpr\expandafter\XINT_Arcsin_Ia\romannumeral0\xintiround9{#1}.}% +\def\XINT_Arcsin_Ia#1.% +{% + (\expandafter\XINT_Arcsin_Ib\the\numexpr#1*#1/\xint_c_x^ix.)*% + #1/\xint_c_x^ix[-9]% +}% +\def\XINT_Arcsin_Ib#1.% +{%(((((((((((((((( + % 3481/3660)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 3249/3422)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 3025/3192)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2809/2970)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2601/2756)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2401/2550)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2209/2352)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + % 2025/2162)*#1/\xint_c_x^ix+\xint_c_x^ix)*% +((((((((((((((((((((((((((((((((((((((((((% + %(\xint_c_x^ix*1849/1980)*% + 933838384*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1681/1806)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1521/1640)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1369/1482)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1225/1332)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1089/1190)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 961/1056)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 841/930)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 729/812)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 625/702)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 529/600)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 441/506)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 361/420)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 289/342)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 225/272)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 169/210)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 121/156)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 81/110)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 49/72)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 25/42)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 9/20)*#1/\xint_c_x^ix+\xint_c_x^ix)*% + 1/6)*#1/\xint_c_x^ix+\xint_c_x^ix +}% \ifnum\XINTdigits>16 - + X(5/112 -\ifnum\XINTdigits>25 - + X(35/1152 -\ifnum\XINTdigits>35 - + X(63/2816 -\ifnum\XINTdigits>46 - + X(231/13312 - )\fi)\fi)\fi)\fi)\fi)\fi;% -\xintdeffloatfunc asin_o(D, T) := T + D*asin_aux(sqr(D));% -\xintdeffloatfunc asin_n(V, T, t, u) :=% V is square of T - asin_o (\xintexpr t*cos_aux(V) - u*T*sin_aux(V)\relax, T);% -\xintdeffloatfunc asin_m(T, t, u) := asin_n(sqr(T), T, t, u);% -\xintdeffloatfunc asin_l(t, u) := asin_m(t*asin_aux(sqr(t)), t, u);% -\xintdeffloatfunc asin_a(t, u) := (t<u)? - {asin_l(t, u)} - {Piover2 - asin_l(u, t)} + \xintdeffloatfunc @asin_o(D, T) := T + D*@asin_II(sqr(D));% + \xintdeffloatfunc @asin_n(V, T, t, u) :=% + @asin_o(\xintexpr t*@cos_aux(V) - u*T*@sin_aux(V)\relax, T);% +\else + \xintdeffloatfunc @asin_n(V, T, t, u) :=% + \xintexpr t*@cos_aux(V) - u*T*@sin_aux(V)\relax + T;% +\fi +\xintdeffloatfunc @asin_m(T, t, u) := @asin_n(sqr(T), T, t, u);% +\xintdeffloatfunc @asin_l(t, u) := @asin_m(@asin_I(t), t, u);% +\xintdeffloatfunc @asin_a(t, u) := (t<u)? + {@asin_l(t, u)} + {@Piover2 - @asin_l(u, t)} ;% -\xintdeffloatfunc asind_a(t, u):= (t<u)? - {asin_l(t, u) * oneRadian} - {90 - asin_l(u, t) * oneRadian} +\xintdeffloatfunc @asind_a(t, u):= (t<u)? + {@asin_l(t, u) * @oneRadian} + {9e1 - @asin_l(u, t) * @oneRadian} ;% -\xintdeffloatfunc asin(t) := (t)?? - {-asin_a(-t, sqrt_(1-sqr(t)))} - {0} - {asin_a(t, sqrt_(1-sqr(t)))} +\xintdeffloatfunc @asin(t) := (t)?? + {-@asin_a(-t, sqrt(1e0-sqr(t)))} + {0e0} + {@asin_a(t, sqrt(1e0-sqr(t)))} ;% -\xintdeffloatfunc asind(t) := (t)?? - {-asind_a(-t, sqrt_(1-sqr(t)))} - {0} - {asind_a(t, sqrt_(1-sqr(t)))} +\xintdeffloatfunc @asind(t) := (t)?? + {-@asind_a(-t, sqrt(1e0-sqr(t)))} + {0e0} + {@asind_a(t, sqrt(1e0-sqr(t)))} ;% -\xintdeffloatfunc acos(t) := Piover2 - asin(t);% -\xintdeffloatfunc acosd(t):= 90 - asind(t);% -\xintdeffloatfunc atan_b(t, w, z):= 0.5 * (w< 0)? - {Pi - asin_a(2z * t, -w*z)} - {asin_a(2z * t, w*z)} +\xintdeffloatfunc @acos(t) := @Piover2 - @asin(t);% +\xintdeffloatfunc @acosd(t):= 9e1 - @asind(t);% +\xintdeffloatfunc @atan_b(t, w, z):= 5e-1 * (w< 0)? + {@Pi - @asin_a(2e0*z * t, -w*z)} + {@asin_a(2e0*z * t, w*z)} ;% -\xintdeffloatfunc atan_a(t, T) := atan_b(t, 1-T, inv(1+T));% -\xintdeffloatfunc atan(t):= (t)?? - {-atan_a(-t, sqr(t))} +\xintdeffloatfunc @atan_a(t, T) := @atan_b(t, 1e0-T, inv(1e0+T));% +\xintdeffloatfunc @atan(t):= (t)?? + {-@atan_a(-t, sqr(t))} {0} - {atan_a(t, sqr(t))} + {@atan_a(t, sqr(t))} ;% -\xintdeffloatfunc atand_b(t, w, z) := 0.5 * (w< 0)? - {180 - asind_a(2z * t, -w*z)} - {asind_a(2z * t, w*z)} +\xintdeffloatfunc @atand_b(t, w, z) := 5e-1 * (w< 0)? + {18e1 - @asind_a(2e0*z * t, -w*z)} + {@asind_a(2e0*z * t, w*z)} ;% -\xintdeffloatfunc atand_a(t, T) := atand_b(t, 1-T, inv(1+T));% -\xintdeffloatfunc atand(t) := (t)?? - {-atand_a(-t, sqr(t))} +\xintdeffloatfunc @atand_a(t, T) := @atand_b(t, 1e0-T, inv(1e0+T));% +\xintdeffloatfunc @atand(t) := (t)?? + {-@atand_a(-t, sqr(t))} {0} - {atand_a(t, sqr(t))} + {@atand_a(t, sqr(t))} ;% -\xintdeffloatfunc Arg(x, y):= (y>x)? +\xintdeffloatfunc @Arg(x, y):= (y>x)? {(y>-x)? - {Piover2 - atan(x/y)} + {@Piover2 - @atan(x/y)} {(y<0)? - {-Pi + atan(y/x)} - {Pi + atan(y/x)} + {-@Pi + @atan(y/x)} + {@Pi + @atan(y/x)} } } {(y>-x)? - {atan(y/x)} - {-Piover2 + atan(x/-y)} + {@atan(y/x)} + {-@Piover2 + @atan(x/-y)} } ;% -\xintdeffloatfunc atan2(y,x) := Arg(x, y);% -\xintdeffloatfunc Argd(x, y):= (y>x)? +\xintdeffloatfunc @atan2(y,x) := @Arg(x, y);% +\xintdeffloatfunc @Argd(x, y):= (y>x)? {(y>-x)? - {90 - atand(x/y)} + {9e1 - @atand(x/y)} {(y<0)? - {-180 + atand(y/x)} - {180 + atand(y/x)} + {-18e1 + @atand(y/x)} + {18e1 + @atand(y/x)} } } {(y>-x)? - {atand(y/x)} - {-90 + atand(x/-y)} + {@atand(y/x)} + {-9e1 + @atand(x/-y)} } ;% -\xintdeffloatfunc atan2d(y,x) := Argd(x, y);% -\xintdeffloatfunc pArg(x, y):= (y>x)? +\xintdeffloatfunc @atan2d(y,x) := @Argd(x, y);% +\xintdeffloatfunc @pArg(x, y):= (y>x)? {(y>-x)? - {Piover2 - atan(x/y)} - {Pi + atan(y/x)} + {@Piover2 - @atan(x/y)} + {@Pi + @atan(y/x)} } {(y>-x)? {(y<0)? - {twoPi + atan(y/x)} - {atan(y/x)} + {@twoPi + @atan(y/x)} + {@atan(y/x)} } - {threePiover2 + atan(x/-y)} + {@threePiover2 + @atan(x/-y)} } ;% -\xintdeffloatfunc pArgd(x, y):=(y>x)? +\xintdeffloatfunc @pArgd(x, y):=(y>x)? {(y>-x)? - {90 - atan(x/y)*oneRadian} - {180 + atan(y/x)*oneRadian} + {9e1 - @atan(x/y)*@oneRadian} + {18e1 + @atan(y/x)*@oneRadian} } {(y>-x)? - {(y<0)? - {360 + atan(y/x)*oneRadian} - {atan(y/x)*oneRadian} + {(y<0e0)? + {36e1 + @atan(y/x)*@oneRadian} + {@atan(y/x)*@oneRadian} } - {270 + atan(x/-y)*oneRadian} + {27e1 + @atan(x/-y)*@oneRadian} } ;% -\expandafter\let\csname XINT_flexpr_func_tg\expandafter\endcsname - \csname XINT_flexpr_func_tan\endcsname -\expandafter\let\csname XINT_flexpr_func_cotg\expandafter\endcsname - \csname XINT_flexpr_func_cot\endcsname +\expandafter\let + \csname XINT_flexpr_exec_+\expandafter\endcsname + \csname XINT_flexpr_exec_+_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_-\expandafter\endcsname + \csname XINT_flexpr_exec_-_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_*\expandafter\endcsname + \csname XINT_flexpr_exec_*_\endcsname +\expandafter\let + \csname XINT_flexpr_exec_/\expandafter\endcsname + \csname XINT_flexpr_exec_/_\endcsname +\expandafter\let + \csname XINT_flexpr_func_sqr\expandafter\endcsname + \csname XINT_flexpr_sqrfunc\endcsname +\expandafter\let + \csname XINT_flexpr_func_sqrt\expandafter\endcsname + \csname XINT_flexpr_sqrtfunc\endcsname +\expandafter\let + \csname XINT_flexpr_func_inv\expandafter\endcsname + \csname XINT_flexpr_invfunc\endcsname \xintFor #1 in {sin, cos, tan, sec, csc, cot, asin, acos, atan}\do {% - \xintdeffunc #1(x) := \xintfloatexpr #1(sfloat(x))\relax;% - \xintdeffunc #1d(x):= \xintfloatexpr #1d(sfloat(x))\relax;% + \xintdeffloatfunc #1(x) := float_(@#1(x));% + \xintdeffloatfunc #1d(x) := float_(@#1d(x));% + \xintdeffunc #1(x) := float_(\xintfloatexpr @#1(sfloat(x))\relax);% + \xintdeffunc #1d(x):= float_(\xintfloatexpr @#1d(sfloat(x))\relax);% }% \xintFor #1 in {Arg, pArg, atan2}\do {% - \xintdeffunc #1(x, y) := \xintfloatexpr #1(sfloat(x), sfloat(y))\relax;% - \xintdeffunc #1d(x, y):= \xintfloatexpr #1d(sfloat(x), sfloat(y))\relax;% + \xintdeffloatfunc #1(x, y) := float_(@#1(x, y));% + \xintdeffloatfunc #1d(x, y) := float_(@#1d(x, y));% + \xintdeffunc #1(x, y) := float_(\xintfloatexpr @#1(sfloat(x), sfloat(y))\relax);% + \xintdeffunc #1d(x, y):= float_(\xintfloatexpr @#1d(sfloat(x), sfloat(y))\relax);% }% -\xintdeffunc tg(x) := \xintfloatexpr tg(sfloat(x))\relax;% -\xintdeffunc cotg(x):= \xintfloatexpr cotg(sfloat(x))\relax;% -\xintdeffunc sinc(x):= \xintfloatexpr sinc(sfloat(x))\relax;% +\xintdeffloatfunc sinc(x):= float_(@sinc(x));% +\xintdeffunc sinc(x):= float_(\xintfloatexpr @sinc(sfloat(x))\relax);% +\expandafter\let\csname XINT_flexpr_func_tg\expandafter\endcsname + \csname XINT_flexpr_func_tan\endcsname +\expandafter\let\csname XINT_flexpr_func_cotg\expandafter\endcsname + \csname XINT_flexpr_func_cot\endcsname +\xintdeffloatvar twoPi := @twoPi;% +\xintdeffloatvar threePiover2 := @threePiover2;% +\xintdeffloatvar Pi := @Pi;% +\xintdeffloatvar Piover2 := @Piover2;% +\xintdeffloatvar oneDegree := @oneDegree;% +\xintdeffloatvar oneRadian := @oneRadian;% +\xintunassignvar{@twoPi}\xintunassignvar{@threePiover2}% +\xintunassignvar{@Pi}\xintunassignvar{@Piover2}% +\xintunassignvar{@oneRadian}\xintunassignvar{@oneDegree}% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintrestorevariable{#1}}% +\XINTtrigendinput% \endinput %% %% End of file `xinttrig.sty'. |