use strict; use warnings; use Math::Pari; 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"; { defined( sysread $in, my $chunk, $STRIDE ) or die "sysread error: $!\n"; last unless length $chunk; my $num = ( $n * PARI( scalar reverse $chunk ) + $carry )->pari_print; print $out scalar reverse substr( $num, -$STRIDE, $STRIDE, '' ); $carry = PARI( $num || 0 ); redo; } ( my $last = $carry->pari_print ) =~ s/^0+//; print $out scalar reverse $last; close $in; close $out; } __END__ #### 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; }