NSNumberFormatter 和 .floor roundingMode

发布于 2025-01-13 07:09:18 字数 653 浏览 2 评论 0原文

有人能告诉我为什么会发生这种情况吗?

let formatter = NumberFormatter.init()
formatter.numberStyle = .decimal
formatter.usesGroupingSeparator = false
formatter.roundingMode = .floor
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2

let v = 36
let scale = 10


let float = formatter.string(from: NSNumber(value: Float(v) / Float(scale)))!
let double = formatter.string(from: NSNumber(value: Double(v) / Double(scale)))!

print(float)    // 3.59
print(double)   // 3.60

当我使用 Float 时,结果是 3.59(我认为结果是错误的),当我使用 Double 时,结果是 3.60。

我知道这与 .floor roundingMode 有关,但我不完全理解原因。

Can someone tell me why this happening?

let formatter = NumberFormatter.init()
formatter.numberStyle = .decimal
formatter.usesGroupingSeparator = false
formatter.roundingMode = .floor
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2

let v = 36
let scale = 10


let float = formatter.string(from: NSNumber(value: Float(v) / Float(scale)))!
let double = formatter.string(from: NSNumber(value: Double(v) / Double(scale)))!

print(float)    // 3.59
print(double)   // 3.60

When I use Float the result is 3.59 (wrong result in my opinion) and when I use Double the result is 3.60.

I know it is something related to .floor roundingMode, but i don't fully understand the reason.

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

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

发布评论

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

评论(1

日久见人心 2025-01-20 07:09:18

如果您想保留分数数字精度,最好使用 Swift 原生 Decimal 类型。就是这样。您可以使用 Decimal init(sign: FloatingPointSign, exponent: Int,significand: Decimal) 初始值设定项并使用小数位数指数和值有效数。只要确保否定它的值:

extension SignedInteger {
    var negated: Self { self * -1 }
}

let v = 36
let scale = 10
let sign: FloatingPointSign = v >= 0 ? .plus : .minus
let exponent = Decimal(scale).exponent.negated
let significand = Decimal(v).significand
let decimal = Decimal.init(sign: sign, exponent: exponent, significand: significand)
let formatted = formatter.string(for: decimal)   // "3.60"

If you would like to preserve your fraction digits precision it is better to use Swift native Decimal type. That's what it is. You can use the Decimal init(sign: FloatingPointSign, exponent: Int, significand: Decimal) initializer and use your scale exponent and your value significand. Just make sure to negate its value:

extension SignedInteger {
    var negated: Self { self * -1 }
}

let v = 36
let scale = 10
let sign: FloatingPointSign = v >= 0 ? .plus : .minus
let exponent = Decimal(scale).exponent.negated
let significand = Decimal(v).significand
let decimal = Decimal.init(sign: sign, exponent: exponent, significand: significand)
let formatted = formatter.string(for: decimal)   // "3.60"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文