如何在 Perl 中对浮点数进行四舍五入?
如何将小数(浮点)四舍五入到最接近的整数?
例如
1.2 = 1
1.7 = 2
How can I round a decimal number (floating point) to the nearest integer?
e.g.
1.2 = 1
1.7 = 2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
perldoc -q 轮
Output of
perldoc -q round
虽然不同意有关中途标记等的复杂答案,但对于更常见(也可能是微不足道)的用例:
my $rounded = int($float + 0.5);
更新
如果您的
$float
可能为负数,则以下变体将产生正确的结果:my $rounded = int($float + $float/abs( $float*2 || 1));
通过此计算,-1.4 舍入为 -1,-1.6 舍入为 -2,并且零不会爆炸。
Whilst not disagreeing with the complex answers about half-way marks and so on, for the more common (and possibly trivial) use-case:
my $rounded = int($float + 0.5);
UPDATE
If it's possible for your
$float
to be negative, the following variation will produce the correct result:my $rounded = int($float + $float/abs($float*2 || 1));
With this calculation -1.4 is rounded to -1, and -1.6 to -2, and zero won't explode.
您可以使用 Math::Round 之类的模块:
或者您也可以粗略地进行方式:
You can either use a module like Math::Round:
Or you can do it the crude way:
如果您决定使用 printf 或 sprintf,请注意它们使用 Round half to Even 方法。
If you decide to use printf or sprintf, note that they use the Round half to even method.
请参阅 perldoc/perlfaq:
See perldoc/perlfaq:
您不需要任何外部模块。
我可能没有理解你的观点,但我认为这是完成同样工作的更干净的方法。
其作用是遍历元素中的每个正数,以您提到的格式打印数字和舍入整数。 该代码仅根据小数连接相应的四舍五入正整数。 int($_) 基本上是对数字进行四舍五入,因此 ($-int($)) 捕获小数。 如果小数(根据定义)严格小于 0.5,则将数字向下舍入。 如果不是,则向上舍入加 1。
You don't need any external module.
I may be missing your point, but I thought this was much cleaner way to do the same job.
What this does is to walk through every positive number in the element, print the number and rounded integer in the format you mentioned. The code concatenates respective rounded positive integer only based on the decimals. int($_) basically round-down the number so ($-int($)) captures the decimals. If the decimals are (by definition) strictly less than 0.5, round-down the number. If not, round-up by adding 1.
以下将正数或负数四舍五入到给定的小数位:
The following will round positive or negative numbers to a given decimal position:
以下是对值求和的五种不同方法的示例。 第一种是执行求和的简单方法(并且失败)。 第二个尝试使用 sprintf(),但也失败了。 第三个成功使用了
sprintf()
,而最后两个(第四和第五)则使用了floor($value + 0.5)
。请注意,
floor($value + 0.5)
可以替换为int($value + 0.5)
以消除对POSIX
的依赖。Following is a sample of five different ways to summate values. The first is a naive way to perform the summation (and fails). The second attempts to use
sprintf()
, but it too fails. The third usessprintf()
successfully while the final two (4th & 5th) usefloor($value + 0.5)
.Note that
floor($value + 0.5)
can be replaced withint($value + 0.5)
to remove the dependency onPOSIX
.负数可能会增加一些人们需要注意的怪癖。
printf 风格的方法为我们提供了正确的数字,但它们可能会导致一些奇怪的显示。 我们发现这个方法(在我看来是愚蠢的)放入了一个
-
符号,无论它是否应该。 例如,-0.01 四舍五入到小数点后一位会返回 -0.0,而不仅仅是 0。如果您打算使用printf
样式方法,并且您知道不需要小数,请使用%d
而不是%f
(当您需要小数时,显示就会变得不稳定)。虽然它是正确的,并且对于数学来说没什么大不了的,但对于显示来说,显示“-0.0”之类的东西看起来很奇怪。
对于 int 方法,负数可以改变您想要的结果(尽管有一些参数可以使其正确)。
int + 0.5
会导致负数出现真正的问题,除非您希望它以这种方式工作,但我想大多数人都不会这样做。 -0.9 可能应该四舍五入到 -1,而不是 0。如果您知道您希望负数成为上限而不是下限,那么您可以在一行中完成,否则,您可能需要使用带有小数的 int 方法修改(这显然只能用于获取整数:Negative numbers can add some quirks that people need to be aware of.
printf
-style approaches give us correct numbers, but they can result in some odd displays. We have discovered that this method (in my opinion, stupidly) puts in a-
sign whether or not it should or shouldn't. For example, -0.01 rounded to one decimal place returns a -0.0, rather than just 0. If you are going to do theprintf
style approach, and you know you want no decimal, use%d
and not%f
(when you need decimals, it's when the display gets wonky).While it's correct and for math no big deal, for display it just looks weird showing something like "-0.0".
For the int method, negative numbers can change what you want as a result (though there are some arguments that can be made they are correct).
The
int + 0.5
causes real issues with -negative numbers, unless you want it to work that way, but I imagine most people don't. -0.9 should probably round to -1, not 0. If you know that you want negative to be a ceiling rather than a floor then you can do it in one-liner, otherwise, you might want to use the int method with a minor modification (this obviously only works to get back whole numbers:如果您只关心从整个浮点数(即 12347.9999 或 54321.0001)中获取整数值,则这种方法(从上面借用并修改)可以解决问题:
If you are only concerned with getting an integer value out of a whole floating point number (i.e. 12347.9999 or 54321.0001), this approach (borrowed and modified from above) will do the trick:
我的 sprintf 解决方案
My solution for sprintf
在阅读大量有关如何对数字进行舍入的文档后,许多专家建议编写自己的舍入例程,因为随您的语言提供的“固定”版本可能不够精确或包含错误。 然而,我想他们谈论的是许多小数位,而不仅仅是一位、两位或三位。 考虑到这一点,这是我的解决方案(虽然不完全按照我的需要显示美元的要求 - 但过程没有太大不同)。
loads of reading documentation on how to round numbers, many experts suggest writing your own rounding routines, as the 'canned' version provided with your language may not be precise enough, or contain errors. i imagine, however, they're talking many decimal places not just one, two, or three. with that in mind, here is my solution (although not EXACTLY as requested as my needs are to display dollars - the process is not much different, though).
使用
Math::BigFloat
你可以这样做:这可以包含在子例程中
Using
Math::BigFloat
you can do something like this:This can be wrapped in a subroutine