namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


numerik:ulp

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:

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

Die Funktion nextafter() behandelt auch Sonderfälle ($\infty$, NaNs), wie ein Probelauf mit dem Programm zeigt:

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

Ausgabe:

double
           inf   :            inf <  > nan
  1.79769e+308   :   1.99584e+292 <  > inf
             2   :   2.22045e-016 <  > 4.44089e-016
           1.5   :   2.22045e-016 <  > 2.22045e-016
             1   :   1.11022e-016 <  > 2.22045e-016
           0.5   :   5.55112e-017 <  > 1.11022e-016
  2.22507e-308   :   4.94066e-324 <  > 4.94066e-324
             0   :   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
numerik/ulp.txt · Zuletzt geändert: 2014-12-29 13:50 (Externe Bearbeitung)