当一个浮点数被转换为 to/from 一个第一原则级别的布尔值时会发生什么?
What happens when a float is cast to/from a boolean at the first principle level?
我试图弄清楚当一个 float 被转换为 to/from python 中的 bool 时,幕后到底发生了什么。这是我在网上找到的信息,我想知道是否有其他人愿意介入并帮助我获得正式的理解:
floats 在 C 中表示为 64 位数据结构,称为双精度数。
布尔值 在 C 中表示为 1 和 0。如果 true -> 1(二进制形式 0001) 如果 false -> 0(二进制形式 0000).
从this link here可以看出,内存中的double确实有3个部分。符号、指数和分数。
从第一原则开始,我倾向于认为指数和分数的某种组合被用来转换为浮点型布尔值。例如 2^0
是 1
但 e^x != 0
分别代表 e
和 x
的所有排列,所以我真的很困惑。
我明天有一个面试很可能会问我这个问题所以我想知道我是否可以得到一些帮助来解决这个问题。谢谢,祝你玩得开心day/night!
这与float
的内部表示无关。
布尔值是 int
的子类,因此 float(True) == 1.0
和 float(False) == 0.0
。
只有 0.0 映射到 False
;所有其他浮点值(包括 float("nan")
和 float("inf")
)映射到 True
.
这似乎是来自 https://github.com/python/cpython/blob/master/Objects/floatobject.c 的相关代码。
static int
float_bool(PyFloatObject *v)
{
return v->ob_fval != 0.0;
}
正如我们所见,值 v->ob_fval(双精度值)与 0.0 进行了比较。如果它们比较不相等,函数 returns 一个非零值,然后 Python 映射到 bool 值 True(或 1)。如果它们比较相等,则函数 returns 0 (false),其中 Python 映射到 bool 值 False (0)。
因此,如何表示 double 的问题与 Python 解释器级别无关。表达式 v->ob_fval != 0.0
很可能映射到单个硬件比较指令。大多数处理器都有用于浮点运算的专用硬件。
与 0 比较有点棘手,因为 IEEE 浮点数同时具有 +0 和 -0 表示(如您在提供的 link 中所见),因此硬件需要检查v->ob_fval 为 -0,但与 +0 进行比较的情况。但是硬件通常会处理这个问题,Python(甚至 C 编译器)通常不必担心那个级别的细节。
你对 2^0
和 e^x
的困惑与原来的问题并不相关,但我认为你肯定很困惑,所以我建议再次阅读你的 link .关键是double中的指数不是小数部分的指数;它是常数值 2 的指数,分数(加 1)乘以结果。
在 C
将 float
转换为 bool
:
+0.0f, -0.0f
--> false
,所有其他 float
,包括非数字,都是 true
.
内部 float
表示无关紧要,只有它的 值。
When any scalar value is converted to _Bool
, the result is 0 if the value compares equal to 0; otherwise, the result is 1 C11 §6.3.1.2 1
将 bool
转换为 float
:
false
--> 0.0f
, true
--> 1.0f
An object declared as type _Bool
is large enough to store the values 0 and 1. §6.2.5 2
我试图弄清楚当一个 float 被转换为 to/from python 中的 bool 时,幕后到底发生了什么。这是我在网上找到的信息,我想知道是否有其他人愿意介入并帮助我获得正式的理解:
floats 在 C 中表示为 64 位数据结构,称为双精度数。
布尔值 在 C 中表示为 1 和 0。如果 true -> 1(二进制形式 0001) 如果 false -> 0(二进制形式 0000).
从this link here可以看出,内存中的double确实有3个部分。符号、指数和分数。
从第一原则开始,我倾向于认为指数和分数的某种组合被用来转换为浮点型布尔值。例如 2^0
是 1
但 e^x != 0
分别代表 e
和 x
的所有排列,所以我真的很困惑。
我明天有一个面试很可能会问我这个问题所以我想知道我是否可以得到一些帮助来解决这个问题。谢谢,祝你玩得开心day/night!
这与float
的内部表示无关。
布尔值是 int
的子类,因此 float(True) == 1.0
和 float(False) == 0.0
。
只有 0.0 映射到 False
;所有其他浮点值(包括 float("nan")
和 float("inf")
)映射到 True
.
这似乎是来自 https://github.com/python/cpython/blob/master/Objects/floatobject.c 的相关代码。
static int
float_bool(PyFloatObject *v)
{
return v->ob_fval != 0.0;
}
正如我们所见,值 v->ob_fval(双精度值)与 0.0 进行了比较。如果它们比较不相等,函数 returns 一个非零值,然后 Python 映射到 bool 值 True(或 1)。如果它们比较相等,则函数 returns 0 (false),其中 Python 映射到 bool 值 False (0)。
因此,如何表示 double 的问题与 Python 解释器级别无关。表达式 v->ob_fval != 0.0
很可能映射到单个硬件比较指令。大多数处理器都有用于浮点运算的专用硬件。
与 0 比较有点棘手,因为 IEEE 浮点数同时具有 +0 和 -0 表示(如您在提供的 link 中所见),因此硬件需要检查v->ob_fval 为 -0,但与 +0 进行比较的情况。但是硬件通常会处理这个问题,Python(甚至 C 编译器)通常不必担心那个级别的细节。
你对 2^0
和 e^x
的困惑与原来的问题并不相关,但我认为你肯定很困惑,所以我建议再次阅读你的 link .关键是double中的指数不是小数部分的指数;它是常数值 2 的指数,分数(加 1)乘以结果。
在 C
将 float
转换为 bool
:
+0.0f, -0.0f
--> false
,所有其他 float
,包括非数字,都是 true
.
内部 float
表示无关紧要,只有它的 值。
When any scalar value is converted to
_Bool
, the result is 0 if the value compares equal to 0; otherwise, the result is 1 C11 §6.3.1.2 1
将 bool
转换为 float
:
false
--> 0.0f
, true
--> 1.0f
An object declared as type
_Bool
is large enough to store the values 0 and 1. §6.2.5 2