significant figures

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
Whilst trying to create something that would parse a number into one with
an appropriate number of significant figures, I accidentally wrote this:

sub sigfig {
my (\$sigfigs, \$number) = @_;

my \$divisor = 10**(length(int \$number) - \$sigfigs);
\$number /= \$divisor;
\$number = sprintf "%1.0f", \$number;
\$number *= \$divisor;

return \$number
}

which seems to work for positive numbers not in scientific notation.

As my friends and colleagues consider me big-headed, I would appreciate
it if somebody could point out any inadequacies,foibles and associated
notwithstandings of the above code, bringing me down a much needed peg or
to.

dan

Re: significant figures

\$number = sprintf("%d",\$number); # just in case...
return \$number if if (\$sigfgs > length(\$number);

\$number = sprintf("%d",\$number);

Well, if it works, it works.

A bit shorter:

\$number = sprintf("%d",\$number); # just in case...
return substr(\$number,0,\$sigfigs) . ("0" x (length(\$number) -
\$sigfigs));

Re: significant figures

It fails for cases like

sigfigs 2, 0.00123;

Ben

Re: significant figures

On Wed, 6 Jan 2010, Ben Morrow wrote:

And for sigfigs 7, 123

The auto-conversion of numbers to strings and back in perl makes it
difficult to manage significant figures without keeping that information
separately. Even something simple like:

\$number = "123.0000";
print "\$number\n";
print \$number + 1.0000 . "\n";
print "\$number" + "1.0000" . "\n";

shows the loss of information about significance. The only printed result
that is correct wrt sig-figs is the first, and that's only because \$number
started as a string and was printed as a string. In the latter two cases,

If you could force perl to keep your numbers in string form and then
overload the math operators to deal with them as strings, you might be
successful...

The other respondent's suggestion to:

\$number = sprintf("%d", \$number); # just in case ...
return \$number if \$sigfigs > length(\$number);

shows an even more amazing lack of understanding of significant figures.
It would return "1" for sigfigs 4, 1.234, which is patently absurd.

Re: significant figures

\$number started as a string and ended as a string.
You should assume that general rules of temporaries still apply ..
even in Perl. In fact, in your above example, \$number was never
alterred, just assigned once.
There was no conversion of \$number at all as this proves:
----
my \$number = "123.0000";
print "\$number\n";
print \$number + 1.0000 . "\n";
print "\$number" + "1.0000" . "\n";
print "Nope, still a string -> ", \$number, "\n";
\$number += "0.0000";
print "Now its a number -> ", \$number, "\n";
----
123.0000
124
124
Nope, still a string -> 123.0000
Now its a number -> 123
----

I don't care what language your in, source code
constants at compile time, are converted to either a number or a string.
"123.0000" is a char(10), and 123.0000 is a float().
In eazy Perl pseudo, its the same as
struct {
char *c;
float f;
... more
TYPE last;
} number;

Temporaries are still the same and conversions only
happen on assignments.
I don't think its too tricky to understand that numeric
operations should be homogenous, and print is just a conversion,
accurate or not, of a temporary, a snapshot of the variable,
in space and time, that has absolutely nothing to do with assigning
to the variable.

There is nothing extrordinary about Perl in that regard, same numeric
base conversion problems as any other language.

In the OP's example code, assuming \$number was passed in as a number,
then this line:  \$number = sprintf "%1.0f", \$number;
is a problem. But it would be no less a problem if done in C++:
number = atof ( sprintf( "%1.0f", number) );
This does not maintain numeric integrity in any language.

-sln

Re: significant figures

On Mon, 11 Jan 2010, sln@netherlands.com wrote:

I did not say that the contents of \$number changed without an assignment,
I said that the value was converted from string to numeric as necessary.

I didn't say it was tricky to understand, and I didn't say that print
assigned anything to anything. 'Print' was there only to show the result
of the operations being performed on the values.

Perl is unique in the sense that it will AUTOMATICALLY convert from string
to number when it is performing operations that require it. Other
languages, at least those I am familiar with, require the programmer to
know which is which and convert as required.

While there was no actual conversion of the stored values in the code I
wrote, it was trivial demo code showing the loss of information by the
operations themselves, and you would expect real code would have a few
assignments saving the incorrect results.