Swift 使用未知数字格式化小数位

Swift 使用未知数字格式化小数位,swift,logic,Swift,Logic,我正在打印一个数值我不知道的数字。在大多数情况下,数字都是整数或尾随数字。在某些情况下,数字以.25或.75结尾,很少有数字排到第千位。我如何特别发现最后一个病例?现在,我的代码检测到一个整数(0位小数),精确到.5(1位小数),然后在所有其他情况下恢复为2位小数点,但需要时,我需要转到3 class func getFormattedNumber(number: Float) -> NSString { var formattedNumber = NSString()

我正在打印一个数值我不知道的数字。在大多数情况下,数字都是整数或尾随数字。在某些情况下,数字以.25或.75结尾,很少有数字排到第千位。我如何特别发现最后一个病例?现在,我的代码检测到一个整数(0位小数),精确到.5(1位小数),然后在所有其他情况下恢复为2位小数点,但需要时,我需要转到3

class func getFormattedNumber(number: Float) -> NSString {

    var formattedNumber = NSString()

    // Use the absolute value so it works even if number is negative
    if (abs(number % 2) == 0) || (abs(number % 2) == 1) {  // Whole number, even or odd
        formattedNumber = NSString(format: "%.0f", number)
    }

    else if (abs(number % 2) == 0.5) || (abs(number % 2) == 1.5) {
        formattedNumber = NSString(format: "%.1f", number)
    }

    else {
        formattedNumber = NSString(format: "%.2f", number)
    }

    return formattedNumber

}

如果要将浮点数打印到小数点后3位,可以使用
字符串(格式:“%.3f”)
。这将四舍五入,因此
0.10000001
变为
0.100
0.1009
变为
0.101

但听起来好像你不想要尾随的零,所以你可能想把它们删掉。(有没有办法用
格式
?编辑:是,
g
,正如@simons指出的那样)

最后,这真的不应该是类函数,因为它是在基元类型上操作的。最好是使其成为一个自由函数,或者扩展
Double
/
Float

extension Double {
    func toString(#decimalPlaces: Int)->String {
        return String(format: "%.\(decimalPlaces)g", self)
    }
}

let number = -0.3009
number.toString(decimalPlaces: 3)  // -0.301

您可以使用
%g
抑制尾随零。那么我认为你不需要经历确定名额的过程。乙二醇-

var num1:Double = 5.5
var x = String(format: "%g", num1) // "5.5"

var num2:Double = 5.75
var x = String(format: "%g", num2) // "5.75"
或指定位置数量的这种变化。乙二醇-

var num3:Double = 5.123456789
var x = String(format: "%.5g", num3) // "5.1235"

Float
使用二进制(IEEE 754)表示,不能表示 所有的小数都精确。比如说,

let x : Float = 123.456
将字节
42f6e979
存储在
x
中,大约为
123.45600128173828
。那么
x
有3个或14个小数位数吗

如果指定最大数字,则可以使用
NSNumberFormatter
应显示的小数位数:

let fmt = NSNumberFormatter()
fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX")
fmt.maximumFractionDigits = 3
fmt.minimumFractionDigits = 0

println(fmt.stringFromNumber(123)!)      // 123
println(fmt.stringFromNumber(123.4)!)    // 123.4
println(fmt.stringFromNumber(123.45)!)   // 123.45
println(fmt.stringFromNumber(123.456)!)  // 123.456
println(fmt.stringFromNumber(123.4567)!) // 123.457

Swift 3/4更新:

let fmt = NumberFormatter()
fmt.locale = Locale(identifier: "en_US_POSIX")
fmt.maximumFractionDigits = 3
fmt.minimumFractionDigits = 0

print(fmt.string(for: 123.456)!) // 123.456
我的2美分;)Swift 3准备好了吗

将浮点数四舍五入,并将尾随的零分为所需的最小/最大分数位数

extension Double {
    func toString(minimumFractionDigits: Int = 0, maximumFractionDigits: Int = 2) -> String {
        let formatter = NumberFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.minimumFractionDigits = minimumFractionDigits
        formatter.maximumFractionDigits = maximumFractionDigits

        return formatter.string(from: self as NSNumber)!
    }
}
用法:

Double(394.239).toString() // Output: 394.24
Double(394.239).toString(maximumFractionDigits: 1) // Output: 394.2

在最后一个else作用域中尝试此操作:formattedNumber=NSString(格式:“%.3f”,number)。我想实际检测数字是否达到3位,我不想简单地依赖于此。请注意,Float和Double都不能准确表示所有小数。如果用户输入1.23,它将(大致)存储为1.2300000190734863。你将如何展示这一点换句话说,“小数位数”对于二进制浮点值没有精确的含义。如果数字为6.5,则代码正确地将余数与0.5完全匹配。如果系统附加了尾随的0,这不是很重要吗?6.5可以精确地表示为浮点。大多数小数点不能。但请注意,数字5是总位数,因此
字符串(格式:%.5g',51245.789)
给出了51246个不带任何小数点的数字,%g可以切换到指数表示,例如
字符串(格式:%.5g',512457.89)
给出了5.1246e+05。这是一个比我的答案好得多。真棒,我遇到的所有答案都缺少设置区域设置,谢谢!