#!/usr/bin/perl use strict; use warnings; sub middle ($$) { my ( $a, $b ) = ( shift, shift ); return ($a + $b) / 2 } sub square ($) { my $x = shift; return $x**2; } sub abs ($) { my $n = shift; return $n < 0 ? -$n : $n; } sub sqrt_search{ my ( $x, $base, $top, $guess, $counter ) = ( shift, shift, shift, shift, shift ); print "sqrt-search( $x, $base, $top, $guess )\n"; return $guess if( abs($x - square $guess) < 0.0001); return undef if $counter == 0; return sqrt_search( $x, $guess, $top, middle( $guess, $top ), --$counter) if( ($x > 0) and (square $guess < $x) ); return sqrt_search( $x, $base, $guess, middle( $base, $guess ), --$counter) if( ($x > 0) and (square $guess > $x) ); return undef; } sub sqrt ($) { my $x = shift; return sqrt_search( $x, 0, $x, middle(0, $x), 50); } # Tests print "SQRT 16:\n", &sqrt( 16 ), $/, $/; print "SQRT 4:\n", &sqrt( 4 ), $/, $/; print "SQRT 2:\n", &sqrt( 2 ), $/, $/; print "SQRT 0.5:\n", &sqrt( .5 ), $/, $/; print "SQRT -1:\n", &sqrt( -1 ), $/, $/; print "SQRT 0:\n", &sqrt( 0 ), $/, $/;