Interesting problem. Here's a straightforward extension of ikegami's solution to work off a file. I post it more for the record than for the OP (who I doubt will find it useful, since using it will require a modicum of honest work ;-) ):
use strict; use warnings; use Math::Pari; use List::Util 'min'; use Fcntl qw( SEEK_SET SEEK_END ); my $STRIDE = 8192; # pulled out of a hat mult( @ARGV ); sub mult { my ( $infile, $div, $rem ) = @_; my $n = PARI $div; my $carry = PARI $rem; my $outfile = "$infile.$$"; open my $in, '<', $infile or die "Can't read $infile: $!\n"; open my $out, '>', $outfile or die "Can't write to $outfile: $!\n"; my $in_offset = sysseek $in, 0, SEEK_END or die "sysseek error: $!\ +n"; my $out_offset = $in_offset + int( ( log $n )/log 10 ); my $to_print; { my $to_read = min( $STRIDE, $in_offset ); $in_offset -= $to_read; sysseek $in, $in_offset, SEEK_SET or die "sysseek error: $!\n"; my $chunk = ''; while ( $to_read ) { my $read = sysread( $in, my $buffer, $to_read ); die "sysread error: $!\n" unless defined $read; $chunk .= $buffer; $to_read -= $read; } my $num = ( $n * PARI( $chunk ) + $carry )->pari_print; my $batch = substr( $num, -$STRIDE, $STRIDE, '' ); $to_print = length $batch; die "internal error\n" if $to_print > $out_offset; $out_offset -= $to_print; seek $out, $out_offset, SEEK_SET or die "sysseek error: $!\n"; print $out $batch; $carry = PARI( $num || 0 ); last if $in_offset == 0; redo; } ( my $last = $carry->pari_print ) =~ s/^0+//; die if $out_offset != length $last; sysseek $out, 0, SEEK_SET or die "sysseek error: $!\n"; print $out $last; close $in; close $out; }
mult takes three arguments: a file, a divisor, and a remainder. The file must contain the quotient (base 10) without any leading 0s or any whitespace anywhere in the file digits of the quotient in reverse order. mult computes the dividend (i.e. the sum of the remainder plus the product of the quotient and the divisor) and puts it, again, with digits in reverse order, in a file whose name is obtained from the name of the input file. The input is read into memory in chunks of size 8192 and processed (though the size of these chunks is easily configurable, by setting the $STRIDE variable).
It processed a file containing a quotient of 1,000,000,000 digits in 35 minutes. Minimally tested, though.
And to the OP, you are welcome to tweak this further to suit your needs.
Update: Fixed the script so that now the digits in the input and output files are in the correct (not reverse) order. Also fixed some lurking bugs relating to mixing sysread calls with seek and tell calls.
the lowliest monk
In reply to Re: Reversed long division
by tlm
in thread Reversed long division
by Smoke
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |