Created
September 17, 2020 16:01
-
-
Save xtetsuji/fe02c80bf8207f416e9438bfd105a0e8 to your computer and use it in GitHub Desktop.
Get square root by Newton's method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use v5.14; | |
use constant MAX_NEWTON_ITERATION_COUNT => 8; | |
print "平方根をニュートン法で求めます\n"; | |
print "1より大きい自然数を入れて下さい: "; | |
my $input = <STDIN>; | |
chomp $input; | |
if ( !$input || $input <= 1 ) { | |
die "1より大きい自然数ではありませんでした\n"; | |
} | |
my $sqrt_newton = sqrt_newton($input); | |
my $sqrt_core = sqrt($input); | |
print "平方根の近似値は $sqrt_newton です\n"; | |
print "なお sqrt 組み込み関数の結果は $sqrt_core です\n"; | |
print "小数点以下の桁数は" | |
. length($sqrt_newton =~ s/^\d+\.//r) . " 桁中 " | |
. match_max_decimal($sqrt_newton, $sqrt_core) . "桁あっています\n"; | |
sub sqrt_newton { | |
my $number = shift; | |
my $func = get_func($number); | |
my $x = $number; # 初期値 | |
$x = $func->($x) for 1..MAX_NEWTON_ITERATION_COUNT; | |
return $x; | |
} | |
sub get_func { | |
my $c = shift; | |
return sub { | |
my $x = shift; | |
return( 0.5 * ($x + $c / $x) ); | |
}; | |
} | |
sub match_max_decimal { | |
my ($n1, $n2) = @_; | |
s/^\d+\.// for $n1, $n2; | |
my $i = 0; | |
for my $pair (zipstr($n1, $n2)) { | |
my ($c1, $c2) = @$pair; | |
if ( $c1 ne $c2 ) { | |
return $i; | |
} | |
$i++; | |
} | |
return $i; | |
} | |
# List::MoreUtils::zip6( split(//, $str1), split(//, $str2) ) と大体同じ | |
sub zipstr { | |
my ($str1, $str2) = @_; | |
my @ar1 = split //, $str1; | |
my @ar2 = split //, $str2; | |
my $i = 0; | |
my @pairs; | |
while ( defined $ar1[$i] && defined $ar2[$i] ) { | |
push @pairs, [$ar1[$i], $ar2[$i]]; | |
$i++; | |
} | |
return @pairs; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment