Encode-Float

 view release on metacpan or  search on metacpan

lib/Encode/Float.pm  view on Meta::CPAN

package Encode::Float;
use strict;

BEGIN
{
	use Exporter ();
	use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
	$VERSION     = '0.11';
	@ISA         = qw(Exporter);
	@EXPORT      = qw();
	@EXPORT_OK   = qw();
	%EXPORT_TAGS = ();
}

#01234567890123456789012345678901234567890123
#Encode/decode float as a string for sorting.

=head1 NAME

C<Encode::Float> - Encode/decode float as a string for sorting.

=head1 SYNOPSIS

  use Encode::Float;
  my $encoder = Encode::Float->new();
  my @list;
  for (my $i = 0 ; $i < 10 ; $i++)
  {
    my $float = (.5 - rand) * 10**int(10 - 20 * rand);
    $float = 0 if $i == 0;
    my $encoded = $encoder->encode($float);
    my $decoded = $encoder->decode($encoded);
    my $error   = $encoder->getRelativeDifference($float, $decoded);
    push @list, [ $encoded, $float, $decoded, $error ];
  }
  @list = sort { $a->[0] cmp $b->[0] } @list;
  foreach (@list)
  {
    print join(',', @$_) . "\n";
  }

=head1 DESCRIPTION

C<Encode::Float> encodes and decodes floating point numbers
as fixed length positive decimal integers that preserve their order (less
rounding errors), that is, sorting the encoded integers also sorts the 
floating point numbers.

=head1 CONSTRUCTOR

=head2 C<new>

The method C<new> creates an instance of the C<Encode::Float>
class with the following parameter:

=over

=item C<digitsOfAccuracy>

 digitsOfAccuracy => 16

C<digitsOfAccuracy> is an optional parameter that sets the number of
decimal digits to preserve in the floating point number; the default is 16.

=back

=cut

sub new
{
	my ($Class, %Parameters) = @_;
	my $Self = bless({}, ref($Class) || $Class);

	# set the number of digits used to represent a float.
	$Self->{digitsOfAccuracy} = 16;
	$Self->{digitsOfAccuracy} = int abs $Parameters{digitsOfAccuracy} if exists $Parameters{digitsOfAccuracy};
	$Self->{digitsOfAccuracy} = 1 if $Self->{digitsOfAccuracy} < 1;

	# get the maximum integer value.
	my $mantissaMaxStr = '9' x $Self->{digitsOfAccuracy};
	my $mantissaMax    = $mantissaMaxStr + 0;
	if ($mantissaMax ne $mantissaMaxStr)
	{
		die "digitsOfAccuracy =  $Self->{digitsOfAccuracy} is too large.\n";
	}
	$Self->{mantissaMax}    = $mantissaMax;
	$Self->{floatFormat}    = '%+' . '.' . ($Self->{digitsOfAccuracy} - 1) . 'E';
	$Self->{exponentSize}   = 3;
	$Self->{exponentFormat} = '%+0' . ($Self->{exponentSize} + 1) . 'd';
	$Self->{exponentMax}    = '9' x $Self->{exponentSize};
	$Self->{mantissaFormat} = '%0' . $Self->{digitsOfAccuracy} . 'd';
	return $Self;
}



( run in 1.180 second using v1.01-cache-2.11-cpan-e1769b4cff6 )