Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Faulty code:

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

\newcommand{\ratio}{%
  \FPdiv\result{\x}{\y}%
  \FPround\result\result{2}%
  \result%
}

\begin{document}
\FPset\x{2}
\FPset\y{3}
\numprint{\ratio}
\end{document}

LaTeX complains:

! Undefined control sequence. \next ->\@nil

l.14 \numprint{\ratio}

How do I evaluate \ratio and print it with \numprint?

share|improve this question
    
\numprint wants to see a number, not the instructions for producing it. Can you show a more realisting situation? –  egreg Oct 18 '13 at 20:44
    
@egreg I have a macro that outputs a value which depends on previously defined variables. –  feklee Oct 18 '13 at 20:56
    
easier syntax is made possible if the computations are done expandably; egreg has now provided an l3fp approach. Using xintfrac, \numprint{\xintRound {2}{\xintDiv\x\y}}. And with xintexpr \numprint{\xinttheexpr round(\x/\y,2)\relax}. I did not make an answer because you might need functions such as sin or cos which are not at this time yet in xintexpr. –  jfbu Oct 19 '13 at 7:32

4 Answers 4

up vote 7 down vote accepted

The \numprint macro needs to be fed with a string of characters, not with the instructions to produce it. With fp, these instructions involve assignments, while \numprint is only able to process a control sequence that just expands to a number in the proper format. So the string has to be produced in advance. (Thanks to jfbu for noticing that macros can be used in the argument to \numprint, so long as they expand to strings with the proper format.)

I suggest you to define a new command that takes as argument an FP expression, possibly in a macro:

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

\newcommand{\numprintexpr}[2][\result]{%
  #2\relax\numprint{#1}}

\newcommand{\ratio}{%
  \FPdiv\result{\x}{\y}%
  \FPround\result\result{2}%
}

\begin{document}

\FPset\x{2}
\FPset\y{3}
\numprintexpr{\ratio}

\numprintexpr[\foo]{%
  \FPset\x{24}%
  \FPset\y{19}%
  \FPdiv\foo{\x}{\y}%
  \FPround\foo\foo{2}
}

\end{document}

The optional argument (default \result) tells \numprintexpr what control sequence stores the final result.

enter image description here


A different implementation using the fixed point facilities of expl3:

\documentclass{article}
\usepackage{xparse}
\usepackage{numprint}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\fpeval}{m}
 {
  \fp_eval:n { #1 }
 }
\NewDocumentCommand{\fpset}{mm}
 {
  \fp_zero_new:N #1
  \fp_set:Nn #1 { #2 }
 }
\cs_new_protected:Npn \feklee_numprint:n #1
 {
  \numprint { #1 }
 }
\NewDocumentCommand{\numprintexpr}{m}
 {
  \feklee_numprint:n { \fp_eval:n { #1 } }
 }
\ExplSyntaxOff

\newcommand{\ratio}{round(\x/\y,2)}

\begin{document}

\fpset\x{2}
\fpset\y{3}
\numprintexpr{\ratio}

\numprintexpr{round(pi/4,8)}

\end{document}

The syntax is different, but it's even easier than with fp.

enter image description here

share|improve this answer
    
Is there no way to evaluate \ratio and print it with \numprint without knowing the internals of the \ratio command? –  feklee Oct 19 '13 at 7:01
    
@feklee No, but with the suggested \numprintexpr command you don't need to know the internals, other than the scratch macro you use for storing the result: \numprint wants to see a string of characters, not the instructions for producing it. It would be different if you used the l3fp macros, that are expandable. –  egreg Oct 19 '13 at 7:06
    
Thanks for clarification! Perhaps you want to add this information to your answer. –  feklee Oct 19 '13 at 7:13
1  
@feklee Check the new implementation; I know it requires changing the syntax for expressions, but I believe it's better in the long run. –  egreg Oct 19 '13 at 7:22
    
Very interesting, thanks! –  feklee Oct 19 '13 at 7:54

pass the x/y values into the macro itself:

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

\newcommand\ratio[3]{%
  \FPdiv#3{#1}{#2}%
  \FPround{#3}{4}{4}}

\begin{document}
\ratio{2}{3}\result
\result

\numprint{\result}
\end{document}
share|improve this answer
    
You modified \ratio. That's an approach. However, I am asking for a solution to evaluate \ratio and then print the result using \numprint. –  feklee Oct 18 '13 at 22:01

There is already several answers to this question, but it seems that nobody suggested to use \edef. Knowing about this might be useful for you in other situations, so let me describe this alternative solution.

The \edef primitive is similar to \def but will expand the replacement text of the macro being defined. Here is how to rewrite your example:

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

\newcommand{\ratio}{%
  \FPdiv\result{\x}{\y}%
  \FPround\result\result{2}%
}

\begin{document}
\FPset\x{2}
\FPset\y{3}
\begingroup
  \ratio
  \edef\next{\noexpand\numprint{\result}%
  \expandafter
\endgroup
\next
\end{document}

See that computation and usage are now separated. The job of \ratio is limited to compute the ratio and store this in a macro.

TeX works very differently than a classical programming language where you can compose functions as you did. Indeed, it is a macro language, based on expanding and rewriting. So if you write

\numprint{\ratio}

you have absolutley no control over how the tokens produced by \ratio will be interpreted. It is easier to produce a \next macro whose replacement text is \numprint{0.67} as I did in my suggestion. Note that the whole \begingroup…\next snippet is actually replaced by \numprint{0.67} during processing.

If you are learning programming TeX, you should consider learning these methods based on \edef, \expandafter, \noexpand and registers.

share|improve this answer
    
In what does this differ from my answer? –  egreg Oct 20 '13 at 17:52
    
In what is this similar to your answer? It is not obvious to me so it will probably not be for the casual reader. –  Michael Grünewald Oct 20 '13 at 17:54
    
I'm doing \ratio\numprint{\result} which is essentially the same, except for the group. –  egreg Oct 20 '13 at 17:57
    
As I stated it in my answer, I think that suggesting the use of \edef might be a useful addition for somebody experimenting with or learning TeX's programming system. –  Michael Grünewald Oct 20 '13 at 18:02
    
Thanks for programming advise! –  feklee Oct 20 '13 at 18:46

You asked for a solution which keeps your original \ratio and then prints the result using \numprint. Here is how to do it:

[update: edited to avoid global assignments]

[update2: added \fFPedef macro which is necessary if one wants to go into the direction indicated at the bottom of this answer]

[update3: removed some superfluous \expandafter's]

[update4: fixed typo above (\fFPedef above was in my earlier choice \fFPset) just to move this up the list and get a chance to gather more upvotes :) ]

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

% ORIGINAL \ratio
% by convention its result is in ... \result
\newcommand{\ratio}{%
  \FPdiv\result{\x}{\y}%
  \FPround\result\result{2}%
  \result%
}

% WRAPPER to \numprint
% Must be applied to things like \ratio which compute a \result
\def\FPnumprint #1{% 
    \setbox0 \hbox{\def\result{#1}#1\expandafter}\expandafter
    \numprint\expandafter {\result}}

\begin{document}\thispagestyle{empty}
\FPset\x{2}
\FPset\y{3}

% works
\FPnumprint {\ratio}

\newcommand{\stuff}{\FPeval\result {(\x)*(\y)+(\x)^(\y)}}

% works also

\FPnumprint {\stuff}

\end{document}

Output:

numprint result

By the way one can use this kind of technique to transform all commands of fp.sty into nestable entities: (I use fFP@ prefix to mean functional form of an fp command)

\documentclass{article}
\usepackage{fp}
\usepackage{numprint}

% ORIGINAL \ratio
% by convention its result is in ... \result
\newcommand{\ratio}{%
  \FPdiv\result{\x}{\y}%
  \FPround\result\result{2}%
  \result%
}

% WRAPPER to \numprint
% Must be applied to things like \ratio which compute a \result
\def\FPnumprint #1{% 
    \setbox0 \hbox{\def\result{#1}#1\expandafter}\expandafter
    \numprint\expandafter {\result}}

\makeatletter
\def\fFPadd #1#2{%
  \setbox0 \hbox{\def\fFP@result{#1}#1\expandafter}%
  \expandafter\def\expandafter\fFP@tmpa\expandafter{\fFP@result}%
  \setbox0 \hbox{\def\fFP@result{#2}#2\expandafter}%
  \expandafter\def\expandafter\fFP@tmpb\expandafter{\fFP@result}%
  \FPadd\fFP@result \fFP@tmpa\fFP@tmpb 
  \fFP@result
}

\def\fFPmul #1#2{%
  \setbox0 \hbox{\def\fFP@result{#1}#1\expandafter}%
  \expandafter\def\expandafter\fFP@tmpa\expandafter{\fFP@result}%
  \setbox0 \hbox{\def\fFP@result{#2}#2\expandafter}%
  \expandafter\def\expandafter\fFP@tmpb\expandafter{\fFP@result}%
  \FPmul\fFP@result \fFP@tmpa\fFP@tmpb 
  \fFP@result
}

\def\fFPround #1#2{%
  \setbox0 \hbox{\def\fFP@result{#1}#1\expandafter}%
  \expandafter\def\expandafter\fFP@tmpa\expandafter{\fFP@result}%
  \setbox0 \hbox{\def\fFP@result{#2}#2\expandafter}%
  \expandafter\def\expandafter\fFP@tmpb\expandafter{\fFP@result}%
  \FPround\fFP@tmpb\fFP@tmpb {0}%
  \FPround\fFP@result \fFP@tmpa\fFP@tmpb
  \fFP@result
}

\def\fFPnumprint #1{%
    \setbox0 \hbox {\def\fFP@result {#1}#1\expandafter}%
    \expandafter\numprint\expandafter{\fFP@result}%
}

\makeatother

\begin{document}
\FPset\x{2}
\FPset\y{3}

% works
\FPnumprint {\ratio}

\newcommand{\stuff}{\FPeval\result {(\x)*(\y)+(\x)^(\y)}}

% works also
\FPnumprint {\stuff}

\fFPadd {\fFPmul{2}{7}}{\fFPmul{3}{7}}


\fFPround {\fFPadd{\fFPmul {3.21267}{5.277282}}{16.8927287}}{2}

\fFPround {\fFPadd{\fFPmul {3.21267}{5.277282}}{16.8927287}}{\fFPadd {1}{3}}

% !!! ATTENTION !!!
% HERE We USE \fFPnumprint as we know the "result" is in "\fFP@result" not in
% "\result"

\fFPnumprint {\fFPround {\fFPadd{\fFPmul
      {3.21267}{5.277282}}{16.8927287}}{\fFPadd {1}{3}}}

\end{document}

Output:

fFP in action

Perhaps some package could be made out of this starting point ... as fp is quite in use.


One needs in addition to the above a macro of the following type:

\makeatletter

\def\fFPedef #1#2{%
    \setbox0 \hbox{\def\fFP@result{#2}#2\expandafter}%
    \expandafter\edef\expandafter#1\expandafter{\fFP@result}%
}

\makeatother

\ttfamily

\fFPedef\x {\fFPmul{3.142627627}{\fFPadd{6.75272872}{7.832298292}}}
\meaning\x

Output:

fFPedef

The big difference is that as we can see here, these things are nestable.

share|improve this answer
    
You still need to know what the scratch macro is called; it may not be \result, for instance if you need two computations in parallel. –  egreg Oct 20 '13 at 15:45
    
@egreg The name of the scratch macro could be an optional argument defaulting to \result. In the second part of the answer I switch to \fFP@result. –  jfbu Oct 20 '13 at 15:50
    
@egreg you mean two computations inside the \numprint? –  jfbu Oct 20 '13 at 15:53
    
The optional argument is what I used, too. Multiple computations may be needed, using different storage macros; of course only one will store the final result and one can arrange for it to be named \result. –  egreg Oct 20 '13 at 15:56
    
@egreg one needs indeed an additional macro with the syntax \fFPprint\x{...} which will define \x to expand to the result of the (nested) computations; the difference with the original syntax of fp being that here we can nest things. –  jfbu Oct 20 '13 at 15:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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