将双精度值四舍五入为快速小数位数的x位

vwoqyblh  于 2022-09-19  发布在  Swift
关注(0)|答案(30)|浏览(265)

谁能告诉我如何在SWIFT中将双精度值舍入到小数点后x位?

我有:

var totalWorkTimeInHours = (totalWorkTime/60/60)

其中totalWorkTime为NSTimeInterval(双精度),单位为秒。

totalWorkTimeInHours会给我小时数,但它给了我如此长的精确数字中的时间量,例如1.543240952039......

当我打印totalWorkTimeInHours时,如何将其四舍五入为1.543?

ds97pgxw

ds97pgxw16#

您可以使用SWIFT的round函数来完成此操作。

要以3位精度对Double进行舍入,首先将其乘以1000,再对其进行舍入,然后将舍入结果除以1000:

let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236

与任何类型的printf(...)String(format: ...)解决方案不同,此操作的结果仍然是类型Double

编辑:

关于它有时不起作用的评论,请阅读以下内容:What Every Programmer Should Know About Floating-Point Arithmetic

zrfyljdw

zrfyljdw17#

以下任一项:

  • 使用String(format:)

  • 使用%.3f格式说明符将Double类型转换为String,然后返回到Double

Double(String(format: "%.3f", 10.123546789))!
  • 或扩展Double以处理N位小数:
extension Double {
    func rounded(toDecimalPlaces n: Int) -> Double {
        return Double(String(format: "%.(n)f", self))!
    }
}
  • 通过计算

  • 乘以10^3,四舍五入,然后除以10^3...

(1000 * 10.123546789).rounded()/1000
  • 或扩展Double以处理N位小数:
extension Double {    
    func rounded(toDecimalPlaces n: Int) -> Double {
        let multiplier = pow(10, Double(n))
        return (multiplier * self).rounded()/multiplier
    }
}
hts6caw3

hts6caw318#

这是一种漫长的变通方法,如果您的需求稍微复杂一些,它可能会派上用场。您可以在SWIFT中使用数字格式化程序。

let numberFormatter: NSNumberFormatter = {
    let nf = NSNumberFormatter()
    nf.numberStyle = .DecimalStyle
    nf.minimumFractionDigits = 0
    nf.maximumFractionDigits = 1
    return nf
}()

假设您要打印的变量是

var printVar = 3.567

这将确保它以所需的格式返回:

numberFormatter.StringFromNumber(printVar)

因此,这里的结果将是“3.6”(四舍五入)。虽然这不是最经济的解决方案,但我给出它是因为OP提到了打印(在这种情况下,字符串并不是不需要的),而且因为这个类允许设置多个参数。

5cg8jx4n

5cg8jx4n19#

一种方便的方法是使用双精度类型的扩展

extension Double {
    var roundTo2f: Double {return Double(round(100 *self)/100)  }
    var roundTo3f: Double {return Double(round(1000*self)/1000) }
}

用途:

let regularPie:  Double = 3.14159
var smallerPie:  Double = regularPie.roundTo3f  // results 3.142
var smallestPie: Double = regularPie.roundTo2f  // results 3.14
eaf3rand

eaf3rand20#

如果您想要对Double值进行舍入,您可能希望使用SWIFT e1d1e,这样就不会在尝试对这些舍入值进行数学运算时出现任何错误。如果使用Decimal,它可以准确地表示四舍五入浮点值的十进制值。

因此您可以执行以下操作:

extension Double {
    /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
    ///
    /// - Parameters:
    ///   - scale: How many decimal places to round to. Defaults to `0`.
    ///   - mode:  The preferred rounding mode. Defaults to `.plain`.
    /// - Returns: The rounded `Decimal` value.

    func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
        var decimalValue = Decimal(self)
        var result = Decimal()
        NSDecimalRound(&result, &decimalValue, scale, mode)
        return result
    }
}

然后,您可以获得四舍五入的Decimal值,如下所示:

let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30

如果您希望以指定的小数位数显示它(并根据用户的当前区域设置本地化字符串),则可以使用NumberFormatter

let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

if let string = formatter.string(for: value) {
    print(string)
}
bwitn5fc

bwitn5fc21#

使用内置的Foundation Darwin库

SWIFT 3

extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return Darwin.round(self * divisor) / divisor
    }
}

用途:

let number:Double = 12.987654321
print(number.round(to: 3))

产量:12.988

ev7lccsx

ev7lccsx22#

小数后的特定数字的代码为:

var a = 1.543240952039
var roundedString = String(format: "%.3f", a)

这里的%.3f告诉SWIFT将这个数字四舍五入到小数点后3位。如果你想要双精度数字,你可以使用以下代码:

//将字符串转换为双精度

var roundedString = Double(String(format: "%.3f", b))

kyvafyod

kyvafyod23#

SWIFT 4,Xcode 10

yourLabel.text =  String(format:"%.2f", yourDecimalValue)
v7pvogib

v7pvogib24#

在SWIFT 3.0和Xcode 8.0中:

extension Double {
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

按如下方式使用此扩展:

let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
juud5qan

juud5qan25#

在Yogi回答的基础上,这里有一个SWIFT功能可以完成这项工作:

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
}
laik7k3q

laik7k3q26#

这是一个完全有效的代码

SWIFT 3.0/4.0/5.0、Xcode 9.0 GM/9.2及更高版本

let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)

输出-123

let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)

产量-123.3

let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)

产量-123.33

let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)

产量-123.326

omjgkv6w

omjgkv6w27#

在SWIFT 5.5和Xcode 13.2中:

let pi: Double = 3.14159265358979
String(format:"%.2f", pi)

示例:

PS:从SWIFT 2.0和Xcode 7.2开始仍然是一样的

6mw9ycah

6mw9ycah28#

使用SWIFT 5,您可以根据需要选择以下9种样式之一,以便从Double获得四舍五入的结果。

1.使用FloatingPointrounded()方法

在最简单的情况下,您可以使用Double``rounded()方法。

let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

2.使用FloatingPointrounded(_:)方法

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

3.使用Darwin round函数

基金会通过达尔文提供了round函数。

import Foundation

let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

4.使用达尔文roundpow函数构建的Double扩展自定义方法

如果您想要多次重复前面的操作,重构您的代码可能是一个好主意。

import Foundation

extension Double {
    func roundToDecimal(_ fractionDigits: Int) -> Double {
        let multiplier = pow(10, Double(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

5.使用NSDecimalNumberrounding(accordingToBehavior:)方法

如果需要,NSDecimalNumber提供了一个冗长但功能强大的小数舍入解决方案。

import Foundation

let scale: Int16 = 3

let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)

let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

6.使用NSDecimalRound(_:_:_:_:)函数

import Foundation

let scale = 3

var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)

var roundedValue1 = Decimal()
var roundedValue2 = Decimal()

NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

7.使用NSStringinit(format:arguments:)初始化器

如果您希望从舍入操作中返回NSString,使用NSString初始值设定项是一个简单但有效的解决方案。

import Foundation

let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

8.使用Stringinit(format:_:)初始化器

SWIFT的String类型与Foundation的NSString类连接。因此,您可以使用以下代码从舍入操作返回String

import Foundation

let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

9.使用NumberFormatter

如果您希望从舍入运算中获得String?NumberFormatter提供了高度可定制的解决方案。

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3

let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")
zengzsys

zengzsys29#

当我打印**totalWorkTimeInHours时,如何将其向下舍入为1.543**?

要将totalWorkTimeInHours舍入为3位数以进行打印,请使用String构造函数,该构造函数接受format字符串:

print(String(format: "%.3f", totalWorkTimeInHours))
idfiyjo8

idfiyjo830#

SWIFT 2扩展

更通用的解决方案是以下扩展,可与SWIFT 2和iOS 9配合使用:

extension Double {
    /// Rounds the double to decimal places value
    func roundToPlaces(places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(self * divisor) / divisor
    }
}

SWIFT 3扩展

在SWIFT 3中,round被替换为rounded

extension Double {
    /// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

返回双四舍五入到小数点后4位的示例:

let x = Double(0.123456789).roundToPlaces(4)  // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4)  // Swift 3 version

相关问题