[32124] in Perl-Users-Digest
Perl-Users Digest, Issue: 3389 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun May 22 18:09:24 2011
Date: Sun, 22 May 2011 15:09:06 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 22 May 2011 Volume: 11 Number: 3389
Today's topics:
Re: piping a vraiable content through a filter <hjp-usenet2@hjp.at>
Re: Posting Guidelines for comp.lang.perl.misc ($Revisi <m@rtij.nl.invlalid>
Re: Rounding issue with defined outcome <jurgenex@hotmail.com>
Re: Rounding issue with defined outcome charley@pulsenet.com
Re: Rounding issue with defined outcome <hjp-usenet2@hjp.at>
Re: Rounding issue with defined outcome charley@pulsenet.com
Re: Rounding issue with defined outcome <hjp-usenet2@hjp.at>
Re: Rounding issue with defined outcome sln@netherlands.com
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sat, 21 May 2011 12:03:36 +0200
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: piping a vraiable content through a filter
Message-Id: <slrnitf3fp.jvd.hjp-usenet2@hrunkner.hjp.at>
On 2011-05-13 09:11, Helmut Richter <hhr-m@web.de> wrote:
> On Thu, 12 May 2011, Rainer Weikusat wrote:
>
>> Helmut Richter <hhr-m@web.de> writes:
>>> I have a filter program "filter" which reads from STDIN and writes to
>>> STDOUT. Now I have in a Perl script a variable $filter_in with data
>>> that have to be transformed to $filter_out. An obvious ways to do that
>>> would be
[...]
>>> Can it be done without creating a temporary file?
>>
>> Have a look at IPC::Open3(3pm).
>
> Thanks, this is a valuable hint. There is also
> http://perldoc.perl.org/perlipc.html#Bidirectional-Communication-with-Another-Process
> with a little more explanation.
>
> In my intended application, things are much simpler: there is no real
> two-way communication. The input data is sent once, and the output data is
> received once.
Then the simplest way is to build a pipe in the same way as the shell
does it: One process for the original producer, one for each filter and
finally the the consumer (the parent process), where each filter has
stdin and stdout connected to its predecessor and successor.
If there is only one filter this can be simply achieved with
open($fh, '-|') and open($fh, '|-'):
#!/usr/bin/perl
use warnings;
use strict;
my $child1_pid = open(my $child1_fh, '-|');
die "fork of child1 failed: $!" unless (defined $child1_pid);
if ($child1_pid == 0) {
# we are now in the child.
# stdout is connected to $child1_fh of the parent
my $child2_pid = open(my $child2_fh, '|-');
die "fork of child2 failed: $!" unless (defined $child1_pid);
if ($child2_pid == 0) {
# we are now in the grandchild
# stdin is connected to $child2_fh of the child
# stdout is inherited from the child and therefore connected to
# $child1_fh of the parent.
# so this is the process where we want our filter.
exec('tr', 'a', 'b');
} else {
# still in the child
# our $child2_fh is now connected to the filter, so we can send
# the output
my $line = "a" x 79 . "\n";
my $len = 0;
for (1 .. 100_000) {
print $child2_fh $line;
$len += length($line);
}
close($child2_fh);
#sleep 1;
print STDERR "\n\nwrote $len bytes\n\n";
exit(0);
}
} else {
my $len = 0;
while (<$child1_fh>) {
print;
$len += length($_);
}
print STDERR "\n\nread $len bytes\n\n";
}
__END__
If more than one filter is needed I would use fork() and pipe()
directly.
hp
------------------------------
Date: Sat, 21 May 2011 16:29:35 +0200
From: Martijn Lievaart <m@rtij.nl.invlalid>
Subject: Re: Posting Guidelines for comp.lang.perl.misc ($Revision: 1.9 $)
Message-Id: <fruka8-tpf.ln1@news.rtij.nl>
On Fri, 20 May 2011 01:34:50 -0600, Uno wrote:
(snip over 200 lines)
> I think the frequency of the faqs could be reduced by a binary order of
> magnitude. Then you might hear the crickets.
And you quoted the whole guidelines for those two lines? Hard to take you
seriously.
M4
------------------------------
Date: Fri, 20 May 2011 20:53:44 -0700
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: Rounding issue with defined outcome
Message-Id: <i0det6p5qtfbn70tc4qeputnbmac3isgup@4ax.com>
Bart Van der Donck <bart@nijlen.com> wrote:
>I have to deal with a rounding issue which basically goes back to high-
>precision calculations.
Actually it doesn't. It goes back to understanding how calculations
work, e.g. basic computer numeric as well as basic rules for accounting.
>The issue is that the outcome is already known
>and should match.
Then you should follow the same processes and rules that resulted in the
already known outcome.
[...]
>- Is there any way to perform the calculations at extreme
> high precision,
Yes, it is called symbolic calculations and there are more or less
expensive computer programs out there that do those. But that doesn't
help you one bit, because ...
>so that all caculated alphanumerics match ?
... the already known outcome was not computed using extreme high
precision, either.
>- I have a known outcome (let's say eg. 8577.77) which was
> done already in javascript by another application; is there
> a way to guarantee that both outcomes are identical ?
Yes. Use the same rules as have been used in the other application.
>- I have the feeling that this is maybe a common situation,
Yes. It is the misguided believe that higher precision equals better
results. THAT IS NOT THE CASE.
You should do your computations using the same method that was used in
the other application using the same precision and the same mathematical
operators with the same behaviour and the same algorithm.
In your case you should specifically check with accountants about how
sums are computed. Trivial example: if the commision is computed for
each individual transaction, listed in e.g. Euro and Cent, and then
added, then you will usually get a different result compared to adding
all transactions and then computing the commision on the total sales.
> are there 'classical' approaches for this kind of things ?
Yes, see Introduction into Basic Numerics for Computer Scientists
>- If I want to manually check the order, the calculations
> must match (e.g. 'Net'+'Tax' must equal to 'Brut')
Then you need to calculate them the same way as they were calculated in
the other application..
jue
------------------------------
Date: Sat, 21 May 2011 14:52:37 -0700 (PDT)
From: charley@pulsenet.com
Subject: Re: Rounding issue with defined outcome
Message-Id: <a1ebc0ee-3590-4fe9-9410-ff7635afd3e8@l30g2000vbn.googlegroups.com>
On May 13, 7:19=A0am, Bart Van der Donck <b...@nijlen.com> wrote:
> Hello,
>
> I have to deal with a rounding issue which basically goes back to high-
> precision calculations. The issue is that the outcome is already known
> and should match.
[snip code]
> Questions:
> ----------------------------------------------------------------
>
> - Is there any way to perform the calculations at extreme
> =A0 high precision, so that all caculated alphanumerics match ?
convert to cents I think.
Then when ready to output, convert back to dollars (do not use sprintf
"%.2f").
Instead, use the substitution operator:
# Convert to pennies from dollars.
# $price is now an integer
$price =3D~ s/\.(?=3D\d\d$)// or die "Cannot expand $price to integer.
$!";
# convert from pennies to dollars, (insert decimal point), for
output.
s/(\d\d)$/.$1/ for $price, $net, $brut;
>
> - I have a known outcome (let's say eg. 8577.77) which was
> =A0 done already in javascript by another application; is there
> =A0 a way to guarantee that both outcomes are identical ?
>
> - I have the feeling that this is maybe a common situation,
> =A0 are there 'classical' approaches for this kind of things ?
>
> - If I want to manually check the order, the calculations
> =A0 must match (e.g. 'Net'+'Tax' must equal to 'Brut')
>
> Thank you,
>
> --
> =A0Bart
Hi Bart,
FWIW, I believe my code (below) exhibits Pennsylvania's sales tax.
#!/usr/bin/perl
use strict;
use warnings;
use 5.012;
use POSIX qw/ ceil /;
for my $cents (1 .. 111) {
my $tax =3D ceil($cents * .06);
my $scale =3D $cents % 100;
$tax-- if $scale >=3D 1 && $scale <=3D 10;
say "$cents $tax";
}
Note that this state (perhaps others too) take the 'ceil(ing)' of the
cents. (Use cents because I am now dealing with integers). Then it is
necessary to convert back to dollars for output purposes.
Chris
------------------------------
Date: Sun, 22 May 2011 00:15:43 +0200
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: Rounding issue with defined outcome
Message-Id: <slrnitgecf.9rv.hjp-usenet2@hrunkner.hjp.at>
On 2011-05-21 21:52, charley@pulsenet.com <charley@pulsenet.com> wrote:
> convert to cents I think.
> Then when ready to output, convert back to dollars (do not use sprintf
> "%.2f").
Why not? Can you show a case where it produces the wrong result?
OTOH:
> # convert from pennies to dollars, (insert decimal point), for
> output.
> s/(\d\d)$/.$1/ for $price, $net, $brut;
This will not work for amount <= 99 cents.
> my $tax = ceil($cents * .06);
my $tax = ceil($cents * 6 / 100);
otherwise you multiply with
0.059999999999999997779553950749686919152736663818359375 which may or
may not make a difference.
hp
------------------------------
Date: Sat, 21 May 2011 16:55:27 -0700 (PDT)
From: charley@pulsenet.com
Subject: Re: Rounding issue with defined outcome
Message-Id: <13eb8f4b-f844-4f9b-836b-dbb6dabc72df@g3g2000vbl.googlegroups.com>
On May 21, 6:15=A0pm, "Peter J. Holzer" <hjp-usen...@hjp.at> wrote:
> On 2011-05-21 21:52, char...@pulsenet.com <char...@pulsenet.com> wrote:
>
> > convert to cents I think.
> > Then when ready to output, convert back to dollars (do not use sprintf
> > "%.2f").
>
> Why not? Can you show a case where it produces the wrong result?
No, I was assuming that by avoiding the sprintf I could avoid a
rounding error.
>
> OTOH:
>
> > =A0 =A0 =A0 =A0 # convert from pennies to dollars, (insert decimal poin=
t), for
> > output.
> > =A0 =A0s/(\d\d)$/.$1/ for $price, $net, $brut;
>
> This will not work for amount <=3D 99 cents.
Good catch. I think you meant it will not work for <=3D 9 cents. No
match and no placement of the decimal point. I should have been more
careful in uncharted (for me) territory. s/(\d\d?)$/.$1/ would be the
correct answer I believe?
>
> > =A0 =A0my $tax =3D ceil($cents * .06);
>
> =A0 =A0 =A0 =A0 my $tax =3D ceil($cents * 6 / 100);
>
> otherwise you multiply with
> 0.059999999999999997779553950749686919152736663818359375 which may or
> may not make a difference.
0 for 3. Not very good.
>
> =A0 =A0 =A0 =A0 hp
------------------------------
Date: Sun, 22 May 2011 16:51:08 +0200
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: Rounding issue with defined outcome
Message-Id: <slrniti8ms.i6q.hjp-usenet2@hrunkner.hjp.at>
On 2011-05-21 23:55, charley@pulsenet.com <charley@pulsenet.com> wrote:
> On May 21, 6:15 pm, "Peter J. Holzer" <hjp-usen...@hjp.at> wrote:
>> On 2011-05-21 21:52, char...@pulsenet.com <char...@pulsenet.com> wrote:
>>
>> > convert to cents I think.
>> > Then when ready to output, convert back to dollars (do not use sprintf
>> > "%.2f").
>>
>> Why not? Can you show a case where it produces the wrong result?
>
> No, I was assuming that by avoiding the sprintf I could avoid a
> rounding error.
If you use sprintf("%.2f", $x/100) there will indeed be a rounding error
in the computation of $x/100 and possibly another one in rounding two
digits. Those rounding errors will be somewhere in the magnitude of
$x/100/2**53 (assuming IEEE double precision floating point arithmetic),
and as long as that error is less than 0.005, it won't affect the
result. So $x/100/2**53 <= 0.005, therefore $x <= 0.005 * 2**53 * 100
or $x <= 4.5E15. Lets be conservative and say you're safe if $x is less
than 1E14.
>> OTOH:
>>
>> > # convert from pennies to dollars, (insert decimal point), for
>> > output.
>> > s/(\d\d)$/.$1/ for $price, $net, $brut;
>>
>> This will not work for amount <= 99 cents.
>
> Good catch. I think you meant it will not work for <= 9 cents. No
> match and no placement of the decimal point.
Actually I meant <= 99 cents, but I realize that there are locales where
".99" (instead of "0.99") is correct. So if your bean counter doesn't
throw a hissy fit over the missing zero, that's ok. For <= 9 cents it's
always incorrect.
> I should have been more careful in uncharted (for me) territory.
> s/(\d\d?)$/.$1/ would be the correct answer I believe?
No that converts 9 to ".9" instead of ".09".
This would work:
for my $cents (9, 99, 999, 999_999_999_999) {
my $dollars = sprintf("%03.0f", $cents);
$dollars =~ s/(\d\d)$/.$1/;
print "$cents -> $dollars\n";
}
hp
------------------------------
Date: Sun, 22 May 2011 11:24:07 -0700
From: sln@netherlands.com
Subject: Re: Rounding issue with defined outcome
Message-Id: <opjit69g1qdve8vk8tgu386murcoejvk2p@4ax.com>
On Fri, 13 May 2011 04:19:39 -0700 (PDT), Bart Van der Donck <bart@nijlen.com> wrote:
[snip code]
>----------------------------------------------------------------
>Output:
>----------------------------------------------------------------
>
>PROD PRICE QUANT NET TAX BRUT
>Screen 661.60 4 2646.41 21% 3202.15
>Cables 556.12 5 2780.58 21% 3364.50
>Server 764.92 1 764.92 21% 925.55
>Battery 76.61 3 229.84 21% 278.11
>Keyb. 58.11 2 116.22 21% 140.62
>Mouse 19.93 6 119.59 21% 144.70
>Battery 86.30 5 431.50 21% 522.11
>
>Net: 7089.05
>Tax: 1488.70
>Brut: 8577.74
>
>----------------------------------------------------------------
>Questions:
>----------------------------------------------------------------
>
>- Is there any way to perform the calculations at extreme
> high precision, so that all caculated alphanumerics match ?
>
>- I have a known outcome (let's say eg. 8577.77) which was
> done already in javascript by another application; is there
> a way to guarantee that both outcomes are identical ?
>
>- I have the feeling that this is maybe a common situation,
> are there 'classical' approaches for this kind of things ?
>
>- If I want to manually check the order, the calculations
> must match (e.g. 'Net'+'Tax' must equal to 'Brut')
>
>Thank you,
There could be a typo in your numbers/code.
If the Brut total were to be 8577.77 , the Net and Tax totals
would be significantly alterred. So, I asume you are not giving
the exact input/output from the code where you state the known
outcome of the Brut total of 8577.77
The reason I know this is that :
1) Net/Tax/Brut intermediate values are all interrelated.
2) Applying arithmetic significance of measured values do not
alter the results.
ie.. percent ~ 1.2958685 does not alter the outcome (a measured value)
factor ~ 0.8567 is the least significant (also a measured value)
3) Applying sprintf "%.4f" to $brut intermediate raises the Brut total
at the expence of Tax and Net. Even then, it only raises Brut to 8577.75
4) Rounding percent and factor to make Brut fit in the 8577.77 range,
significantly alters Tax and Net.
I think its probable there is some other non-mathmatical error going on here.
-sln
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3389
***************************************