8

I often put comments in my documents to remind me where a number comes from:

\SI{39.68}{\milli\metre} deep % 0.31 * 128

I'd like LaTeX to calculate the product by itself. I wrote a function to do that with fp, and it works (although I'd like a shorter one). But it doesn't work within \SI:

\newcommand{\mult}[2]{%
    \FPmul{\tempSum}{#1}{#2}%
    \FPround\roundedSum\tempSum2%
    \roundedSum%
}

\mult{0.31}{128} mm deep % works

\SI{\mult{0.31}{128}}{\milli\metre} deep % does not work

How to solve this?

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! siunitx error: "invalid-number"
! 
! Invalid numerical input '\edef {\FP@mul \tempSum 0.31..\relax 128..\relax
! }\edef {\FP@round \roundedSum ..\relax }{2}'.
! 
! See the siunitx documentation for further information.
! 
! For immediate help type H <return>.
!...............................................
  • 1
    Use \SI[parse-numbers=false]. Maybe you are also interested in a L3 multiplication: \ExplSyntaxOn \NewDocumentCommand \mult { m m } { \fp_eval:n { round( #1 * #2 ,2 ) } } \ExplSyntaxOff – Marco Daniel May 16 '13 at 16:41
6

siunitx parses numerical inputs with some options. However the input of the number isn't expanded before manipulating. To use tokens inside the first mandatory argument you can use the option parse-numbers=false.

If you define an expandable version of \mult you can use it as a valid input of \SI. In the example below this is done by \DeclareExpandableDocumentCommand provided by xparse.

\documentclass{article}
\usepackage{siunitx}
\usepackage{xparse} 
\ExplSyntaxOn
\DeclareExpandableDocumentCommand \mult {  m m  }
 {
  \fp_eval:n { round( #1 * #2  ,2 ) }
 }
\ExplSyntaxOff
\begin{document}
\mult{0.31}{128}

\SI[parse-numbers=false]{\mult{0.31}{128}}{\milli\metre} deep

\SI{\mult{0.31}{128}}{\milli\metre} 
\end{document} 

enter image description here


Using the module l3fp you can define arithmetic functions very easy. In the example above I used your definition with two mandatory arguments. However you can also use:

\NewDocumentCommand \Func { O{2} m   }
 {
  \fp_eval:n { round( #2   , #1 ) }
 }

Now \Func has two arguments the first one is optional and specifies the rounding. The second is passed to fp_eval:

\Func{0.38*4}
  • Thanks! I suppose \ExplSyntaxOn and l3fp only work with LaTeX 3? – Tim N May 16 '13 at 16:58
  • @TimN: This is LaTeX3. The package siunitx is written with the core language of L3 -- expl3. – Marco Daniel May 16 '13 at 16:58
  • Isn't it a bit weird to assume that I'm using LaTeX3, given that it hasn't been released yet? – Tim N May 16 '13 at 17:00
  • 1
    @TimN: The used moduls are all stable. You can find a lot of packages using LateX3. Eg.: siunitx, fnpct, xpatch, ... – Marco Daniel May 16 '13 at 17:02
  • 1
    @TimN 'LaTeX3' at present refers to the bits that are finished as much as the bigger 'a new format' idea. The code layer is pretty solid, and it's used by siunitx, so it's available to use without worrying. – Joseph Wright May 16 '13 at 18:54

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.