@@ -4,8 +4,9 @@ use strict;
44use Carp;
55use Math::BigInt;
66use Math::BigFloat;
7+ use Scalar::Util;
78use vars qw( $VERSION) ;
8- $VERSION = ' 1.2 ' ;
9+ $VERSION = ' 1.20 ' ;
910
1011# configure some basic big number stuff
1112Math::BigInt -> config({
@@ -85,7 +86,10 @@ sub from_base {
8586 my $poten_digits = int (length ($str ) * $self -> {digit_strength }) + 16;
8687 Math::BigFloat-> accuracy($poten_digits + 16);
8788 my $result = Math::BigFloat-> new(0);
88- $result = $result -> as_int() unless $is_dec ;
89+ unless ($is_dec ) {
90+ Math::BigInt-> accuracy($poten_digits + 16);
91+ $result = Math::BigInt-> new( $result -> ffround(0, ' trunc' )-> bstr() ); # as_int loses precision on older BigFloats
92+ }
8993
9094 # short-circuits
9195 unless ($is_dec || !$self -> {digitset_name }) {
@@ -117,13 +121,20 @@ sub from_base {
117121sub _from_accurate_return {
118122 my ($self , $result ) = @_ ;
119123
124+ # Prior to 1.997, Math::BigFloat->numify would always return scientific
125+ # notation, even for the simpliest of numbers. This would cause test
126+ # failures and just look ugly in general. Since we still want to
127+ # support older Perls with core modules, this dualvar workaround was
128+ # necessary to maintain accuracy and still look reasonable as a string.
129+
120130 # never lose the accuracy
121131 my $rscalar = $result -> numify();
122132 my $rstring = $result -> bstr();
123133 $rstring =~ s / 0+$// if ($rstring =~ / \. / );
124134 $rstring =~ s /\. $// ; # float to whole number
125- # (the user can choose to put the string in a Math object if s/he so wishes)
126- return $rstring eq ($rscalar + 0 . ' ' ) ? $result -> numify() : $rstring ;
135+
136+ # (the user can choose to put the scalar in a Math object if s/he so wishes)
137+ return Scalar::Util::dualvar($rscalar , $rstring );
127138}
128139
129140sub to_base {
@@ -139,7 +150,10 @@ sub to_base {
139150 my $poten_digits = length ($num );
140151 Math::BigFloat-> accuracy($poten_digits + 16);
141152 $num = Math::BigFloat-> new($num );
142- $num = $num -> as_int() unless $is_dec && $self -> {radix_char };
153+ unless ($is_dec && $self -> {radix_char }) {
154+ Math::BigInt-> accuracy($poten_digits + 16);
155+ $num = Math::BigInt-> new( $num -> ffround(0, ' trunc' )-> bstr() ); # as_int loses precision on older BigFloats
156+ }
143157
144158 # (hold off on this check until after the big number support)
145159 return $self -> {neg_char }.$self -> to_base( $num -> bneg ) if $num < 0; # Handle negative numbers
@@ -163,8 +177,8 @@ sub to_base {
163177 # BigFloat's accuracy should counter this, but the $i check is
164178 # to make sure we don't get into an irrational/cyclic number loop
165179 while (($num != 0 || $i >= 0) && $i > -1024) {
166- my $exp = Math::BigFloat-> new($base );
167- $exp = $i < 0 ? $ exp-> bpow( $i ) : $exp -> as_int -> bpow($i );
180+ my $exp = $i < 0 ? Math::BigFloat-> new( $base ) : Math::BigInt -> new($base );
181+ $exp = $exp -> bpow($i );
168182 my $v = $num -> copy()-> bdiv($exp )-> bfloor();
169183 $num -= $v * $exp ; # this method is safer for fractionals
170184
@@ -193,7 +207,7 @@ Math::BaseCalc - Convert numbers between various bases
193207
194208=head1 VERSION
195209
196- version 1.2
210+ version 1.20
197211
198212=head1 SYNOPSIS
199213
@@ -276,14 +290,14 @@ If C<NUMBER> is a C<Math::BigInt> object, C<to_base()> will still work
276290fine and give you an exact result string. In fact, Math::Big* is loaded in
277291the background, so big numbers are fully supported.
278292
279- As of v1.2 , C<to_base() > will give you fractional results if passed a
293+ As of v1.20 , C<to_base() > will give you fractional results if passed a
280294fractional number, provided that the radix point character is still
281295available to use.
282296
283297=item * $calc->from_base(STRING)
284298
285299Converts a string representing a number in the associated base to a
286- Perl number. Unlike versions prior to v1.2 , C<from_base() > will fatally
300+ Perl number. Unlike versions prior to v1.20 , C<from_base() > will fatally
287301die if given a character not in $calc's digit set. Hence, if this is a
288302problem, you should clean your strings (including whitespace) prior to
289303conversion.
@@ -293,7 +307,7 @@ that the radix point character is still available to use. Negative
293307strings are supported, provided that the negative character is still
294308available to use.
295309
296- Large numbers are also fully supported, as of v1.2 . The exact type of
310+ Large numbers are also fully supported, as of v1.20 . The exact type of
297311scalar returned depends on the size of the number. If Perl cannot safely
298312represent the exact number, a string scalar is returned instead. Note that
299313C<from_base() > will never return an object, such as a Math::BigInt object,
0 commit comments