按位运算做奇偶数判断

奇偶数判断很简单,不知道的怕是傻子吧

求余法 %

我们只需要对2求余,如果余数为零就是偶数,为1就是奇数。很简单了吧。

function isOdd($num) {
    return $num % 2;
} 

当然求余之前我们还需要对输入的 $num 进行是否为整数的处理。

位运算法 &

位运算是对数的二进制进行的运算,利用按位且操作,就是 & ,来做奇偶数判断是这样的

function isOdd($num) {
    return $num & 1;
} 

奇数的二进制数的最后一位永远是1,与 1 按位且只会得到 1,偶数相反。

总结

两种方法都能达到目的,按位运算应该是有更高的性能的,具体我也没试。
这里提出来是想给记住多一种思路。或者说更好的思路。编程有趣的地方也在于此。

本作品采用《CC 协议》,转载必须注明作者和本文链接
假装会写PHP
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 9
wkan

测试结果:这点差距建议忽略不计,还是用 % 比较通俗易懂

测试代码

<?php
$run_times = 100000000; // 读作 壹亿

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    0 % 2;
    1 % 2;
    2 % 2;
    1000 % 2;
    1001 % 2;
    100000000 % 2;
    100000001 % 2;
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "% cost {$elapsed} seconds" . PHP_EOL;

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    0 & 1;
    1 & 1;
    2 & 1;
    1000 & 1;
    1001 & 1;
    100000000 & 1;
    100000001 & 1;
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "& cost {$elapsed} seconds" . PHP_EOL;

运行5次的结果

# 1
% cost 0.92668008804321 seconds
& cost 0.91673493385315 seconds

# 2
% cost 0.94068813323975 seconds
& cost 0.91913104057312 seconds

# 3
% cost 0.93546605110168 seconds
& cost 0.91442203521729 seconds

# 4
% cost 0.91190505027771 seconds
& cost 0.90930008888245 seconds

# 5
% cost 0.93385791778564 seconds
& cost 0.9063708782196 seconds
6年前 评论
lol173

@wkan 很棒

6年前 评论
lol173

@wkan
我将你的代码改成一下这样,得到的结果就差很挺多的了,我想不通为什么会有这样的差别,请指教

<?php
$run_times = 100000000; // 读作 壹亿

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    isOdd2(0);
    isOdd2(1000);
    isOdd2(1001);
    isOdd2(100000000);
    isOdd2(100000001);
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "% cost {$elapsed} seconds" . PHP_EOL;

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    isOdd1(0);
    isOdd1(1000);
    isOdd1(1001);
    isOdd1(100000000);
    isOdd1(100000001);
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "& cost {$elapsed} seconds" . PHP_EOL;

function isOdd1($num) {
    return $num & 1;
}

function isOdd2($num) {
  return $num % 2;
}
% cost 22.192757844925 seconds
& cost 17.425535917282 seconds
6年前 评论
Jourdon

php 5.6php7.1 差很多哦

php5.6

% cost 11.22690987587 seconds
& cost 6.962562084198 seconds

% cost 11.792548179626 seconds
& cost 7.1402740478516 seconds

% cost 11.124490022659 seconds
& cost 6.8331658840179 seconds

php 7.1

% cost 0.59490394592285 seconds
& cost 0.60731196403503 seconds

% cost 0.5974280834198 seconds
& cost 0.59937500953674 seconds

% cost 0.59455013275146 seconds
& cost 0.59189391136169 seconds
6年前 评论
wkan

@lol173 可能涉及到PHP的某种奇特优化了吧,我也不清楚(ノ_<)

6年前 评论
lol173

@wkan 应该是吧,我的是 7.1

6年前 评论

@wkan 的测试更合理一些。php的函数会编译生成zend_function,存放在函数表里,而调用函数会经过function_exist,function_call等,需要反复在表里查找对应函数,而isOdd1(),isOdd2(),处于表中的位置不同,查找速度也不相同,试下在代码上把isOdd1(),isOdd2()互换位置你就可以知道。当然php7取消了function_exist,并且增加了缓存,差距会减小,但还是可以看出函数位置不同导致的差距

5年前 评论
lol173

@flusky 互换了下位置

<?php
$run_times = 100000000; // 读作 壹亿

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    isOdd2(0);
    isOdd2(1000);
    isOdd2(1001);
    isOdd2(100000000);
    isOdd2(100000001);
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "% cost {$elapsed} seconds" . PHP_EOL;

$times = $run_times;
$start_time = microtime(true);
while (--$times) {
    isOdd1(0);
    isOdd1(1000);
    isOdd1(1001);
    isOdd1(100000000);
    isOdd1(100000001);
}
$end_time = microtime(true);

$elapsed = $end_time - $start_time;

echo "& cost {$elapsed} seconds" . PHP_EOL;

function isOdd2($num) {
  return $num % 2;
}

function isOdd1($num) {
    return $num & 1;
}

结果如下,PHP 是 7.1

% cost 17.123107194901 seconds
& cost 13.568190097809 seconds
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!