How to check if a number (float or integer) is within a range (0 - 100)
我在找最快的方法来做这个测试。所以,functions、operands和其他一切都是允许的。我试过以下的regex(我不是专家):
1
| 0\.[0-9]+|100\.0+|100|[1-9]\d{0,1}\.{0,1}[0-9]+ |
它的作用只是错误地接受0.0或0.000000等。而且这不是最恰当和最快的方式。
(如果有人想修改regex以不允许这些0.00值,我们将不胜感激)`
- 为什么不先把字符串转换成数字,然后再比较数字呢?那不容易吗?
- 我不确定Regex是最好的方法。
- 是的,我不一定要找一个regex,如果你有其他的解决方案被很好地接受,我只是编辑了这个问题。
- 显然,regex并不是实现这一点的工具。用0\.[0-9]*[1-9][0-9]*更改0\.[0-9]+。
- @Casimirethpolyte谢谢。我认识一个雷吉士,这不是最好的。所以我问了最快的方法。我试过你的瑞格鞋,但它不接受0.001。我说的对吗?
- 刷新浏览器,注释已更改
- 谢谢@casimiretthipolyte它起作用了
不需要regex:
1 2 3 4
| if (is_numeric($val) && $val > 0 && $val <= 100)
{
echo '$val is number (int or float) between 0 and 100';
} |
演示
更新
结果是你从一个字符串中得到了数值。在这种情况下,最好使用regex来提取所有的元素,比如:
1 2 3 4 5 6 7 8 9
| if (preg_match_all('/\d+\.?\d*/', $string, $allNumbers))
{
$valid = [];
foreach ($allNumbers[0] as $num)
{
if ($num > 0 && $num <= 100)
$valid[] = $num;
}
} |
您可以省去is_numeric检查,因为匹配的字符串无论如何都保证是数字的…
- is_numeric(1e0)返回true—所以我认为regex是解决方案。
- 也许吧,但无论如何,对于我的用例,我可能需要先做一个regex,从一个字符串中提取这个数字(int或float),比如这个([0-9]+\.{0,1}[0-9]*),然后检查这个数字是否在发布的解决方案的范围内。
- @库斯,你不需要雷鬼。看看我的答案。
- @Violator667:这是因为1e0是数字,它和1^0是相同的(1的幂为0),从定义上来说,这是一个有效值…在php中尝试var_dump(1e0);,它会转储1
- @我的问题是,这个数字和其他的东西,如:sometext($),@31.321312(rew),在一个字符串中,所以我需要从那里提取它,然后进行检查。
- @kuus:使用类似于so的regex提取数值:preg_match_all('/\d+\.?\d*/', $string, $allNumbers),然后使用我的答案处理所有的数字,但您可以忽略is_numeric检查,因为preg_match_all已经保证匹配为数字。
- 实际上,我需要一个更像这个(0\.[0-9]*|[1-9]{0,1}\d+\.{0,1}[0-9]+)的regex,因为我不能允许一个值013,在范围检查中它会返回true,但在我的用例中它不正常。
- 感谢@eliasvanootegem的帮助!
- 如果该值类似于100.000001493894或0.999985378683,则这不适用于计算的浮点值。
- @蒂姆,你对此无能为力,真的……由于PHP使用IEEE754双精度格式,这些数字会导致舍入问题。有专门为解决这些类型的数字带来的一些头痛而构建的扩展(想到了BC数学)。可能还有一些图书馆你也可以使用
使用BCCOMP
这是BCMath函数的完美用例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function compare_numberic_strings ($number) {
if (
is_numeric($number) &&
bccomp($number, '0') === 1 &&
bccomp($number, '100') === -1
) {
return true;
}
return false;
}
echo compare_numberic_strings ('0.00001');
//returns true
echo compare_numberic_strings ('50');
//returns true
echo compare_numeric_strings ('100.1');
//returns false
echo compare_numeric_strings ('-0.1');
//returns false |
从手册中:
Returns 0 if the two operands are equal, 1 if the left_operand is
larger than the right_operand, -1 otherwise.
- 这是否比上述答案更快:stackoverflow.com/a/2798661/1938970?
- @首先,请阅读:stackoverflow.com/questions/3470990/&hellip;。但要回答你的问题,是的。这些函数是用C编写的,它比PHP本身快得多。加上。这是一个很大的优势。您不应该使用<和>来比较浮点数。曾经。关于这个php.net/manual/en/&hellip;,php.net上有一个大的胖警告。这就是BCMath函数的用途。
- @泰克:胡说八道…这些函数是用C->Yes编写的,所以呢?C比PHP快得多->是的。PHP是用什么语言写的?=>c.不管你怎么看,$val > 0 && $val <= 100都在比较2 zval(php变量的内部表示)。bccomp正在调用一个函数,它总是比比较两个标量值更昂贵。
- @谢谢,我知道所有关于微优化的讨论、思考和问题,但我还是想知道最快的是什么。)
- @eliasvanootegem无论哪种方式,都不能用传统的操作符比较浮点。
- @库斯,不客气。当然比使用昂贵的正则表达式要好;)
- @泰克:为什么在这种特殊情况下,比较2个double是如此不可靠?即使如此,你还是宁愿把一个字符串化的数字解析成一个结构,用大量的助手函数和堆内存来比较这个结构。在对其性能提出任何要求之前,请检查bccomp的实施情况。很明显,它不是设计得很快,它是设计用来对付IEEE754规范可能出现的舍入问题,但是OP在这里不做任何算术运算。
- @Eliasvanootegem因为我们不知道他的数据集是什么样子,也许他也不知道。里面的一切都有很好的理由,他们不是在浪费计算。使用专门为此目的编写的函数更安全,因此我们可以避免这样的问题:stackoverflow.com/questions/5230305/&hellip;
- @tek:你链接到的问题,像其他有关浮点数问题的问题一样,执行计算。在我的答案的注释中指定的一个操作,他后面的数字是从一个字符串中提取出来的。没有计算,也没有舍入问题。我只是想让事情简单一点
- @eliasvanootegem即使这样,在比较stackoverflow.com/questions/3148937/compare-floats-in-php时,也需要指定所需的最小可接受差异。最好使用bcmath函数,而不必担心浮点数。另外,您可以保证使用它们进行任何计算。您不希望意外地在浮点上计算,因为您习惯于使用普通运算符,然后比较它们。最好熟悉正确的PHP编程技术
- @泰克:再说一次:关联问题涉及浮点数的计算。此外,一个非常常见的(比bmath更常见),在php和c中更容易的选择是不使用小数(只使用long或int并除以100作为输出)。是的,浮点运算很容易出错,但老实说,是亲吻。我知道你可能会链接到另一个问题,或者告诉我把.1 + .2放在一个JS控制台中,但坦率地说,这是一个毫无意义的讨论,在这里是非常离题的。我们要么同意PHP不是算术的最佳工具,要么同意不同意
- 我同意,尽管还有很多东西要学。lol@js控制台部分
我认为你的regex模式应该是这样的:
演示
- 这个regex对于这个用例是错误的,我会投反对票,但我不能。