NSDecimalNumber 舍入

发布于 2024-09-28 18:44:06 字数 350 浏览 4 评论 0原文

我很难弄清楚一些看起来应该很简单的事情。我需要将 NSDecimalNumber 精确舍入到特定的小数位数(在运行时确定)。据我所知,我有两个选择,但我都不喜欢。

  1. 转换为浮点数,并使用 C 舍入函数:我不喜欢这样做,因为在这种情况下准确性很重要。浮点数并不总是准确地表示十进制数,这可能会导致问题。
  2. 使用 NSNumberFormatter 转换为字符串,然后再转换回来:我不喜欢这个,因为它看起来丑陋且效率低下。

还有我错过的另一种方式吗?有一种简单的方法可以对 NSDecimalNumbers 进行舍入,但我似乎无法弄清楚它是什么。

I'm having the hardest time figuring out something that seems like it should be very simple. I need to accurately round an NSDecimalNumber to a particular number of decimal places (determined at runtime.) So far as I can tell, I have two options, neither of which I like.

  1. Convert to a float, and use C rounding functions: I don't like this because accuracy matters in this case. Floats can't always accurately represent decimal numbers, and this could cause problems.
  2. Convert to a string using NSNumberFormatter and then convert back: I don't like this one because it just seems ugly and inefficient.

Is there another way that I've missed? There has got to be an easy way to do rounding of NSDecimalNumbers, but I can't seem to figure out for the life of me what it is.

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

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

发布评论

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

评论(4

药祭#氼 2024-10-05 18:44:06

您只需使用所需的 NSDecimalNumberBehaviors 协议调用 decimalNumberByRoundingAccordingToBehavior: 即可。请参阅 开发文档

更新:请参阅 http ://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like-me/

You simply call decimalNumberByRoundingAccordingToBehavior:with the desired NSDecimalNumberBehaviors protocol. See the NSDecimalNumberBehaviors reference in the dev docs.

Update: See http://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like-me/

温柔戏命师 2024-10-05 18:44:06

对于那些喜欢示例代码的人...

舍入到小数点后两位 (12345.68):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:2
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];

舍入到最接近的千位 (12000):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:-3
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];

For those that prefer example code...

To round to 2 decimal places (12345.68):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:2
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];

To round to the nearest thousand (12000):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:-3
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];
请你别敷衍 2024-10-05 18:44:06

我在 Swift 3 中使用下面的代码让它工作。

let amount = NSDecimalNumber(string: "123.456789")
let handler = NSDecimalNumberHandler(roundingMode: .plain, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)
let roundedAmount = amount.rounding(accordingToBehavior: handler)

注意比例参数,用于定义您需要的小数位。此处概述: https://developer.apple.com/reference/foundation/nsdecimalnumberhandler/ 1578295-带舍入的十进制数字处理程序

I got it working using the below code in Swift 3.

let amount = NSDecimalNumber(string: "123.456789")
let handler = NSDecimalNumberHandler(roundingMode: .plain, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)
let roundedAmount = amount.rounding(accordingToBehavior: handler)

Note the scale parameter, used to define the decimal places you need. Outlined here: https://developer.apple.com/reference/foundation/nsdecimalnumberhandler/1578295-decimalnumberhandlerwithrounding

空城旧梦 2024-10-05 18:44:06

我正在使用这个解决方案:

import Foundation

extension NSDecimalNumber {
    public func round(_ decimals:Int) -> NSDecimalNumber {
        return self.rounding(accordingToBehavior:
            NSDecimalNumberHandler(roundingMode: .plain,
                                   scale: Int16(decimals),
                                   raiseOnExactness: false,
                                   raiseOnOverflow: false,
                                   raiseOnUnderflow: false,
                                   raiseOnDivideByZero: false))
    }
}

let amount = NSDecimalNumber(string: "123.456")

amount.round(2)  --> 123.46
amount.round(1)  --> 123.5
amount.round(0)  --> 123
amount.round(-1) --> 120
amount.round(-2) --> 100

I'm using this solution:

import Foundation

extension NSDecimalNumber {
    public func round(_ decimals:Int) -> NSDecimalNumber {
        return self.rounding(accordingToBehavior:
            NSDecimalNumberHandler(roundingMode: .plain,
                                   scale: Int16(decimals),
                                   raiseOnExactness: false,
                                   raiseOnOverflow: false,
                                   raiseOnUnderflow: false,
                                   raiseOnDivideByZero: false))
    }
}

let amount = NSDecimalNumber(string: "123.456")

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