Swift:来自float的字符串,不会舍入值

Yog*_*are 5 ios swift

  1. 建议舍入小数,但我面临的情况是我只需要降低精度.

  2. 输出:15.96至16.0

  3. 期望的输出:15.96至15.9

代码:

var value: AnyObject = dict.valueForKey("XXX")!
  var stringVal = NSString(format:"%.1f", value.floatValue)
Run Code Online (Sandbox Code Playgroud)

我认为这很简单,但发现很棘手.您对此的看法非常感谢.

Ste*_*ani 6

如果需要在将来的数学运算中使用舍入数字,可以使用以下函数:

func roundToPlaces(_ value: Double, places: Int, rule: FloatingPointRoundingRule = .toNearestOrAwayFromZero) -> Double {
    let divisor = pow(10.0, Double(places))
    return (value * divisor).rounded(rule) / divisor
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用它来调用它

var value: AnyObject = dict.valueForKey("XXX")!
var rounded = roundToPlaces(value.doubleValue, places: 1, rule: .down)
var stringVal = "\(rounded)"
Run Code Online (Sandbox Code Playgroud)

这实际上做了以下几点:

15.96 * 10.0 = 159.6
floor(159.6) = 159.0
159.0 / 10.0 = 15.9
Run Code Online (Sandbox Code Playgroud)

警告:这对你使用科学精确度的情况没有帮助,即

1.49850e0 --> 1.4e0 // (5 places --> 1 place)
1.39e10 --> 1.3e10 // (3 places --> 1 place)
Run Code Online (Sandbox Code Playgroud)

它将所有数字视为 e0


[更新2018-08-09]
由于看起来我的答案是获得一些观点,我想指出通过除法舍入浮点数可能会引入错误,因为浮点数如何存储在内存中.用户@mattt在别处指出:

floor(1.5679999 * 1000) / 1000 == 1.5669999999999999
Run Code Online (Sandbox Code Playgroud)

(如果你想得到你的数学,这篇论文是关于数字和计算机的一个很好的入门读物)

如果您需要该级别的精度,请使用定点数字.Swift Decimal为此提供了类型.

重要的是要了解你的问题.如果您正在使用金钱或传感器数据,您可能需要小数.如果你正在使用计算机图形,你可以使用Floats.


Cla*_*fou 6

使用 aNSNumberFormatter并相应地配置其舍入模式:

let formatter = NSNumberFormatter()
formatter.maximumFractionDigits = 1
formatter.roundingMode = .RoundDown
let s = formatter.stringFromNumber(15.96)
// Result: s = "15.9"
Run Code Online (Sandbox Code Playgroud)

  • 不用担心!只是想我会指出 Mattt(NSHipster、AFNetworking/Alamofire 等的创建者)对同一主题所做的重要评论。浮点数不能总是代表精确的数字,这违背了使用 floor 解决这个问题的目的。见这里:http://stackoverflow.com/questions/31544046/round-down-in-swift/31544141?noredirect=1#comment51086885_31544141 (2认同)