Enhed sidst - Unit in the last place

Inden for datalogi og numerisk analyse er enhed på det sidste sted eller enhed med mindst præcision ( ulp ) afstanden mellem to på hinanden følgende floating-point tal, dvs. værdien det mindst signifikante ciffer (højre ciffer) repræsenterer, hvis det er 1. Det bruges som et mål for nøjagtighed i numeriske beregninger.

Definition

En definition er: I radix med præcision , hvis , så .

En anden definition, foreslået af John Harrison, er en smule anderledes: er afstanden mellem de to nærmeste grænsende floating-point tal og (dvs. dem med og ), forudsat at eksponentområdet ikke er overgrænset. Disse definitioner adskiller sig kun ved radixens underskrevne beføjelser.

The IEEE 754 specifikationsbaserede efterfulgt af alle moderne floating-point hardware-kræver, at resultatet af en elementær aritmetisk operation (addition, subtraktion, multiplikation, division, og kvadratroden siden 1985, og FMA 2008-) være korrekt afrundet , hvilket indebærer, at i afrunding til nærmeste er det afrundede resultat inden for 0,5 ulp af det matematisk nøjagtige resultat ved hjælp af John Harrisons definition; omvendt indebærer denne egenskab, at afstanden mellem det afrundede resultat og det matematisk nøjagtige resultat minimeres (men for halvvejs-tilfældene tilfredsstilles det med to på hinanden følgende flydende tal). Anerkendte numeriske biblioteker beregner de grundlæggende transcendentale funktioner til mellem 0,5 og ca. 1 ulp. Kun få biblioteker beregner dem inden for 0,5 ulp, da dette problem er komplekst på grund af tabellagerens dilemma .

Eksempler

Eksempel 1

Lad være et positivt flydende tal, og antag, at den aktive afrundingstilstand er rund til nærmeste, er knyttet til lige , betegnet . Hvis , så . Ellers eller afhængigt af værdien af ​​det mindst betydende ciffer og eksponenten for . Dette demonstreres i følgende Haskell -kode, der er skrevet ved en interaktiv prompt:

> until (\x -> x == x+1) (+1) 0 :: Float
1.6777216e7
> it-1
1.6777215e7
> it+1
1.6777216e7

Her starter vi med 0 i enkelt præcision og tilføjer gentagne gange 1, indtil operationen ikke ændrer værdien. Da betydningen for et enkeltpræcisionstal indeholder 24 bit, er det første heltal, der ikke ligefrem kan repræsenteres, 2 24 +1, og denne værdi afrundes til 2 24 i runde til nærmeste, knytter sig til lige. Resultatet er således 2 24 .

Eksempel 2

Det følgende eksempel i Java tilnærmer π som et decimaltalsværdi ved at finde de to dobbelte værdier bracketing : .

// π with 20 decimal digits
BigDecimal π = new BigDecimal("3.14159265358979323846");

// truncate to a double floating point
double p0 = π.doubleValue();
// -> 3.141592653589793  (hex: 0x1.921fb54442d18p1)

// p0 is smaller than π, so find next number representable as double
double p1 = Math.nextUp(p0);
// -> 3.1415926535897936 (hex: 0x1.921fb54442d19p1)

Derefter bestemmes som .

// ulp(π) is the difference between p1 and p0
BigDecimal ulp = new BigDecimal(p1).subtract(new BigDecimal(p0));
// -> 4.44089209850062616169452667236328125E-16
// (this is precisely 2**(-51))

// same result when using the standard library function
double ulpMath = Math.ulp(p0);
// -> 4.440892098500626E-16 (hex: 0x1.0p-51)

Eksempel 3

Et andet eksempel i Python , der også er skrevet ved en interaktiv prompt, er:

>>> x = 1.0
>>> p = 0
>>> while x != x + 1:
...   x = x * 2
...   p = p + 1
... 
>>> x
9007199254740992.0
>>> p
53
>>> x + 2 + 1
9007199254740996.0

I dette tilfælde starter vi med x = 1og gentagne gange fordobler det indtil x = x + 1. På samme måde som i eksempel 1 er resultatet 2 53, fordi formatet med dobbelt præcision flydende punkt bruger en 53-bit signifikant.

Sprogstøtte

Den Boost C ++ biblioteker tilbyder funktioner boost::math::float_next, boost::math::float_prior, boost::math::nextafter og boost::math::float_advancefor at opnå i nærheden (og fjernt) flydende værdier, og boost::math::float_distance(a, b)at beregne floating-point afstanden mellem to fordobles.

Den C-sprog biblioteket indeholder funktioner til at beregne den næste floating-point-tal i en given retning: nextafterfog nexttowardffor float, nextafterog nexttowardfor double, nextafterlog nexttowardlfor long double, erklæret i <math.h>. Det giver også makroer FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON, som repræsenterer den positive difference mellem 1,0 og den næste større repræsenterbare tal i den tilsvarende type (dvs. ulp af en).

Den Java standard biblioteket giver funktionerne Math.ulp(double)og Math.ulp(float). De blev introduceret med Java 1.5.

Den Swift standard biblioteket giver adgang til næste decimaltal i en given retning via instans egenskaber nextDownog nextUp. Det giver også instansegenskaben ulpog typeegenskaben ulpOfOne(som svarer til C-makroer som FLT_EPSILON) for Swifts floating-point-typer.

Se også

Referencer

Bibliografi