7

I would like to create a command that can multiply consecutive integers together (if it doesn't already exists).

How do I create a command, say \multiply{<first_number>}{<last_number>}, using LaTeX3, that multiplies all the integers from <first_number> to <last_number>?

Example: I would like \multiply{4}{9} to do the multiplication 4*5*6*7*8*9 and return the value 60480.

Unfortunately, I can't even create some 'starting' code for you (sorry!) since I haven't learned the L3 syntax yet. Therefore, I know it is a 'please do all the work for me' kind of question. :-(

  • 1
    You might like to know that this thing has already been defined and studied and is usually called the rising factorial with very slightly different notation, in case you want to give it a name which is more specific than \multiply or \Multiply. – ors Mar 13 '24 at 10:12

5 Answers5

12

The name \multiply is already defined (a primitive to multiply a register's value by a number and store the result in that register), hence I use \product for the following. Else this is pretty straight forward if you know the relevant L3 functions:

\documentclass{article}

\ExplSyntaxOn \NewExpandableDocumentCommand \product { m m } { \svendtveskaeg_multiply:nn {#1} {#2} } \cs_new:Npn \svendtveskaeg_multiply:nn #1#2 { \int_eval:n { 1 \int_step_function:nnN {#1} {#2} __svendtveskaeg_multiply:n } } \cs_new:Npn __svendtveskaeg_multiply:n #1 { * #1 } \ExplSyntaxOff

\begin{document} \product{4}{9} \typeout{\product{4}{9}} \end{document}

will print 60480 into the document and write it to the log.

Skillmon
  • 60,462
9

enter image description here

\documentclass{article}
\def\xmultiply#1#2{%
  \ifnum#1=\numexpr#2\relax\the\numexpr#1\relax\else
   \the\numexpr(#2)*\xmultiply{#1}{#2-1}\relax\fi}
\begin{document}

\xmultiply{4}{9} \end{document}

David Carlisle
  • 757,742
4

What we can do with OpTeX:

\def\multiply#1#2{\expr[0]{#1\fornum #1+1..#2\do{*##1}}}

\multiply{4}{9}

\multiply{4}{15}

\bye

Note three features:

  • The macro needs only single line of the code.
  • We can re-define the TeX primitive \multiply without lost of any function of internal macros, because we are doing this in the user name space.
  • The \expr macro is implemented by Lua expression, the numbers are limited by 2^63 while TeX numbers are limited by 2^31.
wipet
  • 74,238
2

Here's a LuaLaTeX-based solution. (Note that I've chosen \Multiply as the macro name, as there's already a macro called \multiply.)

enter image description here

Observe that the code correctly handles \Multiply{4}{4}. If the second argument is smaller than the first, the string "NIL" is returned.

% !TEX TS-program = lualatex
\documentclass{article}
\newcommand\Multiply[2]{\directlua{
  if #2<#1 then tex.sprint ( "NIL" ) 
  else j=#1; for i=#1+1,#2 do j = j*i end; tex.sprint (j)
  end}}

\begin{document} \Multiply{4}{9}, \Multiply{4}{4}. \end{document}

Mico
  • 506,678
  • 1
    Thank you, Mico. Your answer is very nice but I've accepted the answer from @Skillmon since I asked for a L3 solution. (Don't get me wrong; I appreciate your answer alot.) – Svend Tveskæg Mar 12 '24 at 20:09
2

AFAIK, the operation you are after is called Partial Factorial:

second number ! / (first number-1) !

Jean-François Burnol's xintexpr package can be used for this. It is part of the xint bundle and it allows for expandable arbitrary precision floating point and integer operations.

\documentclass{article}
\usepackage{xintexpr}

\begin{document}

\xintiieval{pfactorial(3,9)}% 60480 \typeout{\xintiieval{pfactorial(3,9)}}

\xintiieval{pfactorial(100,130)}% 69293021885203871012298422845822803287591970060789350400000000 \typeout{\xintiieval{pfactorial(100,130)}}

\end{document}

AlexG
  • 54,894