Math-NoCarry-1.11/0000755000076500007650000000000010726706650012673 5ustar brianbrianMath-NoCarry-1.11/Changes0000644000076500007650000000172210726706644014173 0ustar brianbrianRevision history for Perl extension Math::NoCarry. 1.11 - Sun Dec 9 00:37:35 2007 * Now all the functions are exportable on demand. * Distro requires 5.006, although it probably stills works on earlier versions. I'm not actively supporting those though. 1.10 - Tue Jan 9 22:33:59 2007 * updated copyright and license info * no code changes, so no need to upgrade 1.09 - Thu May 18 17:15:39 2006 * Updates to distro and kwalitee. No need to upgrade. 1.08 - Fri Mar 11 21:55:20 2005 * Updated docs for POD coverage tests * No code changes, but the docs for subtract() are labelled correctly now. 1.07 - Wed Nov 17 16:03:55 2004 * no changes 1.07 - Fri Oct 8 15:56:57 2004 * no feature changes: added strictures and removed unreachable statement 1.06 - Wed Sep 8 03:43:12 2004 * cleaned up the distro and the docs 8 no code changes, no need to upgrade 0.01 Tue Jun 25 03:10:43 2002 - original version; created by h2xs 1.21 with options -AXn Math::NoCarry Math-NoCarry-1.11/examples/0000755000076500007650000000000010726706650014511 5ustar brianbrianMath-NoCarry-1.11/examples/README0000644000076500007650000000010510562747364015372 0ustar brianbrianSee the tests in the t/ directory for examples until I add some more.Math-NoCarry-1.11/lib/0000755000076500007650000000000010726706650013441 5ustar brianbrianMath-NoCarry-1.11/lib/NoCarry.pm0000644000076500007650000001063310726705631015355 0ustar brianbrian# $Id: NoCarry.pm 2454 2007-12-09 06:29:57Z comdog $ package Math::NoCarry; use strict; use warnings; no warnings; use base qw(Exporter); use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS); @EXPORT_OK = qw(add subtract multiply); %EXPORT_TAGS = ( all => [ @EXPORT_OK ] ); $VERSION = 1.11; =head1 NAME Math::NoCarry - Perl extension for no carry arithmetic =head1 SYNOPSIS use Math::NoCarry qw(:all); my $sum = add( 123, 456 ); my $difference = subtract( 123, 456 ); my $product = multiply( 123, 456 ); =head1 DESCRIPTION No carry arithmetic doesn't allow you to carry digits to the next column. For example, if you add 8 and 4, you normally expect the answer to be 12, but that 1 digit is a carry. In no carry arithmetic you can't do that, so the sum of 8 and 4 is just 2. In effect, this is addition modulo 10 in each column. I discard all of the carry digits in this example: 1234 + 5678 ------ 6802 For multiplication, the result of pair-wise multiplication of digits is the modulo 10 value of their normal, everyday multiplication. 123 x 456 ----- 8 6 x 3 2 6 x 2 6 6 x 1 5 5 x 3 0 5 x 2 5 5 x 1 2 4 x 3 8 4 x 2 + 4 4 x 1 ------- 43878 Since multiplication and subtraction are actually types of additions, you can multiply and subtract like this as well. No carry arithmetic is both associative and commutative. =head2 Functions As of version 1.11, all of these functions are exportable on demand, or with the tag C<:all> to get them all at once. =over 4 =item multiply( A, B ) Returns the no carry product of A and B. Return A if it is the only argument ( A x 1 ); =cut sub multiply { return $_[0] if $#_ < 1; @_ = map { $_ += 0 } @_; my $sign = ($_[0] > 0 and $_[1] < 0 ) || ($_[1] > 0 and $_[0] < 0 ); my @p0 = reverse split //, abs $_[0]; my @p1 = reverse split //, abs $_[1]; my @m; foreach my $i ( 0 .. $#p0 ) { foreach my $j ( 0 .. $#p1 ) { push @m, ( ( $p1[$j] * $p0[$i] ) % 10 ) * ( 10**($i+$j) ); } } while( @m > 1 ) { unshift @m, Math::NoCarry::add( shift @m, shift @m ); } $m[0] *= -1 if $sign; return $m[0]; } =item add( A, B ) Returns the no carry sum of the positive numbers A and B. Returns A if it is the only argument ( A + 0 ) Returns false if either number is negative. =cut sub add { return $_[0] if $#_ < 1; @_ = map { local $^W; $_ += 0 } @_; return unless( $_[0] >= 0 and $_[1] >= 0 ); my @addends = map scalar reverse, @_; my $string = ''; my $max = length $addends[0]; $max = length $addends[1] if length $addends[1] > $max; for( my $i = 0; $i < $max ; $i++ ) { my @digits = map { local $^W = 0; substr( $_, $i, 1) or 0 } @addends; my $sum = ( $digits[0] + $digits[1] ) % 10; $string .= $sum; } $string =~ s/0*$//; $string = scalar reverse $string; return $string; } =item subtract( A, B ) Returns the no carry difference of the postive numbers A and B. Returns A if it is the only argument ( A - 0 ) Returns false if either number is negative. =cut sub subtract { return $_[0] if $#_ < 1; return unless( $_[0] >= 0 and $_[1] >= 0); my @addends = map scalar reverse, @_; my $string = ''; my $max = length $addends[0]; $max = length $addends[1] if length $addends[1] > $max; for( my $i = 0; $i < $max ; $i++ ) { my @digits = map { substr $_, $i, 1 } @addends; $digits[0] += 10 if $digits[0] < $digits[1]; my $sum = ( $digits[0] - $digits[1] ) % 10; $string .= $sum; } return scalar reverse $string; } 1; __END__ =back =head1 BUGS * none reported yet :) =head1 TO DO * this could be a full object package with overloaded +, *, and - operators * it would be nice if i could give the functions more than two arguments. * addition and subtraction don't do negative numbers. =head1 SOURCE AVAILABILITY This source is part of a SourceForge project which always has the latest sources in SVN, as well as all of the previous releases. http://sourceforge.net/projects/brian-d-foy/ If, for some reason, I disappear from the world, one of the other members of the project can shepherd this module appropriately. =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright (c) 2002-2007 brian d foy. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cutMath-NoCarry-1.11/LICENSE0000644000076500007650000000007610562747364013710 0ustar brianbrianYou can use Math::NoCarry under the same terms as Perl itself.Math-NoCarry-1.11/Makefile.PL0000644000076500007650000000116110726705660014644 0ustar brianbrian# $Id: Makefile.PL 2454 2007-12-09 06:29:57Z comdog $ use ExtUtils::MakeMaker; require 5.006; eval "use Test::Manifest 1.14"; WriteMakefile ( 'NAME' => 'Math::NoCarry', 'ABSTRACT' => 'Perl extension for no carry arithmetic', 'VERSION_FROM' => 'lib/NoCarry.pm', 'LICENSE' => 'perl', 'AUTHOR' => 'brian d foy ', 'PM' => { 'lib/NoCarry.pm' => '$(INST_LIBDIR)/NoCarry.pm', }, 'PREREQ_PM' => { 'Test::More' => '0', }, 'MAN3PODS' => { 'lib/NoCarry.pm' => '$(INST_MAN3DIR)/Math::NoCarry.3', }, clean => { FILES => 'Math-NoCarry-*' }, ); Math-NoCarry-1.11/MANIFEST0000644000076500007650000000037110726706650014025 0ustar brianbrianChanges examples/README lib/NoCarry.pm LICENSE Makefile.PL MANIFEST README t/add.t t/load.t t/multiply.t t/pod.t t/pod_coverage.t t/prereq.t t/subtract.t t/test_manifest META.yml Module meta-data (added by MakeMaker) Math-NoCarry-1.11/META.yml0000664000076500007650000000066210726706650014152 0ustar brianbrian--- #YAML:1.0 name: Math-NoCarry version: 1.11 abstract: Perl extension for no carry arithmetic license: perl generated_by: ExtUtils::MakeMaker version 6.36 distribution_type: module requires: Test::More: 0 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 author: - brian d foy Math-NoCarry-1.11/README0000644000076500007650000000102010562747364013551 0ustar brianbrian$Id: README 1467 2004-09-08 08:30:22Z comdog $ You can install this using in the usual Perl fashion perl Makefile.PL make make test make install The documentation is in the module file. Once you install the file, you can read it with perldoc. perldoc Math::NoCarry If you want to read it before you install it, you can use perldoc directly on the module file. perldoc lib/NoCarry.pm This module is also in CVS on SourceForge http://sourceforge.net/projects/brian-d-foy/ Enjoy, brian d foy, bdfoy@cpan.orgMath-NoCarry-1.11/t/0000755000076500007650000000000010726706650013136 5ustar brianbrianMath-NoCarry-1.11/t/add.t0000644000076500007650000000207610562747363014064 0ustar brianbrianBEGIN { print "1..4\n"; } END { print "not ok\n" unless $loaded } use Math::NoCarry; $loaded = 1; print "ok\n"; my @triads = ( [qw(123 456 579)], [qw(890 135 925)], [qw(456 879 225)], ); eval { foreach my $triad ( @triads ) { my( $n, $m, $expected ) = @$triad; my $sum1 = Math::NoCarry::add( $n, $m ); my $sum2 = Math::NoCarry::add( $m, $n ); die "Different results for different orders!\n" . "[$n + $m] gave [$sum1]\n[$m + $n] gave [$sum2]\n" if $sum1 != $sum2; die "[$n + $m] gave [$sum1], but I expected [$expected]\n" unless $sum1 == $expected; } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { foreach my $triad ( @triads ) { foreach my $n ( @$triad ) { my $sum = Math::NoCarry::add( $n ); die "[$n] gave [$sum], but I expected [$n]\n" unless $sum == $n; } } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { my $sum = Math::NoCarry::add(); die "[NULL] gave [$sum], but I expected [FALSE]\n" if $sum; }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; Math-NoCarry-1.11/t/load.t0000644000076500007650000000036010562747363014245 0ustar brianbrian# $Id: load.t 1467 2004-09-08 08:30:22Z comdog $ BEGIN { @classes = qw(Math::NoCarry); } use Test::More tests => scalar @classes; foreach my $class ( @classes ) { print "bail out! $class did not compile\n" unless use_ok( $class ); } Math-NoCarry-1.11/t/multiply.t0000644000076500007650000000233010562747363015204 0ustar brianbrianBEGIN { print "1..4\n"; } END { print "not ok\n" unless $loaded } use Math::NoCarry; $loaded = 1; print "ok\n"; my @triads = ( [qw( 123 456 43878)], [qw(-123 -456 43878)], [qw(-123 456 -43878)], [qw( 123 -456 -43878)], [qw(456 123 43878)], [qw(456 879 28974)], [qw(879 456 28974)], [qw( 890 135 83750)], [qw( 135 890 83750)], [qw(-135 890 -83750)], [qw( 135 -890 -83750)], [qw(-135 -890 83750)], [qw(500 321 50500)], [qw(321 500 50500)], ); eval { foreach my $triad ( @triads ) { my( $n, $m, $expected ) = @$triad; my $product = Math::NoCarry::multiply( $n, $m ); die "[$n x $m] gave [$product], but I expected [$expected]\n" unless $product == $expected; } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { foreach my $triad ( @triads ) { foreach my $n ( @$triad ) { my $product = Math::NoCarry::multiply( $n ); die "[$n] gave [$product], but I expected [$n]\n" unless $product == $n; } } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { my $product = Math::NoCarry::multiply(); die "[NULL] gave [$product], but I expected [FALSE]\n" if $product; }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; Math-NoCarry-1.11/t/pod.t0000644000076500007650000000026110562747363014110 0ustar brianbrian# $Id: pod.t 1467 2004-09-08 08:30:22Z comdog $ use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); Math-NoCarry-1.11/t/pod_coverage.t0000644000076500007650000000040510562747363015763 0ustar brianbrian# $Id: pod_coverage.t 1591 2005-03-12 03:53:57Z comdog $ use Test::More; eval "use Test::Pod::Coverage"; if( $@ ) { plan skip_all => "Test::Pod::Coverage required for testing POD"; } else { plan tests => 1; pod_coverage_ok( "Math::NoCarry" ); } Math-NoCarry-1.11/t/prereq.t0000644000076500007650000000025610562747363014630 0ustar brianbrian# $Id: prereq.t 1467 2004-09-08 08:30:22Z comdog $ use Test::More; eval "use Test::Prereq"; plan skip_all => "Test::Prereq required to test dependencies" if $@; prereq_ok(); Math-NoCarry-1.11/t/subtract.t0000644000076500007650000000215410562747363015160 0ustar brianbrian# $Id: subtract.t 1467 2004-09-08 08:30:22Z comdog $ BEGIN { print "1..4\n"; } END { print "not ok\n" unless $loaded } use Math::NoCarry; $loaded = 1; print "ok\n"; my @triads = ( [qw(123 456 579)], [qw(890 135 925)], [qw(456 879 225)], ); eval { foreach my $triad ( @triads ) { my( $expected, $m, $n ) = @$triad; my $diff1 = Math::NoCarry::subtract( $n, $m ); my $diff2 = Math::NoCarry::subtract( $n, $expected ); die "[$n - $m] gave [$diff], but I expected [$expected]\n" unless $diff1 == $expected; die "[$n - $expected] gave [$diff], but I expected [$m]\n" unless $diff2 == $m; } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { foreach my $triad ( @triads ) { foreach my $n ( @$triad ) { my $diff = Math::NoCarry::subtract( $n ); die "[$n] gave [$diff], but I expected [$n]\n" unless $diff == $n; } } }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; eval { my $diff = Math::NoCarry::subtract(); die "[NULL] gave [$diff], but I expected [FALSE]\n" if $diff; }; print STDERR $@ if $@; print $@ ? 'not ' : '', "ok\n"; Math-NoCarry-1.11/t/test_manifest0000644000076500007650000000017110562747363015731 0ustar brianbrian# $Id: test_manifest 1591 2005-03-12 03:53:57Z comdog $ load.t pod.t pod_coverage.t prereq.t add.t multiply.t subtract.t