轻松截断 Double - swift
Easily truncating a Double - swift
我希望能够将 longitude/latitude 值 19.3563443 转换为 19.35634(小数点后五位)。有什么简单的方法可以做到这一点吗?
回合,双倍返还。
NSString(format: "%.5f", myfloat).doubleValue
这不会截断,但可能足够精确 long/lat 到小数点后 5 位,而且速度很快。
您可以使用 NumberFormatter
:
extension Formatter {
static let number = NumberFormatter()
}
extension FloatingPoint {
func fractionDigitsRounded(to digits: Int, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
Formatter.number.roundingMode = roundingMode
Formatter.number.minimumFractionDigits = digits
Formatter.number.maximumFractionDigits = digits
return Formatter.number.string(for: self) ?? ""
}
}
let value = 19.3563443
let roundedToFive = value.fractionDigitsRounded(to: 5) // "19.35634"
我建议使用 NSDecimalNumber
。我不知道这实际上比@Leonardo 的回答好还是坏。但是在处理数字时,我更喜欢坚持使用数字,而不是转换 to/from 字符串。下面的代码为请求的位数生成一个函数,可以根据需要重复使用。
这通过向下舍入来截断。要获得正常的算术舍入,请将其更改为使用 .RoundPlain
而不是 .RoundDown
.
func makeRounder(#digits: Int16) -> (Double) -> Double {
class RoundHandler : NSObject, NSDecimalNumberBehaviors {
var roundToDigits : Int16
init(roundToDigits: Int16) {
self.roundToDigits = roundToDigits
}
@objc func scale() -> Int16 {
println("Digits: \(digits)")
return roundToDigits
}
@objc func roundingMode() -> NSRoundingMode {
return NSRoundingMode.RoundDown
}
@objc func exceptionDuringOperation(operation: Selector, error: NSCalculationError, leftOperand: NSDecimalNumber, rightOperand: NSDecimalNumber) -> NSDecimalNumber? {
return nil
}
}
let roundHandler = RoundHandler(roundToDigits:digits)
func roundDigits(original:Double) -> Double {
let decimal = NSDecimalNumber(double: original)
let rounded = decimal.decimalNumberByRoundingAccordingToBehavior(roundHandler)
return rounded.doubleValue
}
println("Digits: \(digits)")
return roundDigits
}
let roundTo5 = makeRounder(digits:Int16(5))
roundTo5(19.3563443)
roundTo5(1.23456789)
我在另一个网站上找到了不同的答案并想分享它:
let x = 129.88888888777
let y = Double(round(1000*x)/1000)
y returns 129.888
感谢 swift 的 "round" 功能。
设 x = (long*100000).rounded(.towardZero)/100000
这是一道数学题,不是编码题。 String
和 Double
之间的转换不是很吸引人。在数学中,截去小数点右边的数字称为缩减比例。要截断一个非整数,您需要做的就是将小数点向右移动,无论您希望它截断多少地方(将其乘以 10
将其移动一位,将其乘以 100
将其移动它二,等等),将它转换成一个整数(它会丢弃新小数点后的所有东西),然后将它除以原来的乘数以 return 小数点到它原来的位置。
将 pi 的比例缩小到 3
:
- 小数点右移:3.1415927 * 10^3 = 3141.5927
- 零分数 = 3141.0
- 小数点后移:3141 / 10^3 = 3.141
为方便起见,将其添加为 Double
的扩展:
extension Double {
func reduceScale(to places: Int) -> Double {
let multiplier = pow(10, Double(places))
let newDecimal = multiplier * self // move the decimal right
let truncated = Double(Int(newDecimal)) // drop the fraction
let originalDecimal = truncated / multiplier // move the decimal back
return originalDecimal
}
}
let dirty = 3.1415927
let clean = dirty.reduceScale(to: 2) // 3.14
我希望能够将 longitude/latitude 值 19.3563443 转换为 19.35634(小数点后五位)。有什么简单的方法可以做到这一点吗?
回合,双倍返还。
NSString(format: "%.5f", myfloat).doubleValue
这不会截断,但可能足够精确 long/lat 到小数点后 5 位,而且速度很快。
您可以使用 NumberFormatter
:
extension Formatter {
static let number = NumberFormatter()
}
extension FloatingPoint {
func fractionDigitsRounded(to digits: Int, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
Formatter.number.roundingMode = roundingMode
Formatter.number.minimumFractionDigits = digits
Formatter.number.maximumFractionDigits = digits
return Formatter.number.string(for: self) ?? ""
}
}
let value = 19.3563443
let roundedToFive = value.fractionDigitsRounded(to: 5) // "19.35634"
我建议使用 NSDecimalNumber
。我不知道这实际上比@Leonardo 的回答好还是坏。但是在处理数字时,我更喜欢坚持使用数字,而不是转换 to/from 字符串。下面的代码为请求的位数生成一个函数,可以根据需要重复使用。
这通过向下舍入来截断。要获得正常的算术舍入,请将其更改为使用 .RoundPlain
而不是 .RoundDown
.
func makeRounder(#digits: Int16) -> (Double) -> Double {
class RoundHandler : NSObject, NSDecimalNumberBehaviors {
var roundToDigits : Int16
init(roundToDigits: Int16) {
self.roundToDigits = roundToDigits
}
@objc func scale() -> Int16 {
println("Digits: \(digits)")
return roundToDigits
}
@objc func roundingMode() -> NSRoundingMode {
return NSRoundingMode.RoundDown
}
@objc func exceptionDuringOperation(operation: Selector, error: NSCalculationError, leftOperand: NSDecimalNumber, rightOperand: NSDecimalNumber) -> NSDecimalNumber? {
return nil
}
}
let roundHandler = RoundHandler(roundToDigits:digits)
func roundDigits(original:Double) -> Double {
let decimal = NSDecimalNumber(double: original)
let rounded = decimal.decimalNumberByRoundingAccordingToBehavior(roundHandler)
return rounded.doubleValue
}
println("Digits: \(digits)")
return roundDigits
}
let roundTo5 = makeRounder(digits:Int16(5))
roundTo5(19.3563443)
roundTo5(1.23456789)
我在另一个网站上找到了不同的答案并想分享它:
let x = 129.88888888777
let y = Double(round(1000*x)/1000)
y returns 129.888
感谢 swift 的 "round" 功能。
设 x = (long*100000).rounded(.towardZero)/100000
这是一道数学题,不是编码题。 String
和 Double
之间的转换不是很吸引人。在数学中,截去小数点右边的数字称为缩减比例。要截断一个非整数,您需要做的就是将小数点向右移动,无论您希望它截断多少地方(将其乘以 10
将其移动一位,将其乘以 100
将其移动它二,等等),将它转换成一个整数(它会丢弃新小数点后的所有东西),然后将它除以原来的乘数以 return 小数点到它原来的位置。
将 pi 的比例缩小到 3
:
- 小数点右移:3.1415927 * 10^3 = 3141.5927
- 零分数 = 3141.0
- 小数点后移:3141 / 10^3 = 3.141
为方便起见,将其添加为 Double
的扩展:
extension Double {
func reduceScale(to places: Int) -> Double {
let multiplier = pow(10, Double(places))
let newDecimal = multiplier * self // move the decimal right
let truncated = Double(Int(newDecimal)) // drop the fraction
let originalDecimal = truncated / multiplier // move the decimal back
return originalDecimal
}
}
let dirty = 3.1415927
let clean = dirty.reduceScale(to: 2) // 3.14