Anzeige:
Ergebnis 1 bis 13 von 13

Thema: \ifnum mit Dezimalzahlen

  1. #1
    Registrierter Benutzer
    Registriert seit
    15.03.2012
    Beiträge
    4

    Question \ifnum mit Dezimalzahlen

    Hallo Leute.
    Ich tüftele seit einer Woche an einem Problem mit if-Abfragen herum. In einer Arbeit will ich den Signifikanzwert (p) so eingeben, wie er berechnet wurde (z. B. 0,00123). In der Ausgabe sollen die Werte dann gerundet bzw. übersetzt werden, üblich ist die Angabe (p < 0,05 oder, wenn p > 0,05 ist p = n. s. [nicht signifikant]).
    Mit Skriptsprachen habe ich etwas Erfahrung aber TeX treibt mich in den Wahnsinn.
    Folgendes Minimalbeispiel erzeugt im PDF zum Beispiel die Zeile
    Code:
    0.123: .123¡0.05p <= 0.05
    .
    Die \ifnum-Anweisung wird einfach ausgegeben! Beispiele wie einfache Schleifen in einem Latex-Kommando führen mich leider nicht weiter. Vielleicht könnt ihr mir helfen?!
    Die Angabe der Zahlen mit Komma (0,05) ändert nichts. Die Übersetzung nach ifthenelse mit dem ifthen-Paket erzeugt den gleichen Unsinn.

    Code:
    \documentclass{article}
    
    \newcommand*\pvalue[1]
    {
    	#1: 
    	\ifnum#1<=0.05%
    		p $<=0.05$		% wenn p <= 0.05
    	\else
    		$p = $ #1 (n.~s.)	% wenn p > 0.05 (nicht signifikant)
    	\fi
    	\\
    }
    
    \begin{document}
    
    \pvalue{0.123}\\
    \pvalue{0.0123}\\
    \pvalue{0.00123}\\
    \pvalue{0.000123}\\
    
    \end{document}

  2. #2
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    Vielleicht wäre das fp Paket was:
    Code:
    \documentclass{article}
    \usepackage{fp}
    \def\mynum{}
    
    \newcommand*\pvalue[1]{%
      #1: %
      \FPset\mynum{#1}%
      \FPiflt\mynum{.05}%
        $p=$ #1 (n.~s.)%
      \else
        $p\geq0.05$%
      \fi
      , gerundet: \FPround\mynum\mynum{2}\FPprint\mynum
      }
    
    \begin{document}
    
    \pvalue{0.123}\\
    \pvalue{0.0123}\\
    \pvalue{0.00123}\\
    \pvalue{0.000123}
    
    \end{document}
    Gruß
    Clemens

  3. #3
    Registrierter Benutzer
    Registriert seit
    15.03.2012
    Beiträge
    4

    Thumbs up Danke

    Danke, Clemens! Das war der Druchbruch!
    Anbei ein Minimalbeispiel, falls noch jemand anderes außer mir mit Latex herumdoktort.
    Code:
    \documentclass{article}
    \usepackage{fp}
    
    %% Das Paket definiert viele Funktionen, hier sind die binären Verhältnisse relevant:
    	%introduction of new values
    		%\FPset#1#2		% #1 := #2  (#1 may be macro or string)
    	%%binary relations
    		%\FPiflt#1#2...\else...\fi % #1 < #2 ?
                 	%\FPifeq#1#2...\else...\fi % #1 = #2 ?
                 	%\FPifgt#1#2...\else...\fi % #1 > #2 
    
    
    \def\mynum{}
    \newcommand*\pvalue[1]{%
    	\FPset{\pval}{#1}%
    	\FPiflt{\pval}{.001}%
    		$p<0.001$%
    	\else
    		\FPiflt{\pval}{.01}%
    			$p<0.01$%
    		\else
    			\FPiflt{\pval}{.05}%
    				$p<0.05$%
    			\else
    				$p =$ n.~s.%		das %-Zeichen beendet die Zeile, damit keine Leerzeichen weitergegeben werden
    			\fi
    		\fi
      \fi
      }
    
    \begin{document}
    
    Es fand sich kein Unterschied in der Koerperhoehe der untersuchten Hunde (\pvalue{0.123}). Sie hatten jedoch ein unterschiedliches Alter (\pvalue{0.0123}) und unterschiedlich lange Schnautzen (\pvalue{0.00123}). Im Vergleich mit Maeusen unterschied sich die Koerpergroeße hoechst signifikant (\pvalue{0.000123}).
    
    \end{document}
    Geändert von texnicker (15-03-2012 um 13:58 Uhr)

  4. #4
    Registrierter Benutzer
    Registriert seit
    15.03.2012
    Beiträge
    4

    doch noch noch ein Problem

    Beim Erstellen der PDF-Datei erscheint ein
    Code:
    extra \fi
    für alle Zahlen, die kleiner als 0.05 sind. Wenn die Schleife zum Beispiel bis \FPiflt{\pval}{.01} durchlaufen wird und dieser Wert true ist, dann wird $p<0.01$ ausgegeben und ein \fi ist zu viel. Bei Zahlen < 0,001 sogar zweimal. - Versteht jemand, warum? ... und vor allem, wie man das beheben kann?
    Reproduzierbar mit meinem Minimalbeispiel von oben.

  5. #5
    Registrierter Benutzer Avatar von mechanicus
    Registriert seit
    10.07.2008
    Ort
    Hamburg
    Beiträge
    3.944
    Hi,

    eine alternative mit expl3:

    Code:
    \documentclass{article}
    \usepackage{amsmath}
    \usepackage{xparse}
    \ExplSyntaxOn
    \NewDocumentCommand \pvalue { m }
    {
      \dim_compare:nTF {#1 pt <= 0.05 pt } 
        { $p \leq 0.05$ }		% wenn p <= 0.05
        { $p =  #1~\text{(n.~s.)}$  }	% wenn p > 0.05 (nicht signifikant)
    }
    \ExplSyntaxOff
    \begin{document}
    
    \pvalue{0.123}\\
    \pvalue{0.0123}\\
    \pvalue{0.00123}\\
    \pvalue{0.000123}\\
    
    \end{document}
    Marco

  6. #6
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    Sowas, wollte gerade dasselbe vorschlagen:
    Code:
    \documentclass{article}
    
    \usepackage{expl3}
    \ExplSyntaxOn
    \newcommand* \pvalue [1]
      {
        \fp_compare:nNnTF { #1 } < { .001 }
          { $p<0.001$ }
          {
            \fp_compare:nNnTF { #1 } < { .01 }
              { $p<0.01$ }
              {
                \fp_compare:nNnTF { #1 } < { .05 }
                  { $p<0.05$ }
                  { $p =$~n.~s. }
              }
          }
      }
    \ExplSyntaxOff
    \begin{document}
     \pvalue{.04}
     
     \pvalue{.005}
     
     \pvalue{.0005}
    \end{document}
    Verschachtelte \if -Abfragen sind immer tricky (finde auf die Schnelle leider nicht die Referenz, die ich im Hinterkopf habe). expl3 hat hier erstens die sichereren und zweitens die m.E. bequemeren Conditionals.

    An die Syntax muss man sich zwar erst gewöhnen, danach ist sie aber ziemlich selbsterklärend.

    Gruß
    Clemens

  7. #7
    Registrierter Benutzer Avatar von mechanicus
    Registriert seit
    10.07.2008
    Ort
    Hamburg
    Beiträge
    3.944
    Hi,

    @Clemens. Die Idee finde ich gut. Ich würde vermutlich eine alternative case-Umgebung bauen.

    Marco

  8. #8
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    Wenn ich ein bisschen mehr Zeit gehabt hätte(*), würde ich das auch ein klein wenig anders versuchen. Gibt es es nicht
    Code:
    \prg_cases
    das man verwenden könnte?

    (*) unterwegs, den St. Patricks Day zu feiern

    Gruß
    Clemens

  9. #9
    Registrierter Benutzer Avatar von mechanicus
    Registriert seit
    10.07.2008
    Ort
    Hamburg
    Beiträge
    3.944
    Hi,

    es gibt prg_case_int:nnn oder prg_case_dim:nnn oder prg_case_str:nnn ... aber kein fp ;-) und die Programmierung der Fälle ist jeweils mit dem Relationszeichen =. Man müsste also eine eigene Funktion bauen.

    Viel Spaß auf deiner Tour.

    Marco

  10. #10
    Registrierter Benutzer Avatar von mechanicus
    Registriert seit
    10.07.2008
    Ort
    Hamburg
    Beiträge
    3.944
    Hi,

    mit Hilfe von Joseph Wright gibt es nun eine Möglichkeit:

    Code:
    \documentclass{article}
    \usepackage[T1]{fontenc}
    \usepackage{amsmath}
    \usepackage{xparse}
    \ExplSyntaxOn
    \cs_new:Npn \prg_relation_case_dim:nnn #1
      {
        \tex_romannumeral:D
        \exp_args:Nf \prg_relation_case_dim_aux:nnn { \dim_eval:n {#1} }
      }
    \cs_new:Npn \prg_relation_case_dim_aux:nnn #1#2#3
      { \prg_relation_case_dim_aux:nw {#1} #2 { = #1 } {#3} \q_recursion_stop }
    \cs_new:Npn \prg_relation_case_dim_aux:nw #1#2#3
      {
        \dim_compare:nTF {#1#2}
          { \prg_case_end:nw {#3} }
          { \prg_relation_case_dim_aux:nw {#1} }
      }
    
    \NewDocumentCommand \pvalue { m }
    {
      \prg_relation_case_dim:nnn {#1 pt}
       {
        {<= 0.01 pt } { $p \leq 0.01$ }
        {<= 0.02 pt } { $p \leq 0.02$ }
        {<= 0.05 pt } { $p \leq 0.05$ }    
       }
       { $p > 0.05$ }
    }
    \ExplSyntaxOff
    \begin{document}
    \pvalue{.04}
     
     \pvalue{.018}
     
     \pvalue{.0005}
     
    \pvalue{1}
    \end{document}
    Marco

  11. #11
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    @Marco: nice

    Ohne expl3 ginge auch das hier:
    Code:
    \documentclass{article}
    \usepackage{fp}
    
    
    \makeatletter
    \newcommand*\pvalue[1]{%
      \FPset{\pval}{#1}%
      \FPiflt{\pval}{.001}%
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
      {$p<0.001$}%
      {%
        \FPiflt{\pval}{.01}%
          \expandafter\@firstoftwo
        \else
          \expandafter\@secondoftwo
        \fi
        {$p<0.01$}%
        {%
          \FPiflt{\pval}{.05}%
            $p<0.05$%
          \else
            $p =$ n.~s.%
          \fi
        }%
      }%
    }
    \makeatother
    
    \begin{document}
    
     \pvalue{.04}
     
     \pvalue{.005}
     
     \pvalue{.0005}
    
    \end{document}
    Durch \@firstoftwo und \@secondoftwo wird garantiert, dass keine neue if-Abfrage innerhalb einer anderen ausgeführt wird. Damit wird dann auch die »extra fi« Warnung vermieden.

    Gruß
    Clemens

  12. #12
    Registrierter Benutzer
    Registriert seit
    15.03.2012
    Beiträge
    4

    Smile Herzlichen Dank: hier jetzt die erweiterte Funktion

    Danke allen Mithelfenden!
    Anbei für alle, die doktorn:

    Code:
    \documentclass{article}
    
    \usepackage{siunitx}
    \usepackage{expl3}
    
    
    \ExplSyntaxOn
    \newcommand* \pvalue [2][none]
    % erfordert die Eingabe des p-Wertes
    % als optionaler Parameter können 
    %	lessthan	für die Angabe 'p < #2', wenn das Statistikprogramm als Wert '<0,0001' ausgibt und man diesen Wert in der tex-Datei speichern will
    % oder
    %	exact		für die Ausgabe des exakten p-Wertes also z. B.: 'p = 0,0123'
    % oder
    %	aprox		für die Ausgabe einen Nährungswertes mit dem \aprox-Symbol
    % ... verwendet werden.
    % #2 ist das erforderliche Argument, #1 das optionale, das, wenn ungesetzt, 'none' ist	
      {		
    	\str_if_eq:nnTF { #1 } { lessthan }
    		{ p\,$<$\,\num{#2} }
    		{%	
    			\str_if_eq:nnTF { #1 } { exact }
    				{	p\,$=$\,\num{#2} }
    				{	\str_if_eq:nnTF { #1 } { approx }
    					{	p\,$\approx$\,\num{#2} }
    					{ 
    					\fp_compare:nNnTF { #2 } < { .001 }			%nNnTF compares floating numbres = < oder > Ergebnis ist (T)rue oder (F)alse
    						{ p\,$<$\,\num{0.001} }
    						{
    							\fp_compare:nNnTF { #2 } < { .01 }
    							{ p\,$<$\,\num{0.01} }
    							{
    								\fp_compare:nNnTF { #1 } < { .05 }
    								{ p\,$<$\num{0.05} }
    								{ p\,$=$\,~n.~s. }
    							}
    						}
    					}
    			}
    		}
    	
      }
    \ExplSyntaxOff
    
    \begin{document}
    
    \pvalue{0.123}\\
    \pvalue{0.0123}\\
    \pvalue[exact]{0.024413}\\
    \pvalue[approx]{0.0532}\\
    \pvalue[lessthan]{0.003}\\
    \pvalue{0.00123}\\
    \pvalue{0.000123}
    
    \end{document}
    Geändert von texnicker (18-03-2012 um 17:55 Uhr)

  13. #13
    Registrierter Benutzer Avatar von mechanicus
    Registriert seit
    10.07.2008
    Ort
    Hamburg
    Beiträge
    3.944
    Hi,

    nutze in Verbindung mit expl3 nicht newcommand. Entweder die Vorteile von xparse mittels NewDocumentCommand oder cs_new:Npn.

    Marco

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •