在 Swift 中获取双精度数的小数部分
Getting the decimal part of a double in Swift
我试图在 swift 中分隔双精度数的小数部分和整数部分。我尝试了多种方法,但它们都 运行 进入了同一个问题...
let x:Double = 1234.5678
let n1:Double = x % 1.0 // n1 = 0.567800000000034
let n2:Double = x - 1234.0 // same result
let n3:Double = modf(x, &integer) // same result
有没有办法在不将数字转换为字符串的情况下获得 0.5678 而不是 0.567800000000034?
使用 Float
因为它的精度数字低于 Double
let x:Double = 1234.5678
let n1:Float = Float(x % 1) // n1 = 0.5678
无需将其转换为字符串,您可以像这样四舍五入到小数位:
let x:Double = 1234.5678
let numberOfPlaces:Double = 4.0
let powerOfTen:Double = pow(10.0, numberOfPlaces)
let targetedDecimalPlaces:Double = round((x % 1.0) * powerOfTen) / powerOfTen
你的输出将是
0.5678
Swift 2:
您可以使用:
modf(x).1
或
x % floor(abs(x))
您可以使用 truncatingRemainder
和 1
作为分隔符。
Returns the remainder of this value divided by the given value using truncating division.
示例:
let myDouble1: Double = 12.25
let myDouble2: Double = 12.5
let myDouble3: Double = 12.75
let remainder1 = myDouble1.truncatingRemainder(dividingBy: 1)
let remainder2 = myDouble2.truncatingRemainder(dividingBy: 1)
let remainder3 = myDouble3.truncatingRemainder(dividingBy: 1)
remainder1 -> 0.25
remainder2 -> 0.5
remainder3 -> 0.75
作为 FloatingPoint 协议实例 属性 实现的与 Alessandro Ornano 相同的方法:
Xcode 11 • Swift 5.1
import Foundation
extension FloatingPoint {
var whole: Self { modf(self).0 }
var fraction: Self { modf(self).1 }
}
1.2.whole // 1
1.2.fraction // 0.2
如果您需要小数位数并保留其精度数字,则需要使用 Swift Decimal
类型并使用 String
:
对其进行初始化
extension Decimal {
func rounded(_ roundingMode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
var result = Decimal()
var number = self
NSDecimalRound(&result, &number, 0, roundingMode)
return result
}
var whole: Decimal { rounded(sign == .minus ? .up : .down) }
var fraction: Decimal { self - whole }
}
let decimal = Decimal(string: "1234.99999999")! // 1234.99999999
let fractional = decimal.fraction // 0.99999999
let whole = decimal.whole // 1234
let sum = whole + fractional // 1234.99999999
let negativeDecimal = Decimal(string: "-1234.99999999")! // -1234.99999999
let negativefractional = negativeDecimal.fraction // -0.99999999
let negativeWhole = negativeDecimal.whole // -1234
let negativeSum = negativeWhole + negativefractional // -1234.99999999
你可以这样得到整数部分:
let d: Double = 1.23456e12
let intparttruncated = trunc(d)
let intpartroundlower = Int(d)
trunc() 函数截断小数点后的部分,Int() 函数舍入到下一个较低的值。这对于正数是相同的,但对于负数是不同的。如果你从d中减去截断部分,那么你将得到小数部分。
func frac (_ v: Double) -> Double
{
return (v - trunc(v))
}
您可以像这样获取 Double 值的尾数和指数:
let d: Double = 1.23456e78
let exponent = trunc(log(d) / log(10.0))
let mantissa = d / pow(10, trunc(log(d) / log(10.0)))
您的指数结果为 78,尾数结果为 1.23456。
希望对您有所帮助。
C 的数学库中有一个函数,包括 Swift 在内的许多编程语言都可以让您访问它。它被称为modf,在Swift中,它是这样工作的
// modf returns 一个 2 元素元组,
//第一个元素为整数部分,
//和第二个元素中的小数部分
让 splitPi = modf(3.141592)
splitPi.0 // 3.0
splitPi.1 // 0.141592
您可以像下面这样创建一个扩展,
extension Double {
func getWholeNumber() -> Double {
return modf(self).0
}
func getFractionNumber() -> Double {
return modf(self).1
}
}
Swift 5.1
let x:Double = 1234.5678
let decimalPart:Double = x.truncatingRemainder(dividingBy: 1) //0.5678
let integerPart:Double = x.rounded(.towardZero) //1234
这两种方法return双精度值。
如果你想要一个整数作为整数部分,你可以只使用
Int(x)
不可能创建适用于所有人的解决方案 Doubles
。如果其他答案曾经奏效(我也认为这是不可能的),那么它们就不再奏效了。
let _5678 = 1234.5678.description.drop { [=10=] != "." } .description // ".5678"
Double(_5678) // 0.5678
let _567 = 1234.567.description.drop { [=10=] != "." } .description // ".567"
Double(_567) // 0.5669999999999999
extension Double {
/// Gets the decimal value from a double.
var decimal: Double {
Double("0." + string.split(separator: ".").last.string) ?? 0.0
}
var string: String {
String(self)
}
}
这似乎解决了双精度问题。
用法:
print(34.46979988898988.decimal) // outputs 0.46979988898988
print(34.46.decimal) // outputs 0.46
我试图在 swift 中分隔双精度数的小数部分和整数部分。我尝试了多种方法,但它们都 运行 进入了同一个问题...
let x:Double = 1234.5678
let n1:Double = x % 1.0 // n1 = 0.567800000000034
let n2:Double = x - 1234.0 // same result
let n3:Double = modf(x, &integer) // same result
有没有办法在不将数字转换为字符串的情况下获得 0.5678 而不是 0.567800000000034?
使用 Float
因为它的精度数字低于 Double
let x:Double = 1234.5678
let n1:Float = Float(x % 1) // n1 = 0.5678
无需将其转换为字符串,您可以像这样四舍五入到小数位:
let x:Double = 1234.5678
let numberOfPlaces:Double = 4.0
let powerOfTen:Double = pow(10.0, numberOfPlaces)
let targetedDecimalPlaces:Double = round((x % 1.0) * powerOfTen) / powerOfTen
你的输出将是
0.5678
Swift 2:
您可以使用:
modf(x).1
或
x % floor(abs(x))
您可以使用 truncatingRemainder
和 1
作为分隔符。
Returns the remainder of this value divided by the given value using truncating division.
示例:
let myDouble1: Double = 12.25
let myDouble2: Double = 12.5
let myDouble3: Double = 12.75
let remainder1 = myDouble1.truncatingRemainder(dividingBy: 1)
let remainder2 = myDouble2.truncatingRemainder(dividingBy: 1)
let remainder3 = myDouble3.truncatingRemainder(dividingBy: 1)
remainder1 -> 0.25
remainder2 -> 0.5
remainder3 -> 0.75
作为 FloatingPoint 协议实例 属性 实现的与 Alessandro Ornano 相同的方法:
Xcode 11 • Swift 5.1
import Foundation
extension FloatingPoint {
var whole: Self { modf(self).0 }
var fraction: Self { modf(self).1 }
}
1.2.whole // 1
1.2.fraction // 0.2
如果您需要小数位数并保留其精度数字,则需要使用 Swift Decimal
类型并使用 String
:
extension Decimal {
func rounded(_ roundingMode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
var result = Decimal()
var number = self
NSDecimalRound(&result, &number, 0, roundingMode)
return result
}
var whole: Decimal { rounded(sign == .minus ? .up : .down) }
var fraction: Decimal { self - whole }
}
let decimal = Decimal(string: "1234.99999999")! // 1234.99999999
let fractional = decimal.fraction // 0.99999999
let whole = decimal.whole // 1234
let sum = whole + fractional // 1234.99999999
let negativeDecimal = Decimal(string: "-1234.99999999")! // -1234.99999999
let negativefractional = negativeDecimal.fraction // -0.99999999
let negativeWhole = negativeDecimal.whole // -1234
let negativeSum = negativeWhole + negativefractional // -1234.99999999
你可以这样得到整数部分:
let d: Double = 1.23456e12
let intparttruncated = trunc(d)
let intpartroundlower = Int(d)
trunc() 函数截断小数点后的部分,Int() 函数舍入到下一个较低的值。这对于正数是相同的,但对于负数是不同的。如果你从d中减去截断部分,那么你将得到小数部分。
func frac (_ v: Double) -> Double
{
return (v - trunc(v))
}
您可以像这样获取 Double 值的尾数和指数:
let d: Double = 1.23456e78
let exponent = trunc(log(d) / log(10.0))
let mantissa = d / pow(10, trunc(log(d) / log(10.0)))
您的指数结果为 78,尾数结果为 1.23456。
希望对您有所帮助。
C 的数学库中有一个函数,包括 Swift 在内的许多编程语言都可以让您访问它。它被称为modf,在Swift中,它是这样工作的
// modf returns 一个 2 元素元组,
//第一个元素为整数部分,
//和第二个元素中的小数部分
让 splitPi = modf(3.141592)
splitPi.0 // 3.0
splitPi.1 // 0.141592
您可以像下面这样创建一个扩展,
extension Double {
func getWholeNumber() -> Double {
return modf(self).0
}
func getFractionNumber() -> Double {
return modf(self).1
}
}
Swift 5.1
let x:Double = 1234.5678
let decimalPart:Double = x.truncatingRemainder(dividingBy: 1) //0.5678
let integerPart:Double = x.rounded(.towardZero) //1234
这两种方法return双精度值。
如果你想要一个整数作为整数部分,你可以只使用
Int(x)
不可能创建适用于所有人的解决方案 Doubles
。如果其他答案曾经奏效(我也认为这是不可能的),那么它们就不再奏效了。
let _5678 = 1234.5678.description.drop { [=10=] != "." } .description // ".5678"
Double(_5678) // 0.5678
let _567 = 1234.567.description.drop { [=10=] != "." } .description // ".567"
Double(_567) // 0.5669999999999999
extension Double {
/// Gets the decimal value from a double.
var decimal: Double {
Double("0." + string.split(separator: ".").last.string) ?? 0.0
}
var string: String {
String(self)
}
}
这似乎解决了双精度问题。
用法:
print(34.46979988898988.decimal) // outputs 0.46979988898988
print(34.46.decimal) // outputs 0.46