我正在嘗試正確減小比例,格式化浮點值并將其作為 Swift 中的字串回傳。
例如:
let value: Float = 4.8962965
// formattedFalue should be 4.90 or 4,90 based on localization
let formattedValue = value.formatNumber()
這是我所做的:
extension Float {
func reduceScale(to places: Int) -> Float {
let multiplier = pow(10, Float(places))
let newDecimal = multiplier * self // move the decimal right
let truncated = Float(Int(newDecimal)) // drop the fraction
let originalDecimal = truncated / multiplier // move the decimal back return originalDecimal
}
func formatNumber() -> String {
let num = abs(self)
let numberFormatter = NumberFormatter()
numberFormatter.usesGroupingSeparator = true
numberFormatter.minimumFractionDigits = 0
numberFormatter.maximumFractionDigits = 2
numberFormatter.roundingMode = .up
numberFormatter.numberStyle = .decimal
numberFormatter.locale = // we take it from app settings
let formatted = num.reduceScale(to: 2)
let returningString = numberFormatter.string(from: NSNumber(value: formatted))!
return "\(returningString)"
}
}
但是當我使用此代碼時,我得到 4.89(或 4,89,具體取決于本地化),而不是我期望的 4.90(或 4,90)。
提前致謝。
uj5u.com熱心網友回復:
您得到 4.89 是因為reduceScale(to:)
將數字轉換為4.89
(實際上,可能是4.89000something
因為 4.89 不能完全表示為二進制浮點數)。當數字格式化程式將其截斷到小數點后兩位時,它自然會向下舍入。
事實上,您根本不需要reduceScale(to:)
,因為數字格式化程式的舍入功能會為您完成。
最后的字串插值也是不必要的,因為結果NumberFormatter.string(from:)
會自動橋接到String?
此外(請參閱下面 Dávid Pásztor 和 Sulthan 的評論),您可以使用它string(for:)
來避免NSNumber
轉換。
這就是你需要的
import Foundation
extension Float {
func formatNumber() -> String {
let num = abs(self)
let numberFormatter = NumberFormatter()
numberFormatter.usesGroupingSeparator = true
numberFormatter.minimumFractionDigits = 0
numberFormatter.maximumFractionDigits = 2
numberFormatter.roundingMode = .up
numberFormatter.numberStyle = .decimal
numberFormatter.locale = whatever
return numberFormatter.string(for: num)!
}
}
let value: Float = 4.8962965
// formattedFalue should be 4.90 or 4,90 based on localization
let formattedValue = value.formatNumber() // "4.9"
uj5u.com熱心網友回復:
通過以下Sulthan的評論解決:
洗掉
reduceScale
不需要的方法,它可能會按預期作業。您正在截斷4.89
不能再四舍五入的小數(它已經四舍五入了)。–蘇丹 6 小時前
那是因為你已經指定了
minimumFractionDigits = 0
. 如果您總是想顯示兩位小數,則必須設定minimumFractionDigits = 2
. –蘇丹 5 小時前
uj5u.com熱心網友回復:
Foundation
現在有更好的 API。
就地,您可以使用.number
:
value.formatted(.number
.precision(.fractionLength(2))
.locale(locale)
)
但它僅適用于特定型別。對于多個浮點型別的擴展,您需要使用等效的初始化程式:
extension BinaryFloatingPoint {
var formattedTo2Places: String {
formatted(FloatingPointFormatStyle()
.precision(.fractionLength(2))
.locale(locale)
)
}
}
let locale = Locale(identifier: "it")
(4.8962965 as Float).formattedTo2Places // 4,90
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/526035.html
標籤:迅速