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
* 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) \
# 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. */
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-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. */
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
* 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--) {
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);
}
+ 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);
}
+ (*exponent)--;
# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
- /* Used in e.g. PPC/Power 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.
+ /* Used in e.g. PPC/Power (AIX) and MIPS.
*
- * 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);
}
+ 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);
}
+ (*exponent)--;
# else
Perl_croak(aTHX_
"Hexadecimal float: unsupported long double format");
/* 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
* 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 */
vend = S_hextract(aTHX_ nv, &exponent, vhex, NULL);
S_hextract(aTHX_ nv, &exponent, vhex, vend);
}
}
- /* 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;