Ungenauigkeit bei der Berechnung von Gleitkommazahlen mit der FPU-Bibliothek

Ungenauigkeit bei der Berechnung von Gleitkommazahlen mit der FPU-Bibliothek

Ich versuche also, einige etwas komplizierte Berechnungen mit LaTeX durchzuführen, und es spuckt immer eine unsinnige Antwort aus. Ich versuche, die Anzahl der Schichten zu berechnen, mit denen man einen Ball unter bestimmten Bedingungen bedecken könnte, und LaTeX gibt mir immer eine negative Antwort! Nachdem ich mir stundenlang die Haare gerauft hatte, konnte ich den Fehler aufspüren, der im MWE unten angezeigt wird

\documentclass[border=1mm]{article}
\usepackage[utf8]{inputenc}

\usepackage{mathtools}
\usepackage{pgfplots}

\begin{document}

\pgfmathsetmacro{\earthRadiusKm}{6371} 
\pgfmathsetmacro{\coinRadiusM}{1.05 / 1000} 
\pgfmathsetmacro{\coinHeightM}{1.7 / 1000} 

\pgfkeys{/pgf/fpu, /pgf/fpu/output format=fixed}

\pgfmathsetmacro{\coinsTotalHeight}{3.27*10^17} 

\pgfmathsetmacro{\earthRadiusM}{6371*1000} 

\pgfmathsetmacro{\radiusCoinsLayerCubedMtest}{%
(\earthRadiusM^3)^(1/3) - \earthRadiusM}

\pgfmathsetmacro{\R}{
((\earthRadiusM)^3 + 1.5 * (\coinRadiusM) * (\coinsTotalHeight))^(1/3)
}

\pgfmathsetmacro{\layers}{
(\R - \earthRadiusM)/(\coinHeightM)
}

\pgfkeys{/pgf/fpu=false}

$\sqrt{(R_\oplus^3)^{1/3} - R_\oplus}$ equals $0$ not \radiusCoinsLayerCubedMtest !

The radius is
\begin{align*}
    R = \sqrt[3]{R_\oplus^3 + \frac{3}{2}r_m h_c}
    \approx
    \R
\end{align*}
%
Which means that the total number of layers are
%
\begin{align*}
    n &= \frac{R - R_\oplus}{h_m} \\
      &\approx \frac{\R - \earthRadiusM}{\coinHeightM}
      \approx \layers
\end{align*}
\end{document}

Das Problem ist, dass

(something^3)^(1/3) - something

ist nicht gleich Null, vermutlich aufgrund von Rundungsfehlern. Es ist klar, dass der obige Ausdruck Null ergeben sollte, aber das tut er nicht. Stattdessen erhalte ich, -1400.0was völliger Unsinn ist. Wie kann ich die FPU-Bibliothek dazu bringen, Quadratwurzeln so genau zu berechnen?

Bildbeschreibung hier eingeben

Mein eigentliches Beispiel ist etwas komplizierter, aber im Endeffekt läuft es auf die gleiche Berechnung hinaus.

Antwort1

Mit xfp erhalte ich ein genaueres Ergebnis:

\documentclass{article}
\usepackage{xfp}

\begin{document}

\fpeval{((6371*1000)^(1/3))^3 - 6371*1000}

\end{document}

Bildbeschreibung hier eingeben

Antwort2

Verwenden Sie das fpModul expl3zusammen mit etwas syntaktischem Zucker für Variablen, der auch sicherstellt, dass wir vorhandene Befehle nicht neu definieren.

Man kann jedoch nicht erwarten, dass (X3 ) 1/3 =X.

\documentclass{article}

\usepackage{mathtools,xfp}

\ExplSyntaxOn

\NewDocumentCommand{\setfpvar}{mm}
 {
  \fp_zero_new:c { nebu_var_#1_fp }
  \fp_set:cn { nebu_var_#1_fp } { #2 }
 }
\NewExpandableDocumentCommand{\fpvar}{m}
 {
  \fp_use:c { nebu_var_#1_fp }
 }

\ExplSyntaxOff

\begin{document}

\setfpvar{earthRadiusKm}{6371} 
\setfpvar{coinRadiusM}{1.05 / 1000} 
\setfpvar{coinHeightM}{1.7 / 1000} 
\setfpvar{coinsTotalHeight}{3.27*10^17} 

\setfpvar{earthRadiusM}{6371*1000} 
\setfpvar{radiusCoinsLayerCubedMtest}{
  (\fpvar{earthRadiusM}^3)^(1/3) - \fpvar{earthRadiusM}
}

\setfpvar{R}{
  ((\fpvar{earthRadiusM})^3 + 1.5 * (\fpvar{coinRadiusM}) * (\fpvar{coinsTotalHeight}))^(1/3)
}

\setfpvar{layers}{
  (\fpvar{R} - \fpvar{earthRadiusM})/(\fpvar{coinHeightM})
}

$\sqrt{(R_\oplus^3)^{1/3} - R_\oplus}$ equals
$\fpvar{radiusCoinsLayerCubedMtest}$

\bigskip

The radius is
\begin{align*}
    R = \sqrt[3]{R_\oplus^3 + \frac{3}{2}r_m h_c}
    \approx
    \fpvar{R}
\end{align*}
which means that the total number of layers is
\begin{align*}
    n &= \frac{R - R_\oplus}{h_m} \\
      &\approx \frac{\fpvar{R} - \fpvar{earthRadiusM}}{\fpvar{coinHeightM}}
      \approx \fpvar{layers}
\end{align*}

\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen