summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2016-08-12 17:36:58 -0400
committerSteve Hay <steve.m.hay@googlemail.com>2017-08-09 13:23:18 +0100
commit79314a4f38d4e66f5f4f7abf4726748163c07c90 (patch)
tree9f369b1154dc97785f523591e6d1dcafaf239d2a
parent3d1a8d12c01c9ebed0c52169733b593180901b7a (diff)
downloadperl-79314a4f38d4e66f5f4f7abf4726748163c07c90.tar.gz
[rt.perl.org #128909] printf %a mishandles exponent-crossing rounding with long double
(cherry picked from commit ee58923a8531731f8acb98ab130abf41f75ebdc7)
-rw-r--r--sv.c6
-rw-r--r--t/op/sprintf2.t9
2 files changed, 11 insertions, 4 deletions
diff --git a/sv.c b/sv.c
index 69ff4aa06a..2dd0b7a54a 100644
--- a/sv.c
+++ b/sv.c
@@ -12557,12 +12557,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
break;
}
}
- if (v == v0 && overflow) {
+ if (v == v0 - 1 && overflow) {
/* If the overflow goes all the
* way to the front, we need to
- * insert 0x1 in front. */
+ * insert 0x1 in front, and adjust
+ * the argument. */
Move(v0, v0 + 1, vn, char);
*v0 = 0x1;
+ exponent += 4;
}
}
diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t
index 6acbccf847..bbc53d1d89 100644
--- a/t/op/sprintf2.t
+++ b/t/op/sprintf2.t
@@ -839,9 +839,9 @@ SKIP: {
}
# x86 80-bit long-double tests for
-# rt.perl.org #128843, #128888, #128889, #128890, #128893
+# rt.perl.org #128843, #128888, #128889, #128890, #128893, #128909
SKIP: {
- skip("non-80-bit-long-double", 7)
+ skip("non-80-bit-long-double", 12)
unless ($Config{uselongdouble} &&
($Config{nvsize} == 16 || $Config{nvsize} == 12) &&
($Config{longdblkind} == 3 ||
@@ -854,6 +854,11 @@ SKIP: {
is(sprintf("%020a", -1.5), "-0x0000000000000cp-3", "[rt.perl.org #128893]");
is(sprintf("%+020a", 1.5), "+0x0000000000000cp-3", "[rt.perl.org #128893]");
is(sprintf("% 020a", 1.5), " 0x0000000000000cp-3", "[rt.perl.org #128893]");
+ is(sprintf("%a", 1.9999999999999999999), "0xf.fffffffffffffffp-3");
+ is(sprintf("%.3a", 1.9999999999999999999), "0x1.000p+1", "[rt.perl.org #128909]");
+ is(sprintf("%.2a", 1.9999999999999999999), "0x1.00p+1");
+ is(sprintf("%.1a", 1.9999999999999999999), "0x1.0p+1");
+ is(sprintf("%.0a", 1.9999999999999999999), "0x1p+1");
}
done_testing();