1

Motivation

I'm trying to calculate different probabilities 'automatically', given only some variables such as the number of cards in a sample and the number of cards drawn.

Code

The following code consists of a combination of the code from "Reducing Fractions Automatically Using LaTeX3" and "Command for Multiplying Integers".

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn \cs_new:Nn \svend_gcd:nn { \int_compare:nNnTF {#2} = { 0 } {#1} { \svend_gcd:ff {#2} { \int_mod:nn {#1} {#2} } } } \cs_generate_variant:Nn \svend_gcd:nn { ff }

\int_new:N \l__svend_tmp_int \cs_new:Nn \svend_reduced:nn { \int_set:Nn \l__svend_tmp_int { \svend_gcd:nn {#1} {#2} } \frac { \svend_reduced_wrap:n { \int_eval:n { #1 / \l__svend_tmp_int } } } { \svend_reduced_wrap:n { \int_eval:n { #2 / \l__svend_tmp_int } } } } \cs_new:Nn \svend_reduced_use_wrapper:N { \cs_set_eq:NN \svend_reduced_wrap:n #1 } \svend_reduced_use_wrapper:N \use:n

\msg_new:nnn { svend } { malformed-fraction } { The~input~you~have~provided~is~malformed.~ Please~provide~input~in~the~form~of~`p/q'. }

\NewDocumentCommand \ReducedFractionWrapper { m } { \svend_reduced_use_wrapper:N #1 }

\NewDocumentCommand \ReducedFraction { o > { \SplitList { / } } m } { \group_begin: \IfValueT{#1}{\ReducedFractionWrapper{#1}} \int_compare:nTF { \tl_count:n {#2} = 2 } { \svend_reduced:nn #2 } { \msg_error:nn { svend } { malformed-fraction } } \group_end: }

\NewExpandableDocumentCommand \produkt { m m } { \svend_multiply:nn {#1} {#2} } \cs_new:Npn \svend_multiply:nn #1#2 { \int_eval:n { 1 \int_step_function:nnN {#1} {#2} __svend_multiply:n } } \cs_new:Npn __svend_multiply:n #1 { * #1 } \ExplSyntaxOff

\usepackage{siunitx}

\begin{document}

\def\roed{5} \def\sort{9} \newcommand*\kortTotal{\fpeval{\roed+\sort}} \def\udtraek{10}

\begin{equation} \ReducedFraction[\num] {(\produkt{\kortTotal-\udtraek+1}{\kortTotal}-\produkt{1}{\udtraek}) /\produkt{\kortTotal-\udtraek+1}{\kortTotal}} \end{equation}

\end{document}

Error

I get the error

! Arithmetic overflow.
<recently read> \__int_eval_end:

l.66 ...\produkt{\kortTotal-\udtraek+1}{\kortTotal}}

When I change \def\udtraek{10} to \def\udtraek{9}, it compiles just fine. The number is obviously too big (which is also indicated by Arithmetic overflow) but I don't know how to adjust the code so that I can use larger numbers.

Question

How do I change the code so that I can use larger input integers?

  • Perlhaps a good thing to do is explain what exactly it is you are trying to do in the first place. Isn't quite clear for me by reading the code. – daleif Mar 13 '24 at 12:43
  • Well your issue here is that your products are just too big for TeX's count register size/expression. You could use bigintcalc for the work (we have some unreleased expl3 that does some but not all of the same). But as mentioned already, perhaps the question could do with some motivation. – Joseph Wright Mar 13 '24 at 13:55
  • 1
    As mentioned in one of the linked questions, xintexpr could also be used to implement the arbitrary precision required – Joseph Wright Mar 13 '24 at 13:57
  • @daleif Please see top of updated post. – Svend Tveskæg Mar 13 '24 at 13:59
  • @JosephWright Please see top of updated post. Thanks - I'll see if I can make it work using xintexpr. If you have an elegant implementation, I'd be happy to see your solution. – Svend Tveskæg Mar 13 '24 at 14:04
  • I haven't followed the code but if you are calculating probablilities do you need integer arithmetic, or can you use floating point? – David Carlisle Mar 13 '24 at 15:45
  • @DavidCarlisle I do need integer arithmetic, unfortunately; I also have to calculate both the numerator and the denominator explicitly. – Svend Tveskæg Mar 13 '24 at 18:40

1 Answers1

2

At present, your best option here is likely xint's \xintiieval, which can work with large integers and parse expressions. (There is some non-released expl3 code in this area, but it needs a few bits of finishing; bigintcalc doesn't do expressions.)

Taking that route and simplifying to highlight just the key points:

\documentclass{article}
\usepackage{xintexpr}
\makeatletter
\newcommand\svend@saved@gcd{}
\NewDocumentCommand\ReducedFraction{O{\@firstofone}mm}
  {%
    \edef\svend@saved@gcd{gcd(#2,#3)}%
    \expanded{%
      \noexpand\frac
        {%
          \noexpand#1%
            {\xintiieval{#2/\svend@saved@gcd}}%
        }%
        {%
          \noexpand#1%
            {\xintiieval{#3/\svend@saved@gcd}}%
        }%
     }% 
  }
\makeatother
\NewExpandableDocumentCommand\produkt{mm}
  {\xintiieval{pfactorial(#1,#2)}}

\usepackage{siunitx}

\begin{document}

\def\roed{5} \def\sort{9} \newcommand*\kortTotal{} \edef\kortTotal{\xintiieval{\roed+\sort}} \def\udtraek{9}

\begin{equation} \ReducedFraction[\num] {(\produkt{\kortTotal-\udtraek+1}{\kortTotal}-\produkt{1}{\udtraek})} {\produkt{\kortTotal-\udtraek+1}{\kortTotal}} \end{equation}

\end{document}

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • 1
    I'm not sure what you mean about the fraction not being reduced: example? – Joseph Wright Mar 13 '24 at 19:50
  • Everything is fine. Sorry. Unrelated: Are there any plans for when the relevant expl code for my question will be released? – Svend Tveskæg Mar 13 '24 at 20:31
  • 1
    @SvendTveskæg Well it wasn't on the agenda at all, but I am wonder if we should tidy up and get it out. Mainly a question of implementing division - I'll make a start on that – Joseph Wright Mar 13 '24 at 20:34