I'm sure you've moved beyond this... but for future searchers:
While trying to implement some ULP-manipulating routines in my Data::IEEE754::Tools development (which I used to call Expand.pm), I was googling to fix a bug, and was led to Data::Float, which actually has most of the tools I was trying to implement in my module. Using that CPAN module, I was able to write a sub which found the ULP for any finite value (normal or denormal); it returns INF or NAN when one of those was passed.
use warnings; use strict; use feature qw/say/; use Data::Float qw/pow2 float_parts float_hex significand_bits min_normal min_normal_exp min_finite min_finite_exp max_finite pos_zero neg_zero pos_infinity neg_infinity nan float_is_zero float_is_finite/; sub find_ulp($) { my $nv = shift; my $vh = float_hex($nv); if(!float_is_finite($nv)) { # INF or NAN say "ulp($nv:$vh) = $nv:$vh"; return $nv; } my $e = float_is_zero($nv) ? (min_finite_exp) : ( (float_parts($n +v))[1] - significand_bits ); my $uv = pow2($e); my $uh = float_hex($uv); say "ulp($nv:$vh) = $uv:$uh"; return $uv; } find_ulp($_) foreach (2.0, 1.0, 0.5, 0.16, max_finite, min_normal, min +_normal/2., min_finite, pos_zero, neg_zero , pos_infinity , neg_infin +ity , nan); __END__ ulp(2:+0x1.0000000000000p+1) = 4.44089209850063e-016:+0x1.000000000000 +0p-51 ulp(1:+0x1.0000000000000p+0) = 2.22044604925031e-016:+0x1.000000000000 +0p-52 ulp(0.5:+0x1.0000000000000p-1) = 1.11022302462516e-016:+0x1.0000000000 +000p-53 ulp(0.16:+0x1.47ae147ae147bp-3) = 2.77555756156289e-017:+0x1.000000000 +0000p-55 ulp(1.79769313486232e+308:+0x1.fffffffffffffp+1023) = 1.99584030953472 +e+292:+0x1.0000000000000p+971 ulp(2.2250738585072e-308:+0x1.0000000000000p-1022) = 4.94065645841247e +-324:+0x0.0000000000001p-1022 ulp(1.1125369292536e-308:+0x0.8000000000000p-1022) = 4.94065645841247e +-324:+0x0.0000000000001p-1022 ulp(4.94065645841247e-324:+0x0.0000000000001p-1022) = 4.94065645841247 +e-324:+0x0.0000000000001p-1022 ulp(0:+0.0) = 4.94065645841247e-324:+0x0.0000000000001p-1022 ulp(0:-0.0) = 4.94065645841247e-324:+0x0.0000000000001p-1022 ulp(Inf:+inf) = Inf:+inf ulp(-Inf:-inf) = -Inf:-inf ulp(NaN:nan) = NaN:nan
In reply to Re^3: Determining the minimum representable increment/decrement possible?
by pryrt
in thread Determining the minimum representable increment/decrement possible?
by BrowserUk
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |