Ios 当递增0.1时,如何将每个.5数字四舍五入为整数值
我正在开发一个板球应用程序。我希望数字增加0.1,但一旦它达到0.5,我再次点击加号,我希望它四舍五入到整个值 例如,2.1、2.2、2.3、2.4、2.5然后跳到3.0(然后重新开始3.1、3.2、3.3等) 我的步进器当前上下移动.1,但它包括小数(.6、.7、.8和.9) 每次它击中一个数字的0.5,我需要它来取整。减法时相同 这是我的密码:Ios 当递增0.1时,如何将每个.5数字四舍五入为整数值,ios,swift,int,uistepper,Ios,Swift,Int,Uistepper,我正在开发一个板球应用程序。我希望数字增加0.1,但一旦它达到0.5,我再次点击加号,我希望它四舍五入到整个值 例如,2.1、2.2、2.3、2.4、2.5然后跳到3.0(然后重新开始3.1、3.2、3.3等) 我的步进器当前上下移动.1,但它包括小数(.6、.7、.8和.9) 每次它击中一个数字的0.5,我需要它来取整。减法时相同 这是我的密码: var oversFloat: Float = 0.0 @IBOutlet weak var displayOversLabel: UILabel
var oversFloat: Float = 0.0
@IBOutlet weak var displayOversLabel: UILabel!
@IBAction func OversStepper(_ sender: UIStepper) {
let oversValue = Float(sender.value)
displayOversLabel.text = String(oversValue)
浮点数是一个数字。您真的不应该测试浮点数是否与另一个值相等。在您的情况下,
0.1
不能用浮点数精确表示,因此增加0.1
会导致错误增加。因此,当您期望0.5
时,您的号码可能以0.49999999
结尾
在您的情况下,您可以通过在步进器中使用整数轻松避免此问题。将步进器修改为按1
步进,而不是按0.1
步进,并将最小值和最大值乘以10
。然后,使用步进器值更新标签时,将步进器值除以10
要从递增的88.5
跳到89.0
,并在递减时从89.0
跳到88.5
,请检查一个人的数字是否为6
或9
,然后通过4
递增/递减步进值:
@IBAction func oversStepper(_ sender: UIStepper) {
let value = Int(sender.value)
let remainder = value % 10
if remainder == 6 {
sender.value = Double(value + 4)
} else if remainder == 9 {
sender.value = Double(value - 4)
}
displayOversLabel.text = String(format: "%.1f", sender.value / 10)
}
通过使用整数值进行步进,不会引入任何错误。浮点数字是可用的。您真的不应该测试浮点数是否与另一个值相等。在您的情况下,
0.1
不能用浮点数精确表示,因此增加0.1
会导致错误增加。因此,当您期望0.5
时,您的号码可能以0.49999999
结尾
在您的情况下,您可以通过在步进器中使用整数轻松避免此问题。将步进器修改为按1
步进,而不是按0.1
步进,并将最小值和最大值乘以10
。然后,使用步进器值更新标签时,将步进器值除以10
要从递增的88.5
跳到89.0
,并在递减时从89.0
跳到88.5
,请检查一个人的数字是否为6
或9
,然后通过4
递增/递减步进值:
@IBAction func oversStepper(_ sender: UIStepper) {
let value = Int(sender.value)
let remainder = value % 10
if remainder == 6 {
sender.value = Double(value + 4)
} else if remainder == 9 {
sender.value = Double(value - 4)
}
displayOversLabel.text = String(format: "%.1f", sender.value / 10)
}
通过使用整数值进行步进,不会引入任何错误。如果步数从0.1更改为0.01或0.001,我会为您的请求添加一个通用答案 第一个是简化案例,这样就可以调用@IBAction而不会造成混淆
@IBAction func oversStepper(_ sender: UIStepper) {
let myValue : MyFloat = MyFloat(Float(sender.value))
sender.value = myValue.value
displayOversLabel.text = String(format: "%.1f", sender.value)
}
MyFloat在这里扮演数字验证器的角色。UIStepper值可以由MyFloat对象更正
下一个问题是浮子可以通过精确控制方式进行比较。换句话说,浮点数的精度可以通过限制一个数和一个实际数之间的abs差来实现,例如abs(a-b)<精度(1e-4),因此我们知道它们足够接近
基于此假设,构建MyFloat并运行测试用例,如下所示:
let presicion: Float = 1e-4
struct MyFloat {
private var val: Float = 0
init(_ v: Float){value = v}
var value : Float {
get{ return val}
set{
let ro = newValue.rounded()
let ground = newValue.rounded(FloatingPointRoundingRule.towardZero)
val = (trunc(newValue) == round(newValue) || abs((ground + ro) / 2.0 - newValue) < presicion ) ? newValue :
(abs(val - ro) < presicion) ? (ground + ro) / 2.0 : ro
}
}
static func +=(left: inout MyFloat, right: Float){
left.value = left.value + right
}
static func -=(left: inout MyFloat, right: Float){
left.value = left.value - right
}
}
//naive testCases
var myFloat = MyFloat(10.0)
myFloat += 0.1; assert(abs( myFloat.value - 10.1) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 10.2) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 10.3) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 10.4) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 10.5) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.0) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.1) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.2) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.3) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.4) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 11.5) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 12.0) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 12.1) < presicion);
myFloat += 0.1; assert(abs( myFloat.value - 12.2) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 12.1) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 12.0) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.5) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.4) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.3) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.2) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.1) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 11.0) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 10.5) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 10.4) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 10.3) < presicion);
myFloat -= 0.1; assert(abs( myFloat.value - 10.2) < presicion);
let presision:Float=1e-4
结构MyFloat{
私有变量val:Float=0
init(v:Float){value=v}
var值:浮动{
获取{return val}
设置{
设ro=newValue.rounded()
让地面=newValue.rounded(FloatingPointRoundingRule.towardZero)
val=(trunc(newValue)=圆形(newValue)| | abs((地面+ro)/2.0-newValue)
这种方法的优点是