in reply to Re: Rounding to a Given Number of Significant Figures Rather Than Decimal Places
in thread Rounding to a Given Number of Significant Figures Rather Than Decimal Places

Thank you very much for your advice. I have tried your suggestion and it does indeed work very well. However, it has made me realise that my question was ill considered. My problem is actually as follows: I have an 8 character wide field into which I must round a number (possibly with a decimal point, possibly not). I need to be able to say, "Take this number, and round it so that, including it's decimal point, if it has one, and any zeros, is only 8 characters long". I have tried using $num = sprintf "%8g", $num; but this seems to give me a 7 character long number with a space at the front. Thank you once again for your advice and any further help you can offer.
  • Comment on Re: Re: Rounding to a Given Number of Significant Figures Rather Than Decimal Places

Replies are listed 'Best First'.
Re: Re: Re: Rounding to a Given Number of Significant Figures Rather Than Decimal Places
by davis (Vicar) on Jan 13, 2003 at 15:12 UTC
    $num = sprintf "%8g", $num;
    Almost. shell$> perldoc -f sprintf reveals this little snippet:
    # Format number with up to 8 leading zeroes $result = sprintf("%08d", $number);
    Change the "d" to a "g" (which you had), and you'll be there. You'll probably find you want to do the SigFig rounding first, then format it for display with the sprintf.
    cheers
    davis
    Is this going out live?
    No, Homer, very few cartoons are broadcast live - it's a terrible strain on the animator's wrist
      Sorry to be dim but with the following lines of code: $_ = FormatSigFigs($_,8); my $clem = sprintf("%08g", $_); print "$clem\n"; and starting with the number 1298.844667, I get the result 01298.84 and not 1298.845, as desired. Any ideas? Thanks again for your help.
      Sorry to be a bit dim but, with the following lines of code:
      $_ = FormatSigFigs($_,8); my $clem = sprintf("%08g", $_); print "$clem\n";
      and the number 1298.844667 as input, I get the output 01298.84 and not 1298.845, which is what I want.
      Any ideas?
      Thanks again for your help.

      Edit: larsen. Added <code> tags and some minor formatting.

Re:x3 Rounding to a Given Number of Significant Figures Rather Than Decimal Places
by grinder (Bishop) on Jan 13, 2003 at 15:28 UTC

    In that case, to a first approximation you could do something like the following:

    #! /usr/bin/perl -w use strict; while( <DATA> ) { chomp; my $nr = squeeze($_); print "[$nr] $_\n"; } sub squeeze { my $n = sprintf( '%0.8f', $_[0] ); $n =~ s/^0//; substr( $n, 0, 8 ); } __DATA__ 12345678901234567890 1234567890 1234567.0 1234567.9 123456.789012345 12345 123.4567 123.4 .1 .1234567890 0.00000999999

    Then again, the few test cases here reveal a certain number of bugs. I contend that the results to squeeze() contain a bug, in that 1234567.0 and 1234567.9 return the same results, but in truth the latter should return 1234568. I don't know whether you will hit these borderline cases or not.

    Maybe there's yet another module that deals with your problem.

    <update>In response to gjb's remark about whether this code is a good idea or not, I was trying to point out the folly of storing numbers in fixed-width fields. The idea being that when you see what this outputs, maybe you better start thinking about overflow conditions. As I don't know the domain. I can't really deal with in a satisfactory matter (at least to my standards). I prefer to let the code stand as it is.</update>


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

      I don't really think that this piece of code is such a good idea: representing 12345678901234567890 as 12345678 doesn't make sense in any situation I can think of.

      I'd suggest the author to check what he's written and either to modify or motivate this program.

      Update: Fair enough given the update grinder added.

      Just my 2 cents, -gjb-

Re3: Rounding to a Given Number of Significant Figures Rather Than Decimal Places
by dragonchild (Archbishop) on Jan 13, 2003 at 15:57 UTC
    Heh. Try doing something like:
    my $num = 12345.678; # a total of 9 characters if (length $num > 8) { if ($num =~ /\./) # If there's a decimal point { # Put it to seven significant figures } else { # Put it to eight significant figures } }
    Another way to test for the decimal point, if you wanted to be purely math-based, could be if ($num == round($num)).

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      What about a minus/plus sign in front of the number? And what if the number is longer than 8 characters, like 1234567890?

      I think there are a lot of corner cases lurking around in this problem ... :)

      -- Hofmator

        Hmmm ... sounds like a job for

        .

        .

        .

        Requirements-Gathering Person!

        (Or, Requirements-Revising Person, as the case may be...)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.