3

I have known that I can use "advance...by..." to do arithmetic on number in TeX, but is there any way to do arithmetic without changing the value of number? For example, if I want to determine whether a number called X whose value is x satisfies x^2+x+1<0, and keep the former value of X for future use, what can I do?

  • 2
    If it's really simple stuff and only integers you can use: \numexpr\myX*\myX+\myX+1\relax. So in a test this becomes: \ifnum\numexpr\myX*\myX+\myX+1\relax<0 (but there is no real value satisfying that inequation). – Skillmon likes topanswers.xyz Mar 20 '18 at 12:46
5

You can e.g. use xfp:

\documentclass{article}
\usepackage{xfp}
\newcommand\myxvalue{15}

\begin{document}

\ifnum \fpeval{\myxvalue^2 + \myxvalue + 1} < 0 \relax 
        yes  
\else no: it is \fpeval{\myxvalue^2 + \myxvalue + 1} 
\fi

\end{document}
  • this does not sound robust because a priori \fpeval produces floating point numbers (as digit tokens with dot) which would immediately cause problems with \ifnum. (for example if computations needs more then 16 digits of precision) Hasn't LaTeX3 introduced \numeval or \inteval ? but maybe this is only a wrapper to \numexpr hence no ^ operator. – user4686 Mar 20 '18 at 13:12
  • @jfbu yes you are right. One would have to use also the tests from l3fp. – Ulrike Fischer Mar 20 '18 at 13:37
  • Thinking again, I would expect your answer to be perfectly fine with integer only computations as long as final result fits in TeX bound (it appers, but I have not checked really, that \fpeval will not output 15.0 for example but 15), but the problem is with / which is not rounded integer division hence a discrepancy with \numexpr based computations. – user4686 Mar 20 '18 at 14:42
  • Out of sheer stubborness: try \fpeval{\myxvalue^1000/\myxvalue^999}. – user4686 Mar 20 '18 at 14:44
  • \xinttheiexpr \xintfloatexpr\myxvalue^1000/\myxvalue^999\relax\relax is only about 2.5x slower (*) as \fpeval{\myxvalue^1000/\myxvalue^999} and does output 15. (*) I must improve ;-) – user4686 Mar 20 '18 at 14:48
5

The xfp package is wrapper to access at user level the "Floating Point Unit" of LaTeX3. All its operations are expandable.

At the core level they use crucially the e-TeX addition to Knuth TeX of \numexpr, \dimexpr... which allow expandable computations with infix notations (and some sometimes surprising restrictions).

using directly \numexpr/\dimexpr might be all you need.

Maybe you need computations with integers bigger than 2^31 and you want ^operator? and factorial with !? then you can use bnumexpr.

For even more complicated things like add(x(x+1), x=1..100) you can use xintexpr.

An earlier package allowing expandable computations inclusive of powers was intcalc but without infix notations, only macros. Also bigintcalc does it with integers exceeding the 2^31 bound (intcalc achieves expandable computations even if the TeX-engine is lacking e-TeX \numexpr; this is interesting theoretically but quite slower in practice. It does use \numexpr if the latter is available).

As mentioned above xintexpr has extended infix syntax (and is faster when computing with "big" numbers). bnumexpr is a more light-weight package, which hooks also into the core arithmetics provided by xintcore, but does not develop as extensive a syntax as xintexpr.

Naturally at some point you will want to actually store the computations somewhere, via an \edef for example; so the computations are done expandably, without assignments, which is nice for \ifnum, for \write etc... (for embedding in some TikZ things, too), but at end of day you almost always have to do something unexpandable...

Then, things like fp, pgfmath, pgfplots, apnum, are math engine doing things non-expandably to start with (maybe I forget some, please complete). The apnum is arbitrary precision.

As per your original question, perhaps something in this style:

\xintdefvar X := whatever with big integers and fractions;
% 
\xintifboolexpr{X^2 + X + 1 < 0}{Yes branch}{No branch}

The first steps does the computations expandably and defines variable X. Then \xintifboolexpr is purely expandable and evaluates X^2 + X + 1 with no assignments.

Of course as was observed by @Skillmon always the No branch is taken here... (there is no interface to complex numbers in xintexpr so far).

  • Even if there were an interface to complex numbers, it doesn’t make much sense to compare complex numbers with zero… ;-) – GuM Mar 20 '18 at 13:54
  • @GuM You aren't completely wrong ;-)... It does make sense, it would expand to yes branch if the complex number is real negative. What does not (with no extra considerations) make sens is to compare two general complex numbers via <. – user4686 Mar 20 '18 at 13:57
  • @GuM If I define the predicate z<0 like I said it behaves correctly with addition, with multiplication by a real positive number, and even by multiplication of two such things if I have also defined similarly z>0. Hence it does make sense, despite the fact that we prefer that math undergraduate don't read these lines ;-) – user4686 Mar 20 '18 at 13:59
  • Fair enough… :-) – GuM Mar 20 '18 at 14:01
  • @GuM the key thing is to avoid defining a z>=0 as opposite of z<0. Because then this new predicate does not behave nicely with respect to addition, contrarily to z<0. Thus to some extent z_1 < z_2 may be defined, and also z_1 > z_2 but it will not be true that either z_1 = z_2or z_1 < z_2or z_2 < z_1. – user4686 Mar 20 '18 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.