use warnings; use strict; use Data::IEEE754::Tools 0.016 qw/:all/; use Math::MPFR qw/:mpfr/; use POSIX qw/floor ceil log10 log2/; Rmpfr_set_default_prec(1000); # easy to come up with one that takes many digits to express: my $x = nextUp( POS_NORM_SMALLEST() ); print "POS_NORM_SMALLEST = 2**-1022\n"; print "POS_NORM_SMALLEST+1ULP = (1 + 2**-52)*(2**-1022)\n"; print "\n"; print "( 1 ) \n"; print "(1 + -----)*(2**-1022)\n"; print "( 2**52) \n"; print "\n"; printf "IEEE754 Hex String: '%s'\n", hexstr754_from_double($x); printf "%-30a %-30s %-30s\n", $x, to_hex_floatingpoint($x), to_dec_floatingpoint($x); my $s=Math::MPFR->new($x); printf "[%d digits long]: %s\n", length($s)-6, $s; my $d = ceil(-log10($x)); # start digit printf "For _FIXED POINT_ notation,\n"; printf "\tstarts %d digits after the decimal point\n", $d; my $ulp = ulp($x); # value of last bit (whether or not it is set) printf "long version of ulp: %s\n", Math::MPFR->new($ulp); my $l2 = log2($ulp); printf "log2(ulp) = %d, so I expect it to fit within %d digits of the fixed decimal point\n", $l2, -$l2; #### __OUTPUT__ POS_NORM_SMALLEST = 2**-1022 POS_NORM_SMALLEST+1ULP = (1 + 2**-52)*(2**-1022) ( 1 ) (1 + -----)*(2**-1022) ( 2**52) IEEE754 Hex String: '0010000000000001' 0x1.0000000000001p-1022 +0x1.0000000000001p-1022 +0d1.0000000000000002p-1022 [303 digits long]: 2.22507385850720187715587855857894824078800884868370419561313003121196886039960069652979042922126288586390370136702819080171712960727119103551272274131751521990557400431388045678032333775398816391773873289592460742292701130780538133970816533612964474495297895212189790907838525833659018517896187998851504e-308 For _FIXED POINT_ notation, starts 308 digits after the decimal point