如何在Julia中将数字转换为布尔值?

5
我希望将数字转换为等效的布尔值。根据官方文档

"false数值上等于0,true数值上等于1。"

因此,我想将数值转换为相应的布尔值。期望的行为示例

[1] Bool(5)
> true

不过,Julia 给了我:

ERROR: InexactError: Bool(5)
Stacktrace:
 [1] Bool(x::Int64)
   @ Base .\float.jl:158
 [2] top-level scope
   @ REPL[26]:1

但是如果我说:

[1] Bool(0.0)

# result
> false

00.0上看起来不错! 但是对于像52.1这样的数字无法正常工作。

1个回答

7
快速答案是,似乎你想要测试一个值是否为非零值,你可以像这样测试一个数字 x 是否为非零: x != 0。然而,一个数字被认为是真或假取决于你所使用的语言;下面会详细讲解。
现在我们已经得到了快速答案,我们可以谈论为什么。文档中说 falsetrue 数值上等于零和一。我们可以自己测试一下:
julia> false == 0
true

julia> true == 1.0
true

你可以看到,等式成立不管是什么类型的数字——整数、浮点数甚至更奥妙的数字类型如复数或有理数。我们也可以将布尔值转换为其他类型的数字:
julia> Int(false)
0

julia> Float64(true)
1.0

我们可以将这些值转换回布尔值:
julia> Bool(0)
false

julia> Bool(1.0)
true

您不能将不等于零或一的数字转换为布尔值:
julia> Bool(5)
ERROR: InexactError: Bool(5)

那是因为 Bool 类型只能精确表示零和一这两个值,尝试将任何其他数值转换为 Bool 将会产生 InexactError。这与尝试将非整数值的浮点数转换为整数类型时得到的错误相同:
julia> Int(5.0)
5

julia> Int(5.5)
ERROR: InexactError: Int64(5.5)

或将整数转换为一个较小的类型,无法表示该值:
julia> Int8(123)
123

julia> Int8(1234)
ERROR: InexactError: trunc(Int8, 1234)

这里发生了完全相同的事情:Bool不足以表示值5,因此如果您尝试将值5转换为Bool,则会出现错误。
许多语言用于数字真实性的约定是,表示零的值为falsey,表示非零的值为truthy。请注意,这没有任何严格的数学依据:零不是假,非零数字不是真;这只是一种约定,来自C编程语言,该语言没有布尔类型,并使用此约定在条件语句中将整数视为true/false。然而,这种约定远非普遍,因为有一些流行的语言不遵循它:例如,在Lisp和Ruby中,所有数字都是truthy的。我最近在Julia讨论区论坛上写了一篇文章,介绍了不同语言中真实性概念的差异以及为什么Julia拒绝真实性,而要求您编写明确的条件,如与零进行比较以获取数字或对集合进行非空检查。

由于您实际想要检查的条件是一个数字是否等于零,因此您应该明确地将数字与零进行比较,即通过执行x != 0来进行比较。这将计算为布尔值:true如果x非零且false如果x等于零。还有一个谓词函数可以执行此操作:iszero(x)检查x是否为零,如果您想要例如计算集合中有多少个零或非零值,则可能很方便:

julia> v = rand(-2:2, 100);

julia> count(iszero, v)
18

julia> count(!iszero, v)
82

5
非常感谢您的详细解释!我理解了概念,并认识到自己犯了错误。感谢您。 - Shayan
5
非常欢迎!很高兴您觉得这个解释有帮助。 - StefanKarpinski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接