In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/2bb3725dfe9edb3ec056dbc691826cda14d85a48?hp=db8b8c75c9ae410a0e47828e501550fa4f47e811>

- Log -----------------------------------------------------------------
commit 2bb3725dfe9edb3ec056dbc691826cda14d85a48
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Tue Aug 19 18:44:30 2014 -0400

    Add todo comment about special hexfp values.

M       sv.c

commit 6094cb95350921efd1cc9550c3c5dfedefa580cb
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Tue Aug 19 22:16:54 2014 -0400

    Quadruple float BE test triggering had a typo.

M       t/op/sprintf2.t

commit 0096dfabfd24cd5a57ff81d61186b2ffc50dbb6d
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Mon Aug 18 12:56:51 2014 -0400

    Reduce double-double %a to single-double for now.
    
    How to exactly handle the second double is unknown, so for
    now extract the mantissa bits only from the first double.
    (Known platforms aix-ppc and linux-ppc.)

M       sv.c
M       t/op/sprintf2.t

commit 288741806892d643315f5aac944e9ca60aad2171
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Mon Aug 18 17:04:06 2014 -0400

    double-double needs the first mantissa bits of doubles.

M       sv.c

commit e85ae363ea55e756d30efca06216f575419e9b9c
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Mon Aug 18 15:27:58 2014 -0400

    Modify the hexfp exponent explicitly in each long double case.

M       sv.c

commit 08780b356b3dfd25eb8df7d19c3f4af4a3511cb6
Author: Jarkko Hietaniemi <j...@iki.fi>
Date:   Mon Aug 18 08:13:18 2014 -0400

    Comment: scan_num also handles hexadecimal floats now.

M       toke.c
-----------------------------------------------------------------------

Summary of changes:
 sv.c            | 119 ++++++++++++++++++++++++++++++++++++--------------------
 t/op/sprintf2.t |  52 ++++++++++++-------------
 toke.c          |   7 ++--
 3 files changed, 106 insertions(+), 72 deletions(-)

diff --git a/sv.c b/sv.c
index 44f816b..92c34a8 100644
--- a/sv.c
+++ b/sv.c
@@ -10610,14 +10610,16 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* 
vhex, U8* vend)
      * repetitions below, but usually only one (or sometimes two)
      * of them is really being used. */
     /* HEXTRACT_OUTPUT() extracts the high nybble first. */
-#define HEXTRACT_OUTPUT() \
+#define HEXTRACT_OUTPUT_HI(ix) (*v++ = nvp[ix] >> 4)
+#define HEXTRACT_OUTPUT_LO(ix) (*v++ = nvp[ix] & 0xF)
+#define HEXTRACT_OUTPUT(ix) \
     STMT_START { \
-      *v++ = nvp[ix] >> 4; \
-      *v++ = nvp[ix] & 0xF; \
+        HEXTRACT_OUTPUT_HI(ix); \
+        HEXTRACT_OUTPUT_LO(ix); \
     } STMT_END
-#define HEXTRACT_COUNT() \
+#define HEXTRACT_COUNT(ix, c) \
     STMT_START { \
-      v += 2; \
+      v += c; \
       if (ix < ixmin) \
         ixmin = ix; \
       else if (ix > ixmax) \
@@ -10644,10 +10646,11 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* 
vhex, U8* vend)
     HEXTRACT_IMPLICIT_BIT();
     for (ix = 13; ix >= 0; ix--) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+    *exponent -= 4;
 #  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
     /* 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 */
@@ -10656,10 +10659,11 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* 
vhex, U8* vend)
     HEXTRACT_IMPLICIT_BIT();
     for (ix = 2; ix <= 15; ix++) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+    *exponent -= 4;
 #  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
     /* x86 80-bit "extended precision", 64 bits of mantissa / fraction /
      * significand, 15 bits of exponent, 1 bit of sign.  NVSIZE can
@@ -10669,64 +10673,86 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* 
vhex, U8* vend)
     /* There explicitly is *no* implicit bit in this case. */
     for (ix = 7; ix >= 0; ix--) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+    *exponent -= 4;
 #  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
     /* The last 8 bytes are the mantissa/fraction.
      * (does this format ever happen?) */
     /* There explicitly is *no* implicit bit in this case. */
     for (ix = LONGDBLSIZE - 8; ix < LONGDBLSIZE; ix++) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+    *exponent -= 4;
 #  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
     /* Where is this used?
-     *
-     * Guessing that the format would be the reverse
-     * of big endian, i.e. for -0.1L:
-     * 9a 99 99 99 99 99 59 3c 9a 99 99 99 99 99 b9 bf */
+     * 9a 99 99 99 99 99 59 bc 9a 99 99 99 99 99 b9 3f */
     HEXTRACT_IMPLICIT_BIT();
+    if (vend)
+        HEXTRACT_OUTPUT_LO(14);
+    else
+        HEXTRACT_COUNT(14, 1);
     for (ix = 13; ix >= 8; ix--) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+    /* XXX not extracting from the second double -- see the discussion
+     * below for the big endian double double. */
+#    if 0
+    if (vend)
+        HEXTRACT_OUTPUT_LO(6);
+    else
+        HEXTRACT_COUNT(6, 1);
     for (ix = 5; ix >= 0; ix--) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+#    endif
+    (*exponent)--;
 #  elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
     /* 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
-     *
-     * Note that this blind copying might be considered not to be
-     * the right thing, since the first double already does
-     * rounding (0x9A as opposed to 0x99).  But then again, we
-     * probably should just copy the bits as they are?
+     * The mantissa bits are in two separate stretches, e.g. for -0.1L:
+     * 3f b9 99 99 99 99 99 9a bc 59 99 99 99 99 99 9a
      */
     HEXTRACT_IMPLICIT_BIT();
+    if (vend)
+        HEXTRACT_OUTPUT_LO(1);
+    else
+        HEXTRACT_COUNT(1, 1);
     for (ix = 2; ix < 8; ix++) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
-    }
+            HEXTRACT_COUNT(ix, 2);
+    }
+    /* XXX not extracting the second double mantissa bits- this is not
+     * right nor ideal (we effectively reduce the output format to
+     * that of a "single double", only 53 bits), but we do not know
+     * exactly how to do the extraction correctly so that it matches
+     * the semantics of, say, the IEEE quadruple float. */
+#    if 0
+    if (vend)
+        HEXTRACT_OUTPUT_LO(9);
+    else
+        HEXTRACT_COUNT(9, 1);
     for (ix = 10; ix < 16; ix++) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
+#   endif
+    (*exponent)--;
 #  else
     Perl_croak(aTHX_
                "Hexadecimal float: unsupported long double format");
@@ -10777,17 +10803,17 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* 
vhex, U8* vend)
     /* Little endian. */
     for (ix = limit_byte; ix >= 0; ix--) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
 #  else
     /* Big endian. */
     for (ix = MANTISSASIZE - 1 - limit_byte; ix < MANTISSASIZE; ix++) {
         if (vend)
-            HEXTRACT_OUTPUT();
+            HEXTRACT_OUTPUT(ix);
         else
-            HEXTRACT_COUNT();
+            HEXTRACT_COUNT(ix, 2);
     }
 #  endif
     /* If there are not enough bits in MANTISSATYPE, we couldn't get
@@ -11825,7 +11851,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char 
*const pat, const STRLEN p
                  * human-readable xdigits. */
                 const char* xdig = PL_hexdigit;
                 int zerotail = 0; /* how many extra zeros to append */
-                int exponent; /* exponent of the floating point input */
+                int exponent = 0; /* exponent of the floating point input */
+
+                /* XXX: denormals, NaN, Inf.
+                 *
+                 * For example with denormals, (assuming the vanilla
+                 * 64-bit double): the exponent is zero. 1xp-1074 is
+                 * the smallest denormal and the smallest double, it
+                 * should be output as 0x0.0000000000001p-1022 to
+                 * match its internal structure. */
 
                 vend = S_hextract(aTHX_ nv, &exponent, vhex, NULL);
                 S_hextract(aTHX_ nv, &exponent, vhex, vend);
@@ -11862,9 +11896,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char 
*const pat, const STRLEN p
                         }
                     }
 
-                    /* Adjust the exponent so that the first output
-                     * xdigit aligns with the 4-bit nybbles. */
-                    exponent -= NV_MANT_DIG % 4 ? NV_MANT_DIG % 4 : 4;
+#if NVSIZE == DOUBLESIZE
+                    /* For long doubles S_hextract() took care of this. */
+                    exponent--;
+#endif
 
                     if (precis > 0) {
                         v = vhex + precis + 1;
diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t
index 0969d58..4969abf 100644
--- a/t/op/sprintf2.t
+++ b/t/op/sprintf2.t
@@ -132,9 +132,8 @@ if ($Config{nvsize} == 8 &&
     # 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
+     pack("F", 0.1) =~ /\x99{6}\x9A$/)    # BE
     ) {
     @hexfloat = (
        [ '%a', '0',       '0x1p-1' ],
@@ -186,14 +185,13 @@ if ($Config{nvsize} == 8 &&
 } 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
+    # bf b9 99 99 99 99 99 9a bc 59 99 99 99 99 99 9a (BE), pack F is the NV
+    (pack("F", 0.1) =~ /^\x9A\x99{5}\x59\xBC/ ||  # LE
+     pack("F", 0.1) =~ /\xBC\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.
+    # XXX these values are actually only "single-double" since
+    # we currently do not know how to exactly handle the second
+    # double.  See the discussion in sv.c:S_hextract().
     @hexfloat = (
        [ '%a', '0',       '0x1p-1' ],
        [ '%a', '1',       '0x1p+0' ],
@@ -201,16 +199,16 @@ if ($Config{nvsize} == 8 &&
        [ '%a', '0.5',     '0x1p-1' ],
        [ '%a', '0.25',    '0x1p-2' ],
        [ '%a', '0.75',    '0x1.8p-1' ],
-       [ '%a', '3.14',    '0x1.91eb851eb851eb851eb851eb852p+1' ],
+       [ '%a', '3.14',    '0x1.91eb851eb851fp+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', '-3.14',   '-0x1.91eb851eb851fp+1' ],
+       [ '%a', '0.1',     '0x1.999999999999ap-4' ],
+       [ '%a', '1/7',     '0x1.2492492492492p-3' ],
+       [ '%a', 'sqrt(2)', '0x1.6a09e661366ebp+0' ],
+       [ '%a', 'exp(1)',  '0x1.5bf0a8b145769p+1' ],
        [ '%a', '2**-10',  '0x1p-10' ],
        [ '%a', '2**10',   '0x1p+10' ],
-       [ '%a', '1e-09',   '0x1.12e0be826d694b2e62d01511f13p-30' ],
+       [ '%a', '1e-09',   '0x1.12e0be826d695p-30' ],
        [ '%a', '1e9',     '0x1.dcd65p+29' ],
 
        [ '%#a', '1',      '0x1.p+0' ],
@@ -219,27 +217,27 @@ if ($Config{nvsize} == 8 &&
        [ '% 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' ],
+       [ '%8a',      '3.14', '0x1.91eb851eb851fp+1' ],
+       [ '%13a',     '3.14', '0x1.91eb851eb851fp+1' ],
+       [ '%20a',     '3.14', '0x1.91eb851eb851fp+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' ],
+        [ '%.20a',    '3.14',   '0x1.91eb851eb851f0000000p+1' ],
        [ '%20.10a',  '3.14', '   0x1.91eb851eb8p+1' ],
-       [ '%20.15a',  '3.14', '0x1.91eb851eb851eb8p+1' ],
+        [ '%20.15a',  '3.14',   '0x1.91eb851eb851f00p+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' ],
+        [ '%30a',  '3.14',   '          0x1.91eb851eb851fp+1' ],
+        [ '%-30a', '3.14',   '0x1.91eb851eb851fp+1          ' ],
+        [ '%030a',  '3.14',  '0x00000000001.91eb851eb851fp+1' ],
+        [ '%-030a', '3.14',  '0x1.91eb851eb851fp+1          ' ],
 
         [ '%.40a',  '3.14',
-          '0x1.91eb851eb851eb851eb851eb8520000000000000p+1' ],
+          '0x1.91eb851eb851f000000000000000000000000000p+1' ],
 
-       [ '%A',       '3.14', '0X1.91EB851EB851EB851EB851EB852P+1' ],
+       [ '%A',       '3.14', '0X1.91EB851EB851FP+1' ],
         );
 } else {
     print "# no hexfloat tests\n";
diff --git a/toke.c b/toke.c
index 0f0641f..be4c8a5 100644
--- a/toke.c
+++ b/toke.c
@@ -9781,9 +9781,10 @@ S_scan_str(pTHX_ char *start, int keep_bracketed_quoted, 
int keep_delims, int re
 
   \d(_?\d)*(\.(\d(_?\d)*)?)?[Ee][\+\-]?(\d(_?\d)*)     12 12.34 12.
   \.\d(_?\d)*[Ee][\+\-]?(\d(_?\d)*)                    .34
-  0b[01](_?[01])*
-  0[0-7](_?[0-7])*
-  0x[0-9A-Fa-f](_?[0-9A-Fa-f])*
+  0b[01](_?[01])*                                       binary integers
+  0[0-7](_?[0-7])*                                      octal integers
+  0x[0-9A-Fa-f](_?[0-9A-Fa-f])*                         hexadecimal integers
+  0x[0-9A-Fa-f](_?[0-9A-Fa-f])*(?:\.\d*)?p[+-]?[0-9]+   hexadecimal floats
 
   Like most scan_ routines, it uses the PL_tokenbuf buffer to hold the
   thing it reads.

--
Perl5 Master Repository

Reply via email to