- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
> t-6ren">
将浮点数与整数进行比较时,某些值对的计算时间比其他类似量级的值要长得多。
例如:
>>> import timeit
>>> timeit.timeit("562949953420000.7 < 562949953421000") # run 1 million times
0.5387085462592742
>>> timeit.timeit("562949953420000.7 < 562949953422000") # integer increased by 1000
0.1481498428446173
>>> timeit.timeit("562949953423001.8 < 562949953421000") # float increased by 3001.1
0.1459577925548956
==
或
>
代替)不会以任何明显的方式影响时间。
最佳答案
float 对象的 Python 源代码中的注释承认:
v
到整数/长
w
,最坏的情况是:
v
和 w
具有相同的符号(均为正或均为负),w
几乎没有足够的位可以保存在 size_t
中类型(通常为 32 或 64 位),w
至少有 49 位,v
与w
中的位数相同. >>> import math
>>> math.frexp(562949953420000.7) # gives the float's (significand, exponent) pair
(0.9999999999976706, 49)
>>> (562949953421000).bit_length()
49
float_richcompare
函数处理两个值之间的比较
v
和
w
.
v
和
w
到两个合适的 C double ,
i
和
j
,然后可以很容易地进行比较以给出正确的结果。 Python 2 和 Python 3 都使用相同的想法来做到这一点(前者只是分别处理
int
和
long
类型)。
v
绝对是一个 Python 浮点数并将其映射到 C double
i
.接下来函数查看是否
w
也是一个浮点数并将其映射到 C double
j
.这是该函数的最佳情况,因为可以跳过所有其他检查。该函数还检查是否
v
是
inf
或
nan
:
static PyObject*
float_richcompare(PyObject *v, PyObject *w, int op)
{
double i, j;
int r = 0;
assert(PyFloat_Check(v));
i = PyFloat_AS_DOUBLE(v);
if (PyFloat_Check(w))
j = PyFloat_AS_DOUBLE(w);
else if (!Py_IS_FINITE(i)) {
if (PyLong_Check(w))
j = 0.0;
else
goto Unimplemented;
}
w
这些检查失败,它不是 Python 浮点数。现在该函数检查它是否是一个 Python 整数。如果是这种情况,最简单的测试是提取
v
的符号。和
w
的标志(返回
0
如果为零,
-1
如果为负,
1
如果为正)。如果符号不同,这就是返回比较结果所需的全部信息:
else if (PyLong_Check(w)) {
int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
int wsign = _PyLong_Sign(w);
size_t nbits;
int exponent;
if (vsign != wsign) {
/* Magnitudes are irrelevant -- the signs alone
* determine the outcome.
*/
i = (double)vsign;
j = (double)wsign;
goto Compare;
}
}
v
和
w
有相同的标志。
w
中的位数.如果它有太多位,那么它不可能被保存为浮点数,因此必须大于浮点数
v
:
nbits = _PyLong_NumBits(w);
if (nbits == (size_t)-1 && PyErr_Occurred()) {
/* This long is so large that size_t isn't big enough
* to hold the # of bits. Replace with little doubles
* that give the same outcome -- w is so large that
* its magnitude must exceed the magnitude of any
* finite float.
*/
PyErr_Clear();
i = (double)vsign;
assert(wsign != 0);
j = wsign * 2.0;
goto Compare;
}
w
具有 48 位或更少位,它可以安全地转换为 C double
j
并比较:
if (nbits <= 48) {
j = PyLong_AsDouble(w);
/* It's impossible that <= 48 bits overflowed. */
assert(j != -1.0 || ! PyErr_Occurred());
goto Compare;
}
w
有 49 位或更多位。治疗会很方便
w
作为正整数,因此根据需要更改符号和比较运算符:
if (nbits <= 48) {
/* "Multiply both sides" by -1; this also swaps the
* comparator.
*/
i = -i;
op = _Py_SwappedOp[op];
}
(void) frexp(i, &exponent);
if (exponent < 0 || (size_t)exponent < nbits) {
i = 1.0;
j = 2.0;
goto Compare;
}
w
中的位数那么我们就有了
v < |w|
因为有效数 * 2exponent 小于 2nbits。
w
中的位数。 .这表明有效数 * 2exponent 大于 2nbits 等
v > |w|
:
if ((size_t)exponent > nbits) {
i = 2.0;
j = 1.0;
goto Compare;
}
v
与整数
w
中的位数相同.
v
构造两个新的 Python 整数。和
w
.这个想法是丢弃
v
的小数部分,将整数部分加倍,然后加一。
w
也加倍了,可以比较这两个新的 Python 对象以给出正确的返回值。使用较小值的示例,
4.65 < 4
将由比较决定
(2*4)+1 == 9 < 8 == (2*4)
(返回假)。
{
double fracpart;
double intpart;
PyObject *result = NULL;
PyObject *one = NULL;
PyObject *vv = NULL;
PyObject *ww = w;
// snip
fracpart = modf(i, &intpart); // split i (the double that v mapped to)
vv = PyLong_FromDouble(intpart);
// snip
if (fracpart != 0.0) {
/* Shift left, and or a 1 bit into vv
* to represent the lost fraction.
*/
PyObject *temp;
one = PyLong_FromLong(1);
temp = PyNumber_Lshift(ww, one); // left-shift doubles an integer
ww = temp;
temp = PyNumber_Lshift(vv, one);
vv = temp;
temp = PyNumber_Or(vv, one); // a doubled integer is even, so this adds 1
vv = temp;
}
// snip
}
}
v
是一个浮点数并将其转换为 C double。现在,如果
w
也是一个浮点数:
w
是 nan
或 inf
.如果是这样,请根据 w
的类型单独处理此特殊情况. v
和 w
直接通过它们的表示作为 C 加倍。 w
是一个整数:
v
的符号和 w
.如果它们不同,那么我们知道 v
和 w
是不同的,哪个是更大的值。 w
有太多位不能作为浮点数(超过 size_t
)。如果是这样,w
具有比 v
更大的震级. w
有 48 位或更少位。如果是这样,它可以安全地转换为 C double 而不会损失其精度并与 v
进行比较。 . w
有超过 48 位。我们现在将 w
视为一个正整数,并适当更改了比较操作。) v
.如果指数为负,则 v
小于 1
因此小于任何正整数。否则,如果指数小于 w
中的位数那么它必须小于 w
. v
大于 w
中的位数然后 v
大于 w
. w
中的位数相同。) v
分为整数部分和小数部分。将整数部分加倍并加 1 以补偿小数部分。现在将整数加倍 w
.比较这两个新整数以获得结果。 关于python - 为什么一些 float < integer 比较比其他的慢四倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30100725/
我知道问题的标题听起来很奇怪,但我不知道该怎么调用它。 首先,我有一个网格布局,我希望我的 .search-wrapper 宽度为 50% 并向右浮动。在我的演示中 jsfiddle整个 .searc
我们正在使用 QA-C 来实现 MISRA C++ 一致性,但是该工具会为这样的代码喷出错误: float a = foo(); float b = bar(); float c = a - b; 据
考虑 float a[] = { 0.1, 0.2, 0.3}; 我很困惑a稍后传递给函数 foo(float* A) .不应该是 float* 类型的变量指向单个浮点数,对吗?就像这里提到的tu
这可能是我一段时间以来收到的最好的错误消息,我很好奇出了什么问题。 原代码 float currElbowAngle = LeftArm ? Elbow.transform.localRotation
刚开始学习 F#,我正在尝试为 e 生成和评估泰勒级数的前 10 项。我最初编写了这段代码来计算它: let fact n = function | 0 -> 1 | _ -> [1
我已经使用 Erlang 读取二进制文件中的 4 个字节(小端)。 在尝试将二进制转换为浮点时,我一直遇到以下错误: ** exception error: bad argument in
假设我有: float a = 3 // (gdb) p/f a = 3 float b = 299792458 // (gdb) p/f b = 29979244
我每次都想在浏览器顶部修复这个框。但是右边有一些问题我不知道如何解决所以我寻求帮助。 #StickyBar #RightSideOfStickyBar { float : right ; }
我正在研究 C# 编译器并试图理解数学运算规则。 我发现在两种不同的原始类型之间使用 == 运算符时会出现难以理解的行为。 int a = 1; float b = 1.0f; Cons
假设我有: float a = 3 // (gdb) p/f a = 3 float b = 299792458 // (gdb) p/f b = 29979244
Denormals众所周知,与正常情况相比,表现严重不佳,大约是 100 倍。这经常导致 unexpected软件 problems . 我很好奇,从 CPU 架构的角度来看,为什么非规范化必须是 那
我有一个由两个 float 组成的区间,并且需要生成 20 个随机数,看起来介于两个 float 定义的区间之间。 比方说: float a = 12.49953f float b = 39.1123
我正在构建如下矩阵: QMatrix4x3 floatPos4x3 = QMatrix4x3( floatPos0.at(0), floatPos1.at(0), floatPos2.at(0),
给定归一化的浮点数f,在f之前/之后的下一个归一化浮点数是多少。 通过微动,提取尾数和指数,我得到了: next_normalized(double&){ if mantissa is n
关于 CSS“float”属性的某些东西一直让我感到困惑。为什么将“float”属性应用到您希望 float 的元素之前的元素? 为了帮助可视化我的问题,我创建了以下 jsFiddle http://
关于 CSS“float”属性的某些东西一直让我感到困惑。为什么将“float”属性应用到您希望 float 的元素之前的元素? 为了帮助可视化我的问题,我创建了以下 jsFiddle http://
我有一个新闻源/聊天框。每个条目包含两个跨度:#user 和#message。我希望#user 向左浮动,而#message 向左浮动。如果#message 导致行超过容器宽度,#message 应该
我想创建一个“记分卡”网格来输出一些数据。如果每个 div.item 中的数据都具有相同的高度,那么在每个 div.item 上留下一个简单的 float 会提供一个漂亮的均匀布局,它可以根据浏览器大
我正在学习使用 CSS float 属性。我想了解此属性的特定效果。 考虑以下简单的 HTML 元素: div1 div2 This is a paragraph 以及以下 CSS 规则: div {
我正在尝试从可以是 int 或 float 的文件中提取数据。我发现这个正则表达式将从文件 (\d+(\.\d+)?) 中提取这两种类型,但我遇到的问题是它将 float 拆分为两个。 >>> imp
我是一名优秀的程序员,十分优秀!