将双精度数舍入到小数点后一位(去掉小数位)
Posted
技术标签:
【中文标题】将双精度数舍入到小数点后一位(去掉小数位)【英文标题】:Round a double down to one decimal place (dropping decimal places) 【发布时间】:2018-01-26 03:29:23 【问题描述】:我想将双精度数四舍五入到小数点后 1 位。例如,如果我有一个双 let val = 3.1915
,我想将它向下舍入到 3.1
。正常的舍入函数会将其舍入到3.2
,但我基本上只想去掉剩余的小数位。做这个的最好方式是什么?这有本机功能吗?我知道这很简单,但我想知道在不使用任何解决方法或不良做法的情况下,最好的方法是什么。这不是其他四舍五入问题的重复,因为我不是在问四舍五入,而是在问如何去掉小数位。
同样,如果值为3.1215
,它也会四舍五入为3.1
【问题讨论】:
【参考方案1】:使用函数trunc()
(代表截断)将去掉小数部分而不进行四舍五入。具体来说,将Double
的值乘以 10,截断它,然后再除以 10。然后,要使用 1 个小数位显示,请使用 String(format:)
:
let aDouble = 1.15
let truncated = trunc(aDouble * 10) / 10
let string = String(format: "%.1f", truncated
print(string)
(displays "1.1")
或者,处理整个样本值数组:
让浮动 = 步幅(从:1.099,到:2.0,通过:0.1)
let truncs = floats
.map trunc($0 * 10) / 10
.map String(format: "%.1f", $0)
let beforeAndAfter = zip(floats, truncs)
.map (float: $0.0, truncString: $0.1)
beforeAndAfter.forEach print(String(format: "%.3f truncated to 1 place is %@", $0.0, $0.1))
输出:
1.099 truncated to 1 place is 1.0
1.199 truncated to 1 place is 1.1
1.299 truncated to 1 place is 1.2
1.399 truncated to 1 place is 1.3
1.499 truncated to 1 place is 1.4
1.599 truncated to 1 place is 1.5
1.699 truncated to 1 place is 1.6
1.799 truncated to 1 place is 1.7
1.899 truncated to 1 place is 1.8
1.999 truncated to 1 place is 1.9
【讨论】:
【参考方案2】:通过您的示例,我假设您的意思是您想要截断,如果是这样,使用乘法并转换为 Int 然后除法并转换回 Float/Double 即可。
示例:3.1915 -> 3.1
var val = 3.1915
let intVal:Int = Int(val*10)
val = Float(intVal)/10.0
print(val) //3.1
如果您想要更多小数位,只需乘以 100 或 1000 即可。
如果出于任何原因你想使用 round() 函数,有一个接受 FloatingPointRoundingRule 的重载变体,它的工作方式如下:
var val = 3.1915
val*=10 //Determine decimal places
val.round(FloatingPoint.towardZero) // .down is also available which differs in rounding negative numbers.
val*=0.1 //This is a divide by 10
print(val) //3.1
在实际使用中,我建议创建一个扩展或全局函数,而不是每次都编写这个块。它看起来像:
extension Float
func trunc(_ decimal:Int)
var temp = self
let multiplier = powf(10,decimal) //pow() for Double
temp = Float(Int(temp*multiplier))/multiplier //This is actually the first example put into one line
return temp
并使用:
var val = 3.1915
print(val.trunc(1)) //3.1
【讨论】:
由于二进制浮点固有的错误,使用print(val)
并不总是能得到想要的结果。最好使用print(String(format:"%.1f", val))
True... 但 print 更像是一个调试函数,用于在运行时检查此变量的值,我宁愿拥有精确的值而不是格式化的值,以防出现一些错误-between 导致 val 变为 3.19,这将导致后续计算错误但不会反映在 print() 中。我也同意使用字符串格式来显示用户可见的值,以防止 3.100000001 问题:)
我只是作为插图打印。一个简单的事实是二进制浮点中没有小数位的概念。如果要将十进制数显示为特定的小数位数,则需要使用 String(format:)
或 NumberFormatter
将其转换为字符串,或使用 DecimalNumber
类,它在内部以 10 为基数表示数字,因此它们确实可以存储特定的小数位数。
在我的回答中,我将 Double 值映射到具有所需小数位数的字符串。以上是关于将双精度数舍入到小数点后一位(去掉小数位)的主要内容,如果未能解决你的问题,请参考以下文章