为什么 false ÷ true 的结果是 false?

9

在Julia中,布尔值在计算时具有数值(false = 0true = 1)。

以下所有内容都有预期结果:

true + false        #  1
false - true        #  -1
false / true        # 0.0
true ÷ false        # DivideError: integer division error
0 ÷ 1               # 0

除外:

false ÷ true        # false

那么为什么 false ÷ true 的结果是 false,而不是像 0 ÷ 1 那样的 0 呢?


更新:看起来乘法也有相同的行为:

false * true        # false

我可以理解布尔类型Bool与其他数字类型可能有不同的行为,但奇怪的是加法和减法的行为与乘法和除法不同。

数学运算文档指出:

请注意,Bool是整数类型,所有通常的提升规则和数字运算符也在其上定义。

因此,在所有算术上下文中,它不将布尔值视为整数有点令人惊讶。


1
如果我没记错,÷ 运算符是 Base.div() 函数的别名。我不确定,也从未使用过Julia,但我猜div函数始终尝试返回与操作数相同类型的内容,因此是布尔值。猜测:div在内部进行bool->int转换,进行整数除法,然后再进行布尔转换。对于 false÷true 这种情况可以执行,但对于 true÷false,整数除法步骤将失败。 - Torge Rosendahl
或者说Julia编译器希望以尽可能接近的类型回答数学问题,因此在这里用布尔值进行回答。从技术上讲,0÷1与false÷true是相同的。 - ADBeveridge
1
是的,这与调用 div(false, true) 相同。https://docs.julialang.org/en/v1/manual/mathematical-operations/#Division-functions - General Grievance
1
@TorgeRosendahl:您的猜测不太准确,该代码完全使用布尔值。这是定义:div(x::Bool, y::Bool) = y ? x : throw(DivideError()) - DNF
2个回答

2
正如 @DNF 指出的那样,div() 决策是用布尔逻辑实现的。
具体的方法定义在 Julia 源代码树的基础代码中 (julia/base/bool.jl)。
加法和减法将 Bool 转换为 Int
+(x::Bool, y::Bool) = Int(x) + Int(y)
-(x::Bool, y::Bool) = Int(x) - Int(y)

但是除法不行:

div(x::Bool, y::Bool) = y ? x : throw(DivideError())

我仍然觉得有点奇怪的是,并非所有的Bool操作都被视为数字类型,但显然这是有意为之的。


相当反直觉。在 C 语言中,那将是未定义行为(UB),这意味着打印“rabbits”是完全有效的。 - Vorac

2
理由是两个布尔值的除法总是一个布尔值或错误,而对布尔值进行其他算术运算可能会产生超出布尔值范围的数字。

我已经修改了问题 - 乘法具有相同的行为,因此它不仅仅适用于除法。 - sj95126
2
乘法具有相同的答案。所有 Bool*Bool 的输出都适合于 Bool - Oscar Smith
2
好的,我可以看到逻辑 - 除法、乘法,甚至指数运算都会得出 01,所以结果可以固定在一个 Bool 中。这种行为有记录在哪里吗?我找不到。 - sj95126
我不确定这是否有记录,而且它有点临时性质,因为(例如)Int8+Int8=Int8,但我认为决定就是对于布尔值,如果你想要带溢出的版本,那么只需要使用异或。 - Oscar Smith

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