是否有方法覆盖Double,使其在swift中默认为每两个双精度值2个小数位?

是否有方法覆盖Double,使其在swift中默认为每两个双精度值2个小数位?,swift,double,overriding,decimal,Swift,Double,Overriding,Decimal,我正在用swift 4编写一个应用程序,我不想每次创建double时都对double值进行四舍五入。默认情况下,我希望将其设置为小数点后2位 双重值将全部用于货币显示/保存目的 例如,10.00美元,而是像:10.0一样节省 我正在寻找可以覆盖双重功能的东西 提前感谢您的帮助我可以为您的问题提出两种解决方案。但我不确定他们是否能满足你的需要。首先是覆盖Double货币值变量的didSet,如下所示: var currencyValue: Double = 0.0 { didSet {

我正在用swift 4编写一个应用程序,我不想每次创建double时都对double值进行四舍五入。默认情况下,我希望将其设置为小数点后2位

双重值将全部用于货币显示/保存目的

例如,10.00美元,而是像:10.0一样节省

我正在寻找可以覆盖双重功能的东西


提前感谢您的帮助

我可以为您的问题提出两种解决方案。但我不确定他们是否能满足你的需要。首先是覆盖
Double
货币值变量的
didSet
,如下所示:

var currencyValue: Double = 0.0 {
   didSet {
        // Do the rounding
        let divisor = pow(10.0, 2) // 2 is the place number

        currencyValue = (currencyValue * divisor).rounded() / divisor
   }
}
第二种方法是使用
extensions
Double
创建一个新的
init
函数,该函数立即进行取整

extension Double {

    init(value: Double, roundTo places: Double) {
        let divisor = pow(10.0, places)

        self = (value * divisor).rounded() / divisor
    }
}
// Use the extension initialization
Double(value: 10.22, roundTo: 2)
虽然这些可以作为解决方案,但我必须同意。使用
NumberFormatter
可以让您轻松地在本地格式化货币。希望这有帮助

编辑:

所以,为了实现你真正想要的,我们需要做一些小的调整。我将更新覆盖方法:

var currencyValue: String = "0.00" {
   get {
        // Convert String value to Double
        let doubleValue = Double(currencyValue)

        // Do the rounding
        let divisor = pow(10.0, 2) // 2 is the place number

        doubleValue = (doubleValue * divisor).rounded() / divisor

        // Format the number
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = NumberFormatter.Style.decimal
        numberFormatter.minimumFractionDigits = 2 // We want at least 2 decimal places
        if let formattedString = numberFormatter.string(from: NSNumber(doubleValue)) {
             return formattedString
        }

        return currencyValue
   }
} 
您可以这样使用它:

var double = 10.2
currencyValue = "\(double)" // Setting the double value as String
print(currencyValue) // will print 10.20
它是一个仅与货币相关的应用程序。因此,我不希望每次都处理舍入函数,而是希望能够在默认情况下处理它

对于货币应用程序,最好避免
Float
&
Double
。这些类型基于二进制浮点数,不精确到小数点

例如,取34美分/便士/任何货币,其中100美分等于1美元/英镑/任何货币,那么你可以用小数点0.34表示,或者用3/10+4/100表示1/(10^n)分数的总和。现在二进制浮点(和定点)使用1/(2^n)个分数的和。所以34/100=1/4(25/100)+9/100=1/4+1/16+275/10000=1/4+1/16+1/64+。。。(此总和可以是有限的,也可以是无限的,具体取决于小数点)

请注意,考虑到这个二进制基数,您要求有两个小数位是不可能的,因为无论您将自己限制为小数点的位数是多少,某些小数位都是不精确的

那么解决方案是什么呢?整数(或定点数字,见下文)

如果您只需要支持十进制货币,即小单位是大单位的1/100(如美元/美分、英镑/便士),那么您可以简单地使用足够大的整数,并将金额保持在小单位。例如,将12.34美元存储为1234美分。若你们需要更高的精度(比如说你们在计算股价等),你们可以将你们的值存储为小单位的一些(十进制)部分,比如1/100美分。这样,所有计算都使用精确的整数算术运算。对于字符串转换,您需要添加/删除货币点,然后进行整数转换,或者使用余数/除法将存储的值拆分为其组件并格式化每个组件

如果您需要支持非十进制货币,或者您需要的范围比存储为最大整数类型中允许的较小单位(部分)的范围更大,那么您可以将大单位和小单位存储为两个整数值,并自行处理它们之间的进位操作

您可以在Swift中将操作包装为值(
struct
)类型

有些语言支持十进制定点算法,或者提供了类似于我们刚才描述的库;如果你看的话,那里可能有一个斯威夫特图书馆。(例如,请参见Python的链接,该链接还涵盖了上面解释的要点。)

如果您希望继续使用可用的类型,请查看使用
Decimal
,这是一种十进制浮点类型,提供38位十进制精度。它不是专门为货币设计的,但您可以使用
NSDecimalRound
将数字保留到所需的小数位数(甚至支持四舍五入);为了满足您自动执行此操作的特定要求,您必须包装/扩展并实现您自己的运算符,该运算符将标准运算符与四舍五入合并到所需的位数


希望这对你的帮助大于困惑

没有必要每两个回合都进行一次。只要在需要向用户显示double时使用适当的
NumberFormatter
。您是否使用这两个小数位来表示货币值?CRD,是的。它是一个仅与货币相关的应用程序。因此,我不希望每次都处理舍入函数,而是希望能够在默认情况下执行。@Smartcat,我以前看过这篇文章,不幸的是,这不是我想要的。为了更清楚,我编辑了我的问题。虽然你的答案与我想要的很接近,但它仍然不适用于10.00美元这样的值。无论如何,我想我会听取你和@rmaddy的建议,使用NumberFormatter。这是额外的工作,但很有效。谢谢你的建议。我要试试