use strict;
use warnings;

use constant EPS => 1E-12;

sub f
  {
  my $x = shift;
  return (exp(-$x) - 2.0*$x);
  }

my $y = nullstelle(0.3, 0.4, \&f);
printf("Nullstelle: %.4f Funktionswert: %.4f\n", $y, f($y));

# Ergebnis: Nullstelle: 0.3500 Funktionswert: 0.0047


sub nullstelle #($a, $b, \&f(x))
  {
  my ($a, $b, $f) = @_;
  my $x;
  do
    {
    # Mitte zwischen $a und $b
    $x = ($a + $b)/2.0;
    if (&{$f}($a) * &{$f}($b) > 0)
      { $a = $x; } # Nullstelle im rechten Intervall
    else
      { $b = $x; } # Nullstelle im linken Intervall
    }
  while (abs($b - $a) > EPS * abs($b));
  return($x);
  }