在Swift中测试小数是否为整数

在Swift中测试小数是否为整数,swift,decimal,Swift,Decimal,使用Swift 3 我在网上找到了很多奇怪的方法来检查一个物体是否是一个整数。每件事都比它需要的复杂得多 以下是我的解决方案: extension Decimal { var isWholeNumber: Bool { return self.exponent == 1 } } 在我的测试中,这是有效的。我的问题是我是否遗漏了一些明显的东西?谢谢你的评论!这是我现在使用的 extension Decimal { var isWholeNumber: Bo

使用Swift 3

我在网上找到了很多奇怪的方法来检查一个物体是否是一个整数。每件事都比它需要的复杂得多

以下是我的解决方案:

extension Decimal {
    var isWholeNumber: Bool {
        return self.exponent == 1
    }
}

在我的测试中,这是有效的。我的问题是我是否遗漏了一些明显的东西?

谢谢你的评论!这是我现在使用的

extension Decimal {
    var isWholeNumber: Bool { 
        return self.isZero || (self.isNormal && self.exponent >= 0) 
    }
}

以下是Objective-C解决方案在Swift中的翻译:

extension Decimal {
    var isWholeNumber: Bool {
        if isZero { return true }
        if !isNormal { return false }
        var myself = self
        var rounded = Decimal()
        NSDecimalRound(&rounded, &myself, 0, .plain)
        return self == rounded
    }
}

print(Decimal(string: "1234.0")!.isWholeNumber) // true
print(Decimal(string: "1234.5")!.isWholeNumber) // false
即使尾数不是最小值(或指数不是最大值),例如100*10-1,这种方法也有效。例如:

let z = Decimal(_exponent: -1, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0,
                _mantissa: (100, 0, 0, 0, 0, 0, 0, 0))

print(z) // 10.0
print(z.exponent) // -1
print(z.isWholeNumber) // true

我不确定它在所有情况下都能起作用,但这可能是一个更为精确的选择

extension Decimal {

    static var decimalSeparator: String { return NumberFormatter().decimalSeparator }

    var isFraction: Bool {
        return self.description.contains(Decimal.decimalSeparator)
    }

    var isWhole: Bool {
        return !isFraction
    }

}

实际上,您希望
返回self.exponent>=0
,但除此之外,我想不出它不起作用的任何原因。@JohnMontgomery true,与type variable相反,其实例variable@mgChristopher请注意,当使用getter但不使用setter创建实例计算属性时,可以省略
get
关键字及其括号
var isWholeNumber:Bool{return isZero | | |(isNormal&&exponent>=0)}
我确实看到了@PauloMattos:D。我很想做#3中提到的解决方案之一,但仍然觉得需要做更多的工作。@mgChristopher:可以毫无问题地翻译成Swift。它更多的是代码,但其优点是它只使用有文档记录的函数——据我所知,十进制的精确表示没有任何保证,甚至声明“NSDecimal的字段是私有的。”这给了整数值一个假负数,非规范化的
Decimal
sIMHO-guard语句在这里有一个更自然的语法:
guard!是零
守卫是正常的
@Alexander:不,我在
守卫中找不到“双重否定”!isZero else{return true}
更自然。Zero必须单独处理,但它不是“例外情况”。@MartinR:FWIW guard不适用于“例外情况”。它适用于应强制退出当前范围的情况。无论如何,if vs.guard的使用通常由实现者决定(我在这里使用的是guard,但不是YMMV)。谢谢你的回答。@Frizlab:当然,guard是用来解决“如果让金字塔毁灭”的,但是可以和任何布尔表达式一起使用也许我表达得很糟糕,我只是反对在每次“提前返回”的情况下使用
guard
。在这种情况下,
if为零{return true}
guard更容易理解!在我看来,isZero else{return true}