在swift中将double值舍入到x个小数位数
任何人都可以告诉我如何在Swift中将double值舍入到x个小数位数?
我有:
var totalWorkTimeInHours = (totalWorkTime/60/60)
totalWorkTime
是NSTimeInterval(双)秒。
totalWorkTimeInHours
将给我的时间,但它给了我这么长的精确数量,如1.543240952039 ……
当我打印totalWorkTimeInHours
时,我怎样才能把它降低到1.543?
你可以使用Swift的round
函数来完成这个任务。
要以3位精度对Double
进行舍入,首先将其乘以1000,四舍五入将舍入结果除以1000:
let x = 1.23556789 let y = Double(round(1000*x)/1000) print(y) // 1.236
除了任何types的printf(...)
或String(format: ...)
解决scheme之外,此操作的结果仍然是Double
types的。
编辑:
关于有时不起作用的评论,请阅读:
计算机科学家应该知道什么是浮点运算
Swift 2的扩展
更通用的解决scheme是以下扩展,它适用于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
被replace为round
:
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 } }
返回Double的示例四舍五入到小数点后四位:
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
使用带format
string的String
构造函数:
print(String(format: "%.3f", totalWorkTimeInHours))
在Swift 2.0和Xcode 7.2中:
let pi: Double = 3.14159265358979 String(format:"%.2f", pi)
例:
使用Swift 3,根据您的需要,您可以select以下八种风格中的一种,以获得Double
的舍入结果。
#1。 使用FloatingPoint
rounded()
方法
在最简单的情况下,您可以使用Double
round()
方法。
用法:
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。 将FloatingPoint
rounded(_:)
方法与FloatingPointRoundingRule.toNearestOrEven
用法:
var roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000 var roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000 print(roundedValue1) // returns 0.684 print(roundedValue2) // returns 0.685
#3。 使用达尔文round
函数
基金会通过达尔文提供一个round
function。
用法:
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。 使用用Darwin round
和pow
函数构build的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。 使用NSDecimalNumber
如果需要, NSDecimalNumber
提供了一个详细但function强大的四舍五入小数的解决scheme。
用法:
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。 使用NSString
init(format:arguments:)
初始值设定项
如果你想从舍入操作返回一个NSString
,使用NSString
初始化是一个简单而有效的解决scheme。
用法:
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
#7。 String
init(format:_:)
初始化程序样式
Swift的String
types与Foundation的NSString
类桥接(可以通过阅读Swift编程语言了解更多信息)。 因此,您可以使用下面的代码为了从舍入操作返回一个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
#8。 使用NumberFormatter
如果你接受一个String?
从你的四舍五入操作, NumberFormatter
提供了一个高度可定制的解决scheme。
用法:
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")
基于瑜珈的回答,下面是一个可以完成这个工作的Swift函数:
func roundToPlaces(value:Double, places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor }
在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
方便的方式可以是使用Doubletypes的扩展
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
这是一个很长的解决方法,如果您的需求稍微复杂一点,这可能会派上用场。 您可以在Swift中使用数字格式化程序。
let numberFormatter: NSNumberFormatter = { let nf = NSNumberFormatter() nf.numberStyle = .DecimalStyle nf.minimumFractionDigits = 0 nf.maximumFractionDigits = 1 return nf }()
假设你想要打印的variables是
var printVar = 3.567
这将确保它以所需格式返回:
numberFormatter.StringFromNumber(printVar)
这里的结果将是“3.6”(四舍五入)。 虽然这不是最经济的解决scheme,但是我提供它是因为OP提到打印(在这种情况下string不是不可取的),并且因为这个类允许设置多个参数。
我会用
print(String(format: "%.3f", totalWorkTimeInHours))
并将.3f更改为您需要的任意十进制数字
使用内置的基础达尔文库
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
不是斯威夫特,但我相信你明白了。
pow10np = pow(10,num_places); val = round(val*pow10np) / pow10np;
这是四舍五入到N个有效数字的更灵活的algorithm
Swift 3解决scheme
extension Double { // Rounds the double to 'places' significant digits func roundTo(places:Int) -> Double { guard self != 0.0 else { return 0 } let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self)))) return (self * divisor).rounded() / divisor } } // Double(0.123456789).roundTo(places: 2) = 0.12 // Double(1.23456789).roundTo(places: 2) = 1.2 // Double(1234.56789).roundTo(places: 2) = 1200
格式化双重属性的最佳方法是使用Apple预定义的方法。
mutating func round(_ rule: FloatingPointRoundingRule)
FloatingPointRoundingRule是一个具有以下可能性的枚举
查点个案:
case fromFromZero舍入到最接近的允许值,其值大于或等于源的值。
向下舍入舍入到最接近的小于或等于源的允许值。
case toNearestOrAwayFromZero舍入到最接近的允许值; 如果两个值相等,则select较大幅度的值。
case toNearestOrEven舍入到最接近的允许值; 如果两个值相等,则select偶数。
向zeroero的情况舍入到最接近的允许值,其大小小于或等于源的值。
case up向上舍入到大于或等于源的最接近的允许值。
var aNumber : Double = 5.2 aNumber.rounded(.up) // 6.0
将double值舍入为x的十进制数
没有。 十进制后的数字
var x = 1.5657676754
var y =(x * 10000).rounded()/ 10000
print(y)// 1.5658
var x = 1.5657676754
var y =(x * 100).rounded()/ 100
print(y)// 1.57
var x = 1.5657676754
var y =(x * 10).round()/ 10
print(y)// 1.6
这是一行代码
Swift 3.2,Xcode 9.0 GM
let doubleValue : Double = 123.32565254455 self.lblValue.text = String(format:"%.2f", doubleValue) print(self.lblValue.text)
输出 – 123.32
我发现这个问题是否有可能纠正用户的input。 那就是如果他们input三位小数而不是两位一美元。 说1.111而不是1.11,你可以通过四舍五入来修复吗? 许多原因的答案是否定的! 随着钱超过0.001,最终会导致一个真正的支票簿的问题。
这是一个function来检查用户input的时间过后的值太多。 但是,这将允许1.,1.1和1.11。
假定已经检查了从String到Double的成功转换的值。
//func need to be where transactionAmount.text is in scope func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{ var theTransactionCharacterMinusThree: Character = "A" var theTransactionCharacterMinusTwo: Character = "A" var theTransactionCharacterMinusOne: Character = "A" var result = false var periodCharacter:Character = "." var myCopyString = transactionAmount.text! if myCopyString.containsString(".") { if( myCopyString.characters.count >= 3){ theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)] } if( myCopyString.characters.count >= 2){ theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)] } if( myCopyString.characters.count > 1){ theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)] } if theTransactionCharacterMinusThree == periodCharacter { result = true } if theTransactionCharacterMinusTwo == periodCharacter { result = true } if theTransactionCharacterMinusOne == periodCharacter { result = true } }else { //if there is no period and it is a valid double it is good result = true } return result }
问题陈述:
double d=3.0; d/100= 0.0299999999
我需要0.03
解:
NSNumber *doubleNSNumber=[[NSNumber alloc] initWithDouble:d/100.0]; double roundedNumber=[doubleNSNumber doubleValue]; roundedNumber=0.03