在 Perl 中处理美元计算的最佳技术是什么?

发布于 2024-08-02 04:03:57 字数 227 浏览 10 评论 0原文

在 Perl 中处理美元计算的最佳技术是什么?

特别是:以下需要工作:

$balance = 10;
$payment = $balance / 3; # Each payment should be 3.33. How best to round amount?
$balance -= $payment * 3;
# assert: $balance == .01

What's the best technique for handling US Dollar calculations in Perl?

Especially: the following needs to work:

$balance = 10;
$payment = $balance / 3; # Each payment should be 3.33. How best to round amount?
$balance -= $payment * 3;
# assert: $balance == .01

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诠释孤独 2024-08-09 04:03:57

一种常见的技术是以整数美分进行所有计算,然后转换为美元和美分进行输出。 因此,您的 10 美元余额将表示为 1000(美分),除以三得到 333,即 3.33 美元。

但是,如果您想将 10 美元的付款除以三,则需要某种方法来最终获得 3.33 美元、3.33 美元和3.34 美元的付款。 这将更多地取决于您的应用程序逻辑和业务规则,而不是您的语言的算术功能。

One common technique is to do all calculations in integer cents, then convert to dollars and cents for output. So your $10 balance would be represented by 1000 (cents), and dividing by three gives 333, or $3.33.

However, if you want to divide a $10 payment by three, you will need some way to end up with payments of $3.33, $3.33, and $3.34. This will be more up to your application logic and business rules than the arithmetic features of your language.

强辩 2024-08-09 04:03:57

请参阅Math::Currency

更新:

假设所有付款加起来等于余额是可取的,我根据 Greg Hewgill 提出的观点

#!/usr/bin/perl

use strict;
use warnings;

use List::Util qw( sum );

my @balances = (10, 1, .50, 5, 7, 12, 3, 2, 8, 1012);

for my $balance (@balances) {
    my @stream = get_payment_stream($balance, 3);
    my $sum = sum @stream;
    print "$balance : @stream : $sum\n";
}

sub get_payment_stream {
    my ($balance, $installments) = @_;
    $balance *= 100;
    my $payment = int($balance / $installments);
    $installments -= 1;
    my $residual = $balance - int($payment * $installments);
    my @stream = (($payment) x $installments, $residual);
    return map { sprintf '%.2f', $_ / 100} @stream;
}

输出:

C:\Temp> p
10 : 3.33 3.33 3.34 : 10
1 : 0.33 0.33 0.34 : 1
0.5 : 0.16 0.16 0.18 : 0.5
5 : 1.66 1.66 1.68 : 5
7 : 2.33 2.33 2.34 : 7
12 : 4.00 4.00 4.00 : 12
3 : 1.00 1.00 1.00 : 3
2 : 0.66 0.66 0.68 : 2
8 : 2.66 2.66 2.68 : 8
1012 : 337.33 337.33 337.34 : 1012

See Math::Currency.

Updated:

Assuming all payments adding up to the balance is desirable, I came up with the following script based on the points made by Greg Hewgill:

#!/usr/bin/perl

use strict;
use warnings;

use List::Util qw( sum );

my @balances = (10, 1, .50, 5, 7, 12, 3, 2, 8, 1012);

for my $balance (@balances) {
    my @stream = get_payment_stream($balance, 3);
    my $sum = sum @stream;
    print "$balance : @stream : $sum\n";
}

sub get_payment_stream {
    my ($balance, $installments) = @_;
    $balance *= 100;
    my $payment = int($balance / $installments);
    $installments -= 1;
    my $residual = $balance - int($payment * $installments);
    my @stream = (($payment) x $installments, $residual);
    return map { sprintf '%.2f', $_ / 100} @stream;
}

Output:

C:\Temp> p
10 : 3.33 3.33 3.34 : 10
1 : 0.33 0.33 0.34 : 1
0.5 : 0.16 0.16 0.18 : 0.5
5 : 1.66 1.66 1.68 : 5
7 : 2.33 2.33 2.34 : 7
12 : 4.00 4.00 4.00 : 12
3 : 1.00 1.00 1.00 : 3
2 : 0.66 0.66 0.68 : 2
8 : 2.66 2.66 2.68 : 8
1012 : 337.33 337.33 337.34 : 1012
删除→记忆 2024-08-09 04:03:57

使用数学::货币;

不重新发明轮子是一件好事:)

use Math::Currency;

Not reinventing the wheel is a good thing :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文