eval { my $q = pack "q", 0 };
my $Q = $@ eq '';
+my $doubledouble;
+
# %a and %A depend on the floating point config
# This totally doesn't test non-IEEE-754 float formats.
my @hexfloat;
(pack("F", 0.1) =~ /^\x9A\x99{5}\x59\xBC/ || # LE
pack("F", 0.1) =~ /\xBC\x59\x99{5}\x9A$/) # BE
) {
+ $doubledouble = 1;
@hexfloat = (
[ '%a', '0', '0x0p+0' ],
[ '%a', '1', '0x1p+0' ],
print "# no hexfloat tests\n";
}
-plan tests => 1406 + ($Q ? 0 : 12) + @hexfloat;
+plan tests => 1408 + ($Q ? 0 : 12) + @hexfloat + 8;
use strict;
use Config;
}
# Overload count
-package o { use overload '""', sub { ++our $count; $_[0][0]; } }
-my $o = bless ["\x{100}"], o::;
+package o {
+ use overload
+ '""', sub { ++our $count; $_[0][0]; },
+ '0+', sub { ++our $numcount; $_[0][1]; }
+}
+my $o = bless ["\x{100}",42], o::;
() = sprintf "%1s", $o;
is $o::count, '1', 'sprinf %1s overload count';
$o::count = 0;
() = sprintf "%.1s", $o;
is $o::count, '1', 'sprinf %.1s overload count';
+$o::count = 0;
+() = sprintf "%d", $o;
+is $o::count, 0, 'sprintf %d string overload count is 0';
+is $o::numcount, 1, 'sprintf %d number overload count is 1';
+
+my $ppc64_linux = $Config{archname} =~ /^ppc64-linux/;
+my $irix_ld = $Config{archname} =~ /^IP\d+-irix-ld$/;
for my $t (@hexfloat) {
my ($format, $arg, $expected) = @$t;
$arg = eval $arg;
my $result = sprintf($format, $arg);
my $ok = $result eq $expected;
+ if ($doubledouble && $ppc64_linux && $arg =~ /^2.71828/) {
+ # ppc64-linux has buggy exp(1).
+ local $::TODO = "$Config{archname} exp(1)";
+ ok($ok, "'$format' '$arg' -> '$result' cf '$expected'");
+ next;
+ }
+ if ($doubledouble && $irix_ld && $arg =~ /^1.41421/) {
+ # irix has buggy sqrt(2),
+ # last hexdigit one bit error:
+ # gets '0x1.6a09e667f3bcc908b2fb1366eacp+0'
+ # wants '0x1.6a09e667f3bcc908b2fb1366ea8p+0'
+ local $::TODO = "$Config{archname} sqrt(2)";
+ ok($ok, "'$format' '$arg' -> '$result' cf '$expected'");
+ next;
+ }
unless ($ok) {
# It seems that there can be difference in the last bits:
# [perl #122578]
}
ok($ok, "'$format' '$arg' -> '$result' cf '$expected'");
}
+
+# double-double long double %a special testing.
+SKIP: {
+ skip("$^O doublekind=$Config{doublekind}", 6)
+ unless ($Config{doublekind} == 4 && $^O eq 'linux');
+ # [rt.perl.org 125633]
+ like(sprintf("%La\n", (2**1020) + (2**-1072)),
+ qr/^0x1.0{522}1p\+1020$/);
+ like(sprintf("%La\n", (2**1021) + (2**-1072)),
+ qr/^0x1.0{523}8p\+1021$/);
+ like(sprintf("%La\n", (2**1022) + (2**-1072)),
+ qr/^0x1.0{523}4p\+1022$/);
+ like(sprintf("%La\n", (2**1023) + (2**-1072)),
+ qr/^0x1.0{523}2p\+1023$/);
+ like(sprintf("%La\n", (2**1023) + (2**-1073)),
+ qr/^0x1.0{523}1p\+1023$/);
+ like(sprintf("%La\n", (2**1023) + (2**-1074)),
+ qr/^0x1.0{524}8p\+1023$/);
+}
+
+SKIP: {
+ skip("negative zero not available\n", 2)
+ unless sprintf('%+f', -0.0) =~ /^-0/;
+ is(sprintf("%a", -0.0), "-0x0p+0", "negative zero");
+ is(sprintf("%+a", -0.0), "-0x0p+0", "negative zero");
+}