namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


numerik:ulp

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

numerik:ulp [2014-12-29 13:50] (aktuell)
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 ​  : ​  ​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
 +</​file>​
  
numerik/ulp.txt · Zuletzt geändert: 2014-12-29 13:50 (Externe Bearbeitung)