Неточность в вычислениях чисел с плавающей точкой с помощью библиотеки fpu

Неточность в вычислениях чисел с плавающей точкой с помощью библиотеки fpu

Итак, я пытаюсь сделать несколько сложных вычислений с LaTeX, и он продолжает выдавать бессмысленный ответ. Я пытаюсь вычислить количество слоев, которыми можно покрыть мяч, учитывая некоторые условия, и LaTeX продолжает выдавать мне отрицательный ответ! После нескольких часов выдергивания волос я смог отследить ошибку, которая показана в MWE ниже

\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}

Проблема в том, что

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

не равно нулю, предположительно из-за ошибок округления. Понятно, что выражение выше должно быть равно нулю, однако этого не происходит. Вместо этого я получаю -1400.0что является полной ерундой. Как мне заставить библиотеку fpu слишком точно вычислять квадратные корни?

введите описание изображения здесь

Мой реальный пример немного сложнее, но он сводится к тому же расчету.

решение1

С xfp я получаю более точный результат:

\documentclass{article}
\usepackage{xfp}

\begin{document}

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

\end{document}

введите описание изображения здесь

решение2

Используйте fpмодуль expl3вместе с некоторым синтаксическим сахаром для переменных, который также гарантирует, что мы не переопределяем существующие команды.

Однако вы не можете этого ожидать (Икс3 ) 1/3 =Икс.

\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}

введите описание изображения здесь

Связанный контент