In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/217fd77b9ad13cd0604186df640099439adf5f62?hp=cf4f60037a32b53dd09c94455f6d3684f353d717>
- Log ----------------------------------------------------------------- commit 217fd77b9ad13cd0604186df640099439adf5f62 Author: Jarkko Hietaniemi <[email protected]> Date: Sun Aug 17 13:51:01 2014 -0400 Comment tweaks. M sv.c commit b08e1c9b64352c88606f2aa5281fbc88a9be0ed8 Author: Jarkko Hietaniemi <[email protected]> Date: Sun Aug 17 13:50:08 2014 -0400 Little-endian double-double detection was wrong. M Configure commit f7a48a8cf4bd1c2284879545eb4badd8d8c6faae Author: Jarkko Hietaniemi <[email protected]> Date: Sun Aug 17 10:00:06 2014 -0400 Add quadruple precision tests, verified by Craig Berry. Also tentatively adding double-double tests, but those are probably bogus. Also comment tweaks. M sv.c M t/op/sprintf2.t ----------------------------------------------------------------------- Summary of changes: Configure | 5 ++- sv.c | 13 +++--- t/op/sprintf2.t | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 133 insertions(+), 14 deletions(-) diff --git a/Configure b/Configure index 817b515..aab3f03 100755 --- a/Configure +++ b/Configure @@ -16017,8 +16017,9 @@ int main() { #endif #if LDBL_MANT_DIG == 106 && LONGDBLSIZE == 16 /* software "double double", the 106 is 53+53 */ - if (b[0] == 0xCD && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) { - /* double double 128-bit little-endian */ + if (b[0] == 0x9A && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) { + /* double double 128-bit little-endian, + * 9a 99 99 99 99 99 59 3c 9a 99 99 99 99 99 b9 bf */ printf("5\n"); exit(0); } diff --git a/sv.c b/sv.c index 8fe2c7e..44f816b 100644 --- a/sv.c +++ b/sv.c @@ -10603,7 +10603,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) int ix; int ixmin = 0, ixmax = 0; - /* XXX Inf/NaN handling in the HEXTRACT_IMPLICIT_BIT, + /* XXX Inf/NaN/denormal handling in the HEXTRACT_IMPLICIT_BIT, * and elsewhere. */ /* These macros are just to reduce typos, they have multiple @@ -10637,7 +10637,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) # define HEXTRACTSIZE NVSIZE (void)Perl_frexp(PERL_ABS(nv), exponent); # if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN - /* Used in e.g. VMS and HP-UX IA64, e.g. -0.1L: + /* Used in e.g. VMS and HP-UX IA-64, e.g. -0.1L: * 9a 99 99 99 99 99 99 99 99 99 99 99 99 99 fb 3f */ /* The bytes 13..0 are the mantissa/fraction, * the 15,14 are the sign+exponent. */ @@ -10649,7 +10649,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) HEXTRACT_COUNT(); } # elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN - /* Used in e.g. Solaris Sparc and HP-PA HP-UX, e.g. -0.1L: + /* Used in e.g. Solaris Sparc and HP-UX PA-RISC, e.g. -0.1L: * bf fb 99 99 99 99 99 99 99 99 99 99 99 99 99 9a */ /* The bytes 2..15 are the mantissa/fraction, * the 0,1 are the sign+exponent. */ @@ -10664,7 +10664,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) /* x86 80-bit "extended precision", 64 bits of mantissa / fraction / * significand, 15 bits of exponent, 1 bit of sign. NVSIZE can * be either 12 (ILP32, Solaris x86) or 16 (LP64, Linux and OS X), - * meaning that 4 or 6 bytes are empty padding. */ + * meaning that 2 or 6 bytes are empty padding. */ /* The bytes 7..0 are the mantissa/fraction */ /* There explicitly is *no* implicit bit in this case. */ for (ix = 7; ix >= 0; ix--) { @@ -10703,14 +10703,11 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) HEXTRACT_COUNT(); } # elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN - /* Used in e.g. PPC/Power and MIPS. + /* Used in e.g. PPC/Power (AIX) and MIPS. * * The mantissa bits are in two separate stretches, * e.g. for -0.1L: * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a - * as seen in PowerPC AIX, as opposed to "true" 128-bit IEEE 754: - * bf fb 99 99 99 99 99 99 99 99 99 99 99 99 99 9a - * as seen in HP-PA HP-UX. * * Note that this blind copying might be considered not to be * the right thing, since the first double already does diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t index 1de85c2..0969d58 100644 --- a/t/op/sprintf2.t +++ b/t/op/sprintf2.t @@ -21,14 +21,14 @@ print "# nv_preserves_uv_bits = $Config{nv_preserves_uv_bits}\n"; print "# d_quad = $Config{d_quad}\n"; if ($Config{nvsize} == 8 && ( - # IEEE-754, we hope, the most common out there. + # IEEE-754 64-bit ("double precision"), the most common out there ($Config{uvsize} == 8 && $Config{nv_preserves_uv_bits} == 53) || # If we have a quad we can still get the mantissa bits. ($Config{uvsize} == 4 && $Config{d_quad}) ) ) { - @hexfloat = ( + @hexfloat = ( [ '%a', '0', '0x0p+0' ], [ '%a', '1', '0x1p+0' ], [ '%a', '1.0', '0x1p+0' ], @@ -70,13 +70,18 @@ if ($Config{nvsize} == 8 && [ '%030a', '3.14', '0x00000000001.91eb851eb851fp+1' ], [ '%-030a', '3.14', '0x1.91eb851eb851fp+1 ' ], + [ '%.40a', '3.14', + '0x1.91eb851eb851f000000000000000000000000000p+1' ], + [ '%A', '3.14', '0X1.91EB851EB851FP+1' ], ); } elsif (($Config{nvsize} == 16 || $Config{nvsize} == 12) && - # 80-bit long double, pack F is the NV + # 80-bit ("extended precision") long double, pack F is the NV + # cd cc cc cc cc cc cc cc fb bf 00 00 00 00 00 00 + # cd cc cc cc cc cc cc cc fb bf 00 00 (pack("F", 0.1) =~ /^\xCD/ || # LE pack("F", 0.1) =~ /\xCD$/)) { # BE (if this ever happens) - @hexfloat = ( + @hexfloat = ( [ '%a', '0', '0x0p+0' ], [ '%a', '1', '0x8p-3' ], [ '%a', '1.0', '0x8p-3' ], @@ -118,8 +123,124 @@ if ($Config{nvsize} == 8 && [ '%030a', '3.14', '0x00000000c.8f5c28f5c28f5c3p-2' ], [ '%-030a', '3.14', '0xc.8f5c28f5c28f5c3p-2 ' ], + [ '%.40a', '3.14', + '0xc.8f5c28f5c28f5c30000000000000000000000000p-2' ], + [ '%A', '3.14', '0XC.8F5C28F5C28F5C3P-2' ], ); +} elsif ( + # IEEE 754 128-bit ("quadruple precision"), e.g. IA-64 (Itanium) in VMS + $Config{nvsize} == 16 && + # 9a 99 99 99 99 99 99 99 99 99 99 99 99 99 fb 3f (LE), pack F is the NV + # (compare this with "double-double") + (pack("F", 0.1) =~ /^\x9A\x99{6}/ || # LE + pack("F", 0.1) =~ /\x99{6}x9A$/) # BE + ) { + @hexfloat = ( + [ '%a', '0', '0x1p-1' ], + [ '%a', '1', '0x1p+0' ], + [ '%a', '1.0', '0x1p+0' ], + [ '%a', '0.5', '0x1p-1' ], + [ '%a', '0.25', '0x1p-2' ], + [ '%a', '0.75', '0x1.8p-1' ], + [ '%a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%a', '-1', '-0x1p+0' ], + [ '%a', '-3.14', '-0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%a', '0.1', '0x1.999999999999999999999999999ap-4' ], + [ '%a', '1/7', '0x1.2492492492492492492492492492p-3' ], + [ '%a', 'sqrt(2)', '0x1.6a09e667f3bcc908b2fb1366ea95p+0' ], + [ '%a', 'exp(1)', '0x1.5bf0a8b1457695355fb8ac404e7ap+1' ], + [ '%a', '2**-10', '0x1p-10' ], + [ '%a', '2**10', '0x1p+10' ], + [ '%a', '1e-09', '0x1.12e0be826d694b2e62d01511f12ap-30' ], + [ '%a', '1e9', '0x1.dcd65p+29' ], + + [ '%#a', '1', '0x1.p+0' ], + [ '%+a', '1', '+0x1p+0' ], + [ '%+a', '-1', '-0x1p+0' ], + [ '% a', '1', ' 0x1p+0' ], + [ '% a', '-1', '-0x1p+0' ], + + [ '%8a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%13a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%20a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%.4a', '3.14', '0x1.91ecp+1' ], + [ '%.5a', '3.14', '0x1.91eb8p+1' ], + [ '%.6a', '3.14', '0x1.91eb85p+1' ], + [ '%.20a', '3.14', '0x1.91eb851eb851eb851eb8p+1' ], + [ '%20.10a', '3.14', ' 0x1.91eb851eb8p+1' ], + [ '%20.15a', '3.14', '0x1.91eb851eb851eb8p+1' ], + [ '% 20.10a', '3.14', ' 0x1.91eb851eb8p+1' ], + [ '%020.10a', '3.14', '0x0001.91eb851eb8p+1' ], + + [ '%30a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%-30a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%030a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + [ '%-030a', '3.14', '0x1.91eb851eb851eb851eb851eb851fp+1' ], + + [ '%.40a', '3.14', + '0x1.91eb851eb851eb851eb851eb851f000000000000p+1' ], + + [ '%A', '3.14', '0X1.91EB851EB851EB851EB851EB851FP+1' ], + ); +} elsif ( + # "double-double", two 64-bit doubles end to end + $Config{nvsize} == 16 && + # bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a (BE), pack F is the NV + # (compare this with "quadruple precision") + (pack("F", 0.1) =~ /^\x9A\x99{5}\x59\x3C/ || # LE + pack("F", 0.1) =~ /\x3C\x59\x99{5}\x9A$/) # BE + ) { + # XXX these values are probably slightly wrong, even if + # the double-double extraction code gets fixed, the exact + # truncation/rounding effects are unknown. + @hexfloat = ( + [ '%a', '0', '0x1p-1' ], + [ '%a', '1', '0x1p+0' ], + [ '%a', '1.0', '0x1p+0' ], + [ '%a', '0.5', '0x1p-1' ], + [ '%a', '0.25', '0x1p-2' ], + [ '%a', '0.75', '0x1.8p-1' ], + [ '%a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%a', '-1', '-0x1p+0' ], + [ '%a', '-3.14', '-0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%a', '0.1', '0x1.99999999999999999999999999ap-4' ], + [ '%a', '1/7', '0x1.249249249249249249249249249p-3' ], + [ '%a', 'sqrt(2)', '0x1.6a09e667f3bcc908b2fb1366ea9p+0' ], + [ '%a', 'exp(1)', '0x1.5bf0a8b1457695355fb8ac404e8p+1' ], + [ '%a', '2**-10', '0x1p-10' ], + [ '%a', '2**10', '0x1p+10' ], + [ '%a', '1e-09', '0x1.12e0be826d694b2e62d01511f13p-30' ], + [ '%a', '1e9', '0x1.dcd65p+29' ], + + [ '%#a', '1', '0x1.p+0' ], + [ '%+a', '1', '+0x1p+0' ], + [ '%+a', '-1', '-0x1p+0' ], + [ '% a', '1', ' 0x1p+0' ], + [ '% a', '-1', '-0x1p+0' ], + + [ '%8a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%13a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%20a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%.4a', '3.14', '0x1.91ecp+1' ], + [ '%.5a', '3.14', '0x1.91eb8p+1' ], + [ '%.6a', '3.14', '0x1.91eb85p+1' ], + [ '%.20a', '3.14', '0x1.91eb851eb851eb851eb8p+1' ], + [ '%20.10a', '3.14', ' 0x1.91eb851eb8p+1' ], + [ '%20.15a', '3.14', '0x1.91eb851eb851eb8p+1' ], + [ '% 20.10a', '3.14', ' 0x1.91eb851eb8p+1' ], + [ '%020.10a', '3.14', '0x0001.91eb851eb8p+1' ], + + [ '%30a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%-30a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%030a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + [ '%-030a', '3.14', '0x1.91eb851eb851eb851eb851eb852p+1' ], + + [ '%.40a', '3.14', + '0x1.91eb851eb851eb851eb851eb8520000000000000p+1' ], + + [ '%A', '3.14', '0X1.91EB851EB851EB851EB851EB852P+1' ], + ); } else { print "# no hexfloat tests\n"; } -- Perl5 Master Repository
