use strict; use warnings; use feature "say"; use constant DEBUG => 1; my $epsilon = 1e-12; # precision my ($result, $step) = (0, 10); # arbitrary start values my $equation = "(2*(4*x-8)+3*x)-(10*x+1-9)"; # " = 0" omitted $equation =~ s/x/\$x/g; my $eval = create_eval($equation); # currying the equation for simplicity my $debug = 1; while (1) { my $val = $eval->($result); last if abs $val < $epsilon; my $new_result = $result + $step; my $temp = $eval->($new_result); say "x = $result ; val = $val ; temp = $temp; step = $step" if DEBUG; $result = $new_result and last if abs $temp < $epsilon; if ($temp == $val) { say "No solution for this equation"; undef $result; last; } if (($val > 0 and $temp < 0) or ($val < 0 and $temp > 0)) { while (1) { $step = 0; my $avg = ($result + $new_result) /2; my $avg_val = $eval->($avg); # say "x = $result; val = $val ; temp = $temp; step = $step; avg = $avg" if DEBUG; printf "%s%.15f%s%.15f%s%.15f%s%.15f\n", "x = ", $result, " val = ", $val, " temp = ", $temp, " avg = ", $avg; $new_result = $avg and last if abs $avg_val < $epsilon; if ($avg_val > 0) { $result = $avg and $val= $avg_val if $val > 0; $new_result = $avg and $temp = $avg_val if $temp > 0; } else { $result = $avg and $val = $avg_val if $val < 0; $new_result = $avg and $temp = $avg_val if $temp < 0; } } } $step = -$step and next if $temp < $val and $val < 0; $step /= 2 and next if abs $temp > abs $val; # we are further from 0, reduce step by half $result =$new_result; # $temp is closer to 0, let's continue with $new_resultp } printf "%s%.10f\n", "Result is: ", $result;# if defined $result; sub create_eval { my $formula = shift; return sub { my $x = shift; return eval($formula);} } #### $ perl solver.pl x = 0 ; val = -8 ; temp = 2; step = 10 x = 0.000000000000000 val = -8.000000000000000 temp = 2.000000000000000 avg = 5.000000000000000 x = 5.000000000000000 val = -3.000000000000000 temp = 2.000000000000000 avg = 7.500000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 2.000000000000000 avg = 8.750000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 0.750000000000000 avg = 8.125000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 0.125000000000000 avg = 7.812500000000000 x = 7.812500000000000 val = -0.187500000000000 temp = 0.125000000000000 avg = 7.968750000000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.125000000000000 avg = 8.046875000000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.046875000000000 avg = 8.007812500000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.007812500000000 avg = 7.988281250000000 x = 7.988281250000000 val = -0.011718750000000 temp = 0.007812500000000 avg = 7.998046875000000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.007812500000000 avg = 8.002929687500000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.002929687500000 avg = 8.000488281250000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.000488281250000 avg = 7.999267578125000 x = 7.999267578125000 val = -0.000732421875000 temp = 0.000488281250000 avg = 7.999877929687500 x = 7.999877929687500 val = -0.000122070312500 temp = 0.000488281250000 avg = 8.000183105468750 x = 7.999877929687500 val = -0.000122070312500 temp = 0.000183105468750 avg = 8.000030517578125 x = 7.999877929687500 val = -0.000122070312500 temp = 0.000030517578125 avg = 7.999954223632812 x = 7.999954223632812 val = -0.000045776367188 temp = 0.000030517578125 avg = 7.999992370605469 x = 7.999992370605469 val = -0.000007629394531 temp = 0.000030517578125 avg = 8.000011444091797 x = 7.999992370605469 val = -0.000007629394531 temp = 0.000011444091797 avg = 8.000001907348633 x = 7.999992370605469 val = -0.000007629394531 temp = 0.000001907348633 avg = 7.999997138977051 x = 7.999997138977051 val = -0.000002861022949 temp = 0.000001907348633 avg = 7.999999523162842 x = 7.999999523162842 val = -0.000000476837158 temp = 0.000001907348633 avg = 8.000000715255737 x = 7.999999523162842 val = -0.000000476837158 temp = 0.000000715255737 avg = 8.000000119209290 x = 7.999999523162842 val = -0.000000476837158 temp = 0.000000119209290 avg = 7.999999821186066 x = 7.999999821186066 val = -0.000000178813934 temp = 0.000000119209290 avg = 7.999999970197678 x = 7.999999970197678 val = -0.000000029802322 temp = 0.000000119209290 avg = 8.000000044703484 x = 7.999999970197678 val = -0.000000029802322 temp = 0.000000044703484 avg = 8.000000007450581 x = 7.999999970197678 val = -0.000000029802322 temp = 0.000000007450581 avg = 7.999999988824129 x = 7.999999988824129 val = -0.000000011175871 temp = 0.000000007450581 avg = 7.999999998137355 x = 7.999999998137355 val = -0.000000001862645 temp = 0.000000007450581 avg = 8.000000002793968 x = 7.999999998137355 val = -0.000000001862645 temp = 0.000000002793968 avg = 8.000000000465661 x = 7.999999998137355 val = -0.000000001862645 temp = 0.000000000465661 avg = 7.999999999301508 x = 7.999999999301508 val = -0.000000000698492 temp = 0.000000000465661 avg = 7.999999999883585 x = 7.999999999883585 val = -0.000000000116415 temp = 0.000000000465661 avg = 8.000000000174623 x = 7.999999999883585 val = -0.000000000116415 temp = 0.000000000174623 avg = 8.000000000029104 x = 7.999999999883585 val = -0.000000000116415 temp = 0.000000000029104 avg = 7.999999999956344 x = 7.999999999956344 val = -0.000000000043656 temp = 0.000000000029104 avg = 7.999999999992724 x = 7.999999999992724 val = -0.000000000007276 temp = 0.000000000029104 avg = 8.000000000010914 x = 7.999999999992724 val = -0.000000000007276 temp = 0.000000000010914 avg = 8.000000000001819 x = 7.999999999992724 val = -0.000000000007276 temp = 0.000000000001819 avg = 7.999999999997272 x = 7.999999999997272 val = -0.000000000002728 temp = 0.000000000001819 avg = 7.999999999999545 Result is: 8.0000000000