namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


numerik:ulp
no way to compare when less than two revisions

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


numerik:ulp [2014-12-29 13:50] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Abstand zwischen Gleitkommazahlen ======
 +[[Maschinenzahlen]] haben aufgrund ihres Aufbaus eine begrenzte Auflösung. Der Abstand zwischen zwei benachbarten Gleitkommazahlen wird auf Englisch als unit of least precision (ulp) bezeichnet.
 +Dieser ist abhängig von der Größenordnung der Zahl, ihrem Exponenten. Für exakte Zweierpotenzen wie 0.5, 1, oder 2 differieren der Abstand nach oben und nach unten.
 +
 +Funktionen der Bibliothek von C++ können genutzt werden, um das ulp(x) einer Zahl x zu bestimmen:
 +
 +<code cpp ulp.h>
 +#include <limits>
 +#include <cmath>
 +
 +template <typename T>
 +T ulp_up(T x)
 +{
 +  T infty = std::numeric_limits<T>::infinity();
 +  T above = std::nextafter(x, infty);
 +  return above - x;
 +}
 +
 +template <typename T>
 +T ulp_down(T x)
 +{
 +  T infty = std::numeric_limits<T>::infinity();
 +  T below = std::nextafter(x, -infty);
 +  return x - below;
 +}
 +</code>
 +Die Funktion [[:kennen:lib::nextafter]] behandelt auch Sonderfälle ($\infty$, NaNs), wie ein Probelauf mit dem Programm zeigt:
 +<code cpp ulp.cpp>
 +#include <iostream>
 +#include <iomanip>
 +#include "ulp.h"
 +
 +template <typename T>
 +void show(T x)
 +{
 +  std::cout
 +    << std::setw(14) << x << "\t : " 
 +    << std::setw(14) << ulp_down(x) << " <  > " << ulp_up(x) << '\n';
 +}
 +
 +template <typename T>
 +void ulps(const char * msg)
 +{
 +  std::cout << "\n" << msg << "\n";
 +
 +  auto max = std::numeric_limits<T>::max();
 +  auto min = std::numeric_limits<T>::min();
 +  auto inf = std::numeric_limits<T>::infinity();
 +  show(inf);
 +  show(max);
 +  show(T(2.0));
 +  show(T(1.5));
 +  show(T(1.0));
 +  show(T(0.5));
 +  show(min);
 +  show(T(0.0));
 +  show(-min);
 +  show(T(-0.5));
 +  show(T(-1.0));
 +  show(T(-1.5));
 +  show(T(-2.0));
 +  show(-max);
 +  show(-inf);
 +}
 +
 +int main()
 +{
 +  ulps<double>("double");
 +  return 0;
 +}
 +</code> 
 +Ausgabe:
 +<file>
 +double
 +           inf   :            inf <  > nan
 +  1.79769e+308   :   1.99584e+292 <  > inf
 +               :   2.22045e-016 <  > 4.44089e-016
 +           1.5   :   2.22045e-016 <  > 2.22045e-016
 +               :   1.11022e-016 <  > 2.22045e-016
 +           0.5   :   5.55112e-017 <  > 1.11022e-016
 +  2.22507e-308   :   4.94066e-324 <  > 4.94066e-324
 +               :   4.94066e-324 <  > 4.94066e-324
 + -2.22507e-308   :   4.94066e-324 <  > 4.94066e-324
 +          -0.5   :   1.11022e-016 <  > 5.55112e-017
 +            -1   :   2.22045e-016 <  > 1.11022e-016
 +          -1.5   :   2.22045e-016 <  > 2.22045e-016
 +            -2   :   4.44089e-016 <  > 2.22045e-016
 + -1.79769e+308   :            inf <  > 1.99584e+292
 +          -inf   :            nan <  > inf
 +</file>
  
numerik/ulp.txt · Zuletzt geändert: 2014-12-29 13:50 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki