Swift 将双精度四舍五入到小数点后一位(删除小数点)

Swift 将双精度四舍五入到小数点后一位(删除小数点),swift,swift4,Swift,Swift4,我想把一个双精度整数舍入到小数点后1位。例如,如果我有一个双let val=3.1915,我想把它四舍五入到3.1。正常的四舍五入函数会将其四舍五入到3.2,但我想基本上去掉剩下的小数点。最好的方法是什么?是否有用于此的本机函数?我知道这很简单,但我想知道最好的方法是在不使用任何解决方法或不良做法的情况下。这不是其他四舍五入问题的重复,因为我不是问关于四舍五入的问题,我是问如何去掉小数点 类似地,如果值是3.1215,它也将舍入到3.1。根据您的示例,我假设您的意思是要截断,如果是这样,则使用乘

我想把一个双精度整数舍入到小数点后1位。例如,如果我有一个双let val=3.1915,我想把它四舍五入到3.1。正常的四舍五入函数会将其四舍五入到3.2,但我想基本上去掉剩下的小数点。最好的方法是什么?是否有用于此的本机函数?我知道这很简单,但我想知道最好的方法是在不使用任何解决方法或不良做法的情况下。这不是其他四舍五入问题的重复,因为我不是问关于四舍五入的问题,我是问如何去掉小数点


类似地,如果值是3.1215,它也将舍入到3.1。根据您的示例,我假设您的意思是要截断,如果是这样,则使用乘法和转换为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

在您的示例中,我假设您的意思是要截断,如果是这样,请使用乘法并转换为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
使用trunc函数,它代表truncate,它将在不舍入的情况下切掉小数部分。具体来说,将双精度值乘以10,截断它,然后再除以10。然后,要使用1位小数显示,请使用Stringformat::

或者,要处理整个样本值数组,请执行以下操作:

让floats=strippefrom:1.099,to:2.0,by: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
使用trunc函数,它代表truncate,它将在不舍入的情况下切掉小数部分。具体来说,将双精度值乘以10,截断它,然后再除以10。然后,要使用1位小数显示,请使用Stringformat::

或者,要处理整个样本值数组,请执行以下操作:

让floats=strippefrom:1.099,to:2.0,by: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

由于二进制浮点中固有的错误,使用printval不会总是给出期望的结果。最好使用printStringformat:%.1f,valTrue。。。但print更像是一个调试函数,用于在运行时检查此变量的值,我宁愿使用精确的值,而不是格式化的值,以防其间出现一些错误,导致val变为3.19,这将导致后续计算错误,但不会反映在print中。我也同意使用字符串格式来显示用户可见的值,以防止3.10000001问题:我只是作为一个插图打印。简单的事实是二进制浮点中没有小数位数的概念。如果要将十进制数显示为特定的小数位数,则需要使用Stringformat:或NumberFormatter或DecimalNumber类将其转换为字符串,它在10进制内部表示数字,因此它们确实可以存储特定的小数位数。在我的回答中,我将双精度值映射到具有所需小数位数的字符串。由于二进制浮点中固有的错误,使用printval不会始终给出所需的结果。最好使用printStringformat:%.1f,valTrue。。。但print更像是一个调试函数,用于在运行时检查此变量的值,我宁愿使用精确的值,而不是格式化的值,以防其间出现一些错误,导致val变为3.19,这将导致后续计算错误,但不会反映在print中。我也同意使用字符串格式来显示用户可见的值,以防止3.10000001问题:我只是作为一个插图打印。简单的事实是二进制浮点中没有小数位数的概念。如果要将十进制数显示为特定的小数位数,则需要使用Stringformat:或NumberFormatter或DecimalNumber类将其转换为字符串,它表示以10为基数的内部数字,因此它们确实可以存储特定的小数位数。在我的回答中,我将双精度值映射到具有所需小数位数的字符串。