18

Example:

\usepackage{siunitx}

\newcommand{\temperature}[1]{\SI{#1}{\celsius}}
\temperature{100}

output: 100°C

I would like something like:

\newcommand{\temperature}[1]{\SI{#1+273}{\kelvin} (\SI{#1}{\celsius})}
\temperature{100}

output: 373K (100°C)

Is it possible?

5
  • 1
    Welcome to TeX.SE! A quick hint: If you indent lines of LaTeX code by four spaces, they will be auto-formatted appropriately.
    – Mico
    Nov 22 '13 at 14:08
  • In addition to the great answers below, you can have a look on an fp-package solution in this answer: tex.stackexchange.com/a/87825
    – LaRiFaRi
    Nov 22 '13 at 14:53
  • 2
    Remember that the difference is 275.15 degrees, not 273 degrees. Nov 22 '13 at 15:15
  • @SvendTveskæg I thought you couldn't have temperatures lower than 0 K, but with your suggested transformation we can go down to -2K.
    – Bakuriu
    Nov 22 '13 at 19:02
  • No it cannot; absolut zero is 0 degrees Kelvin and that is equivalent to -273.15 degrees Celsius. Nov 23 '13 at 10:45
15

You can use the l3fp module of expl3:

\documentclass{article}
\usepackage{siunitx} % already loads xparse

\ExplSyntaxOn
\NewDocumentCommand{\temperature}{ O{0} m }
 {
  \bryebex_temperature:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bryebex_temperature:nn #1 #2
 {
  \SI{ \fp_to_decimal:n { round ( #2+273.15, #1 ) } } { \kelvin }
  \nobreakspace ( \SI { #2 } { \celsius } )
 }
\ExplSyntaxOff

\begin{document}

\temperature{100}

\temperature[2]{100}

\end{document}

The optional argument tells the number of decimal digits for the rounding.

enter image description here

5
  • 5
    Note that it's likely that I'll extend siunitx to have this ability available 'natively' for the next major release. I'm hoping to work on it over the Christmas holidays.
    – Joseph Wright
    Nov 22 '13 at 16:06
  • @JosephWright Exactly what ability? Doing automatic calculations? Nov 22 '13 at 16:36
  • 2
    @SvendTveskæg Treating the numerical input as a floating-point expression. Current thinking is to make this optional with the result having to be a simple real number. I need to extend the parser approach in several ways as it is.
    – Joseph Wright
    Nov 22 '13 at 16:38
  • @JosephWright Thank you for the explanation. Nov 22 '13 at 16:42
  • @JosephWright I first tried with \exp_args:Nx in front of the first \SI, but then I realized it's not needed as \SI already does full expansion on its first argument.
    – egreg
    Nov 22 '13 at 16:47
7

You can calculate the expression #1+273 outside \SI and use it. To calculate you can use your preferred method. I chose pgf.

\documentclass{article}
\usepackage{siunitx,pgf}
\newcommand*{\temperature}[1]{\pgfmathtruncatemacro{\temp}{#1+273}\SI{\temp}{\kelvin} (\SI{#1}{\celsius})}
%no truncation
\newcommand*{\temperatur}[1]{\pgfmathparse{#1+273}\SI{\pgfmathresult}{\kelvin} (\SI{#1}{\celsius})}
%
\begin{document}
    \temperatur{100.23} and \temperature{123}
\end{document}

enter image description here

4

To each his/her favourite math engine...

Blockquote

Update: using \xinttheexpr...\relax for infix notations. But it doesn't seem that \SI does a full expansion immediately, it first apparently parses for ( and ) among others. So I had to do a little trick with a \firstofone.

\documentclass{article}
\usepackage{siunitx,xintexpr}

\providecommand\firstofone [1]{#1}

% We use this \firstofone trick to hide ( and ) from the \SI parser.
% Braces can not be used inside \xinttheexpr...\relax for this purpose

\newcommand*{\celsiusfromkelvin}[2][2]
     {\SI{\firstofone {\xinttheexpr round(#2-273.15,#1)\relax}}{\celsius}}
\newcommand*{\celsiusfromfahrenheit}[2][2]
     {\SI{\firstofone {\xinttheexpr round((#2-32)*5/9,#1)\relax}}{\celsius}}
\newcommand*{\fahrenheitfromkelvin}[2][2]
     {\SI{\firstofone {\xinttheexpr round(1.8*#2-459.67,#1)\relax}}{\fahrenheit}}
\newcommand*{\fahrenheitfromcelsius}[2][2]
     {\SI{\firstofone {\xinttheexpr round(1.8*#2+32,#1)\relax}}{\fahrenheit}}
\newcommand*{\kelvinfromcelsius}[2][2]
     {\SI{\firstofone {\xinttheexpr round(#2+273.15,#1)\relax}}{\kelvin}}
\newcommand*{\kelvinfromfahrenheit}[2][2]
     {\SI{\firstofone {\xinttheexpr round((#2+459.67)*5/9,#1)\relax}}{\kelvin}}



\DeclareSIUnit[number-unit-product=\,]
\fahrenheit{\SIUnitSymbolDegree F}    
\begin{document}
    \celsiusfromkelvin {300} (\SI{300}{\kelvin})

    \fahrenheitfromkelvin {300} (\SI{300}{\kelvin})

    \celsiusfromfahrenheit {80.33} (\SI{80.33}{\fahrenheit})

    \fahrenheitfromcelsius {26.85}  (\SI{26.85}{\celsius})

    \kelvinfromcelsius {26.85} (\SI{26.85}{\celsius})

    \kelvinfromfahrenheit {80.33} (\SI{80.33}{\fahrenheit})

    \celsiusfromfahrenheit [4] {80} (\SI{80}{\fahrenheit})

    \fahrenheitfromcelsius [4] {26.6667}  (\SI{26.6667}{\celsius})

    \fahrenheitfromcelsius [4] {26.66667}  (\SI{26.66667}{\celsius})


\end{document}

Earlier method, without infix notations

\documentclass{article}
\usepackage{siunitx,xintfrac}

\newcommand*{\celsiusfromkelvin}[2][2]
     {\SI{\xintRound{#1}{\xintSub{#2}{273.15}}}{\celsius}}
\newcommand*{\celsiusfromfahrenheit}[2][2]
     {\SI{\xintRound{#1}{\xintMul{\xintSub{#2}{32}}{5/9}}}{\celsius}}
\newcommand*{\fahrenheitfromkelvin}[2][2]
     {\SI{\xintRound{#1}{\xintSub{\xintMul{#2}{1.8}}{459.67}}}{\fahrenheit}}
\newcommand*{\fahrenheitfromcelsius}[2][2]
     {\SI{\xintRound{#1}{\xintAdd{\xintMul{#2}{1.8}}{32}}}{\fahrenheit}}
\newcommand*{\kelvinfromcelsius}[2][2]
     {\SI{\xintRound{#1}{\xintAdd{#2}{273.15}}}{\kelvin}}
\newcommand*{\kelvinfromfahrenheit}[2][2]
     {\SI{\xintRound{#1}{\xintMul{\xintAdd{#2}{459.67}}{5/9}}}{\kelvin}}


\DeclareSIUnit[number-unit-product=\,]
\fahrenheit{\SIUnitSymbolDegree F}

\begin{document}

    \celsiusfromkelvin {300} (\SI{300}{\kelvin})

    \fahrenheitfromkelvin {300} (\SI{300}{\kelvin})

    \celsiusfromfahrenheit {80.33} (\SI{80.33}{\fahrenheit})

    \fahrenheitfromcelsius {26.85}  (\SI{26.85}{\celsius})

    \kelvinfromcelsius {26.85} (\SI{26.85}{\celsius})

    \kelvinfromfahrenheit {80.33} (\SI{80.33}{\fahrenheit})

    \celsiusfromfahrenheit [4] {80} (\SI{80}{\fahrenheit})

    \fahrenheitfromcelsius [4] {26.6667}  (\SI{26.6667}{\celsius})

    \fahrenheitfromcelsius [4] {26.66667}  (\SI{26.66667}{\celsius})


\end{document}
2

My first thought: With luaLaTeX it should be quite easy.

Here it is:

\documentclass{scrartcl} 
\usepackage{siunitx}
\newcommand{\temperature}[1]{\SI{\directlua{tex.sprint(#1+273.15)}}{\kelvin} (\SI{#1}{\celsius})}

\begin{document}
\temperature{100}
\end{document}

I replaced your #1+273 with \directlua{tex.sprint(#1+273.15)}.

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.