vis1982 has asked for the wisdom of the Perl Monks concerning the following question:

I have a question regarding solving quadratic equation.
#!/usr/bin/perl use strict; open(FH,"$ARGV[0]") or die; my @temp=<FH>; close FH; my $quadratic = quadratic (\@temp); print "$quadratic\n"; sub quadratic { my ($a, $b, $c) = @_; return (-$b + sqrt($b*$b - 4*$a * $c)) / 2*$a; }
and u have a input number given 4,8,3 Still it print as zero Why??

Replies are listed 'Best First'.
Re: solving a quadratic equation
by RMGir (Prior) on Dec 08, 2009 at 12:46 UTC
    You've got a couple of different problems going on here.

    I'd suggest running your code under perl -d (the debugger) and using the "b" command to set breakpoints at the line where you're closing FH and doing

    p @temp
    That will show you what @temp contains. Hint, it's not what you expect :)

    Also, you should put a breakpoint in quadratic in the line that returns the result. Check out the values of $a, $b, and $c - they're also not what you expect, because @temp isn't what you expected, and also because you're passing \@temp (a reference to an array) but then accessing @_, which will only contain one element, that reference.


    Mike
Re: solving a quadratic equation
by Anonymous Monk on Dec 08, 2009 at 12:44 UTC
    You're passing a single value, \@temp, but you appear to want to pass @temp instead
    #!/usr/bin/perl -- use strict; use warnings; my @temp = ( 4, 8, 3 ); my $quadratic = quadratic (\@temp); print "$quadratic\n"; $quadratic = quadratic (@temp); print "$quadratic\n"; sub quadratic { my ($a, $b, $c) = @_; return (-$b + sqrt($b*$b - 4*$a * $c)) / 2*$a; } __END__ Use of uninitialized value $b in negation (-) at - line 13. Use of uninitialized value $b in multiplication (*) at - line 13. Use of uninitialized value $b in multiplication (*) at - line 13. Use of uninitialized value $c in multiplication (*) at - line 13. 0 -8
Re: solving a quadratic equation
by GrandFather (Saint) on Dec 08, 2009 at 21:47 UTC

    Although you use strict, you don't use warnings. If you had you'd have received a slew of 'Use of uninitialized value' warnings.

    However, there are a bundle of problems and areas for improvement from using lexical file handles and three parameter open to processing input data and checking parameters. The following addresses those issues:

    use strict; use warnings; my $data = <<DATA; 4,8,3 2,2,3 -1,2,8 DATA open my $inFile, '<', \$data or die "File open failed: $!\n"; my @temp = map {[split ',']} <$inFile>; close $inFile; for my $values (@temp) { my $quadratic = quadratic (@$values); if (! defined $quadratic) { printf "a = %f, b = %f, c = %f: No solution\n", @$values; next; } printf "a = %f, b = %f, c = %f: %f\n", @$values, $quadratic; } sub quadratic { my ($a, $b, $c) = @_; my $root = $b*$b - 4*$a * $c; return if ! $a; return if $root < 0; return -($b + (0 < $b ? 1 : -1) * sqrt($root)) / 2*$a; }

    Prints:

    a = 4.000000, b = 8.000000, c = 3.000000: -24.000000 a = 2.000000, b = 2.000000, c = 3.000000: No solution a = -1.000000, b = 2.000000, c = 8.000000: 4.000000

    True laziness is hard work
Re: solving a quadratic equation
by ambrus (Abbot) on Dec 08, 2009 at 14:37 UTC

    In addittion to the two errors others have pointed out, note that the correct formula is

    -($b + (0 < $b ? 1 : -1) * sqrt($b*$b - 4*$a * $c)) / 2*$a

      Ambrus: Why does your choice of root depend on the sign of $b?

      Returning a list containing both roots is quite reasonable for Perl, and then the calling function can decide what subset of them it wants to use.
      I would also suggest a test for $a being too small, and then use a linear solution rather than trying to divide by zero.