184 lines
6.1 KiB
Diff
184 lines
6.1 KiB
Diff
From 441f53eb116a003c78acad32f133b16f2f4c0814 Mon Sep 17 00:00:00 2001
|
|
From: Peter John Acklam <pjacklam@gmail.com>
|
|
Date: Wed, 6 Jul 2022 13:11:15 +0200
|
|
Subject: [PATCH] Instance methods should return instance variables
|
|
|
|
- When accuracy() and precision() are used as instance methods, they
|
|
should return the instance variables, not the class variables.
|
|
|
|
- New instances should get the accuracy/precision from the class
|
|
variables, not from other instances. The only exception is for
|
|
instances created with copy().
|
|
|
|
- Adjust a few existing tests, and add more tests to confirm behaviour.
|
|
---
|
|
lib/Math/BigFloat.pm | 8 ++---
|
|
lib/Math/BigInt.pm | 4 +--
|
|
t/mbimbf.t | 71 +++++++++++++++++++++++++++++++++++-------
|
|
xt/author/sparts-mbf.t | 4 +--
|
|
4 files changed, 65 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm
|
|
index 6800f62..0fabbee 100644
|
|
--- a/lib/Math/BigFloat.pm
|
|
+++ b/lib/Math/BigFloat.pm
|
|
@@ -4394,17 +4394,13 @@ sub sparts {
|
|
|
|
# Finite number.
|
|
|
|
- my $mant = $x -> copy();
|
|
+ my $mant = $class -> new($x);
|
|
$mant->{_es} = '+';
|
|
$mant->{_e} = $LIB->_zero();
|
|
$mant = $downgrade -> new($mant) if defined $downgrade;
|
|
return $mant unless wantarray;
|
|
|
|
- my $expo = bless { sign => $x -> {_es},
|
|
- _m => $LIB->_copy($x -> {_e}),
|
|
- _es => '+',
|
|
- _e => $LIB->_zero(),
|
|
- }, $class;
|
|
+ my $expo = $class -> new($x -> {_es} . $LIB->_str($x -> {_e}));
|
|
$expo = $downgrade -> new($expo) if defined $downgrade;
|
|
return ($mant, $expo);
|
|
}
|
|
diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm
|
|
index c355c7a..c2dfe7c 100644
|
|
--- a/lib/Math/BigInt.pm
|
|
+++ b/lib/Math/BigInt.pm
|
|
@@ -377,7 +377,7 @@ sub accuracy {
|
|
}
|
|
|
|
# Return instance variable.
|
|
- return $x->{_a} if ref($x) && (defined($x->{_a}) || defined($x->{_p}));
|
|
+ return $x->{_a} if ref($x);
|
|
|
|
# Return class variable.
|
|
return ${"${class}::accuracy"};
|
|
@@ -420,7 +420,7 @@ sub precision {
|
|
}
|
|
|
|
# Return instance variable.
|
|
- return $x->{_p} if ref($x) && (defined($x->{_a}) || defined($x->{_p}));
|
|
+ return $x->{_p} if ref($x);
|
|
|
|
# Return class variable.
|
|
return ${"${class}::precision"};
|
|
diff --git a/t/mbimbf.t b/t/mbimbf.t
|
|
index 23599dd..064ca36 100644
|
|
--- a/t/mbimbf.t
|
|
+++ b/t/mbimbf.t
|
|
@@ -7,7 +7,7 @@ use strict;
|
|
use warnings;
|
|
|
|
use Test::More tests => 712 # tests in require'd file
|
|
- + 26; # tests in this file
|
|
+ + 52; # tests in this file
|
|
|
|
use Math::BigInt only => 'Calc';
|
|
use Math::BigFloat;
|
|
@@ -58,24 +58,71 @@ foreach my $class (qw/Math::BigInt Math::BigFloat/) {
|
|
}
|
|
|
|
foreach my $class (qw/Math::BigInt Math::BigFloat/) {
|
|
- $class->accuracy(42);
|
|
+ my $x;
|
|
|
|
- # $x gets A of 42, too!
|
|
- my $x = $class->new(123);
|
|
+ # Accuracy
|
|
|
|
- # really?
|
|
- is($x->accuracy(), 42, '$x has A of 42');
|
|
+ # set and check the class accuracy
|
|
+ $class->accuracy(1);
|
|
+ is($class->accuracy(), 1, "$class has A of 1");
|
|
|
|
- # $x has no A, but the global is still in effect for $x so the return value
|
|
- # of that operation should be 42, not undef
|
|
- is($x->accuracy(undef), 42, '$x has A from global');
|
|
+ # a new instance gets the class accuracy
|
|
+ $x = $class->new(123);
|
|
+ is($x->accuracy(), 1, '$x has A of 1');
|
|
|
|
- # so $x should still have A = 42
|
|
- is($x->accuracy(), 42, '$x has still A of 42');
|
|
+ # set and check the instance accuracy
|
|
+ $x->accuracy(2);
|
|
+ is($x->accuracy(), 2, '$x has A of 2');
|
|
|
|
- # reset for further tests
|
|
+ # change the class accuracy
|
|
+ $class->accuracy(3);
|
|
+ is($class->accuracy(), 3, "$class has A of 3");
|
|
+
|
|
+ # verify that the instance accuracy hasn't changed
|
|
+ is($x->accuracy(), 2, '$x still has A of 2');
|
|
+
|
|
+ # change the instance accuracy
|
|
+ $x->accuracy(undef);
|
|
+ is($x->accuracy(), undef, '$x now has A of undef');
|
|
+
|
|
+ # check the class accuracy
|
|
+ is($class->accuracy(), 3, "$class still has A of 3");
|
|
+
|
|
+ # change the class accuracy again
|
|
$class->accuracy(undef);
|
|
+ is($class->accuracy(), undef, "$class now has A of undef");
|
|
+
|
|
+ # Precision
|
|
+
|
|
+ # set and check the class precision
|
|
+ $class->precision(1);
|
|
+ is($class->precision(), 1, "$class has A of 1");
|
|
+
|
|
+ # a new instance gets the class precision
|
|
+ $x = $class->new(123);
|
|
+ is($x->precision(), 1, '$x has A of 1');
|
|
+
|
|
+ # set and check the instance precision
|
|
+ $x->precision(2);
|
|
+ is($x->precision(), 2, '$x has A of 2');
|
|
+
|
|
+ # change the class precision
|
|
+ $class->precision(3);
|
|
+ is($class->precision(), 3, "$class has A of 3");
|
|
+
|
|
+ # verify that the instance precision hasn't changed
|
|
+ is($x->precision(), 2, '$x still has A of 2');
|
|
+
|
|
+ # change the instance precision
|
|
+ $x->precision(undef);
|
|
+ is($x->precision(), undef, '$x now has A of undef');
|
|
+
|
|
+ # check the class precision
|
|
+ is($class->precision(), 3, "$class still has A of 3");
|
|
+
|
|
+ # change the class precision again
|
|
$class->precision(undef);
|
|
+ is($class->precision(), undef, "$class now has A of undef");
|
|
}
|
|
|
|
# bug with blog(Math::BigFloat, Math::BigInt)
|
|
diff --git a/xt/author/sparts-mbf.t b/xt/author/sparts-mbf.t
|
|
index f67ec95..45c0d64 100644
|
|
--- a/xt/author/sparts-mbf.t
|
|
+++ b/xt/author/sparts-mbf.t
|
|
@@ -57,7 +57,7 @@ note(qq|\nVerify that accuracy depends on invocand, not class.\n\n|);
|
|
my ($mant, $expo) = $x -> sparts();
|
|
cmp_ok($mant, '==', 3, "value of significand");
|
|
cmp_ok($expo, '==', 0, "value of exponent");
|
|
- cmp_ok($mant -> accuracy(), '==', 10, "accuracy of significand");
|
|
+ cmp_ok($mant -> accuracy(), '==', 20, "accuracy of significand");
|
|
cmp_ok($expo -> accuracy(), '==', 20, "accuracy of exponent");
|
|
}
|
|
|
|
@@ -71,7 +71,7 @@ note(qq|\nVerify that precision depends on invocand, not class.\n\n|);
|
|
my ($mant, $expo) = $x -> sparts();
|
|
cmp_ok($mant, '==', 3, "value of significand");
|
|
cmp_ok($expo, '==', 0, "value of exponent");
|
|
- cmp_ok($mant -> precision(), '==', 10, "precision of significand");
|
|
+ cmp_ok($mant -> precision(), '==', 20, "precision of significand");
|
|
cmp_ok($expo -> precision(), '==', 20, "precision of exponent");
|
|
}
|
|
|