2

我在 jqGrid 服务器端 PHP 示例中找到了下一行

$start = $limit*$page - $limit; // do not put $limit*($page - 1)

有什么区别

$start = $limit*$page - $limit; 

$start = $limit*($page - 1);

为什么作者不推荐第二种方式?

4

7 回答 7

1

从数学上讲,两个表达式应该产生相同的结果。
实际上,由于 CPU 中的浮点运算(假设我们不只考虑整数),这两个表达式的结果可能会有很大差异。

示例:
想象$page是一个非常大的数字。
在这种情况下,1表达式$page - 1将被分解(因为 1 比 小几个数量级$page),
表达式$start = $limit*($page - 1);将等价于$start = $limit*$page;
第一种方式,我们没有这样的问题,这就是为什么它被推荐.

结论:
从数学上讲,它没有区别。
实际上,CPU(浮点运算单元)只能处理有限的数量级,而较小的数字在与大数字结合时通常会被分解。

编辑: 一个例子值得 1000 字......
看看这个小提琴,看看两个数学上相同的表达式如何产生不同的结果:http:
//jsfiddle.net/EyalAr/Z9BT5/

于 2012-07-07T07:49:20.170 回答
1

我怀疑这是一个数值数学问题。假设$page是巨大的,如6.02e231. 然后

($page - 1) = 6.02e231  

(完全相同的浮点表示),因此

$limit*($page - 1) = $limit*$page

从任何处理器的角度来看。相比

$limit*$page = [SOME HUGE VALUE]
$limit*$page - $limit = [SUBTRACTION OF TWO HUGE VALUES]

这将产生不同的结果,比“减一”表示法更准确。

因此,尽管在完美的数学世界中,这两个符号是相等的,但在非完美的计算世界中,第一个比第二个更容易出现“灾难性取消”(wiki that)。

于 2012-07-07T07:53:15.337 回答
0
$start = $limit*$page - $limit; 

这将首先执行乘法运算,然后减去结果的限制

$start = $limit*($page - 1);

这将首先将 $page 减去 1,然后与 $limit 相乘

于 2012-07-07T07:39:29.063 回答
0

就像在代数中一样,乘法按运算顺序发生在加法/减法之前。请参阅PHP 的优先文档。所以第一行做$limit * $page,然后减去limit,其实和$page * ($limit-1).

我认为暗示这一点的原因是,在代数中,语句在数学上是相同的,但在编程中却不是(括号被视为操作顺序指标而不是数量表示)

于 2012-07-07T07:43:46.250 回答
0

通常不建议使用第二种方法,因为在较旧的语言/编译器中,第二条语句会导致-0. 这-0会在计算中产生一些其他问题,因此,首选第一种方法。

您可以在此处看到上述内容:PHP 中的代码(未-0观察到)Lua 中的代码(-0在输出中观察)

于 2012-07-07T07:52:24.157 回答
0

老实说,我不明白为什么不推荐第二个版本。

$c = $a * $b - $a;

在抽象视图中,这将计算如下:

  1. 加载$a到 CPU 寄存器 1。
  2. 加载$b到 CPU 寄存器 2。
  3. 将两个寄存器相乘,将结果存储到寄存器 2 中。
  4. $a仍在寄存器 1 中。从寄存器 2 中减去它,将结果存储在任一寄存器中。
  5. 将结果寄存器保存到$c.

如果编译器看到$a等式中的两个操作数相同,则整行将仅使用两个 CPU 寄存器。

$c = $a * ($b - 1);
  1. 加载$a到寄存器 1。这应该首先完成,因为据我所知,PHP 保证了从左到右的评估顺序。
  2. 加载$b到寄存器 2。
  3. 递减寄存器 2。这是一个单独的操作,因此1不需要显式加载。
  4. 将寄存器 1 和 2 相乘,将结果存储在其中一个中。
  5. 将结果寄存器保存到$c.

对我来说,这看起来很像同样的努力。再说一次,他们可能已经分析了整个事情,并发现出于某种原因(例如由于行的上下文)第一个版本更有效。

假设整数算术,结果绝对没有区别。我也不完全分享浮点参数,因为如果$page是这么大的数字,那么您使用哪个版本仍然无关紧要。1要么从一个非常大的数字中减去,要么没有效果。或者您将大数和1分别乘以相同的因子,然后执行减法。这两个值在数量级上的差异与原始值相同,$page并且1

于 2012-07-07T07:57:42.860 回答
-1

程序员对准确性过于谨慎了。

在数学上根本没有区别。

从程序员的角度来看,运算符的优先级并不重要,因为变量是基本数字。(如果它们是具有重载运算符的 foo 类的实例,情况就不同了)

表格可能会失去准确性$limit*$page - $limit,请参阅rody_o对此的回答。但这不会发生,因为我从不认为 $page 和 $limit 的数量级为 10^38 之类的。但是 php 知道如何处理数字。请记住,我们甚至不知道它们是花车!

正如其他人也提到了执行速度,这不是程序员可能想到的。你真的关心在你的代码中编写哪种形式吗?选择一种形式而不是另一种形式甚至不是微优化。

没有理由告诉别人他们绝对不应该使用第二种形式。没关系。

于 2012-07-07T08:21:46.597 回答