37

是否有一种(简单的)方法可以在 PHP 中获取与gmp_signDocs相当的数字(整数)的“符号” :

  • -1 负
  • 0 零
  • 1 阳性

我记得有某种比较功能可以做到这一点,但我目前无法找到它。

我很快编译了这个(Demo)来完成这项工作,但也许还有更漂亮的东西(比如单个函数调用?),我想将结果映射到一个数组:

$numbers = array(-100, 0, 100);

foreach($numbers as $number)
{
   echo $number, ': ', $number ? abs($number) / $number : 0, "\n";
}

(此代码可能会遇到浮点精度问题)

相关:请求 #19621 数学需要一个“sign()”函数

4

9 回答 9

67

这是一个很酷的单线,可以高效可靠地为您完成:

function sign($n) {
    return ($n > 0) - ($n < 0);
}
于 2013-12-08T23:12:36.983 回答
41

在 PHP 7 中,您应该使用组合比较运算符( <=>):

$sign = $i <=> 0;
于 2015-08-27T10:18:56.933 回答
17

在我测试的问题中,上述问题的一个变体也可以正常工作并且没有浮点问题:

min(1, max(-1, $number))

编辑:-1上面的代码在大于和小于范围内的浮点数(问题是关于整数)有一个缺陷1,可以用以下shorty修复:

min(1, max(-1, $number == 0 ? 0 : $number * INF))

那个浮动仍然有一个缺陷,NAN使它-1总是返回。那可能不正确。相反,人们可能也想返回0

min(1, max(-1, (is_nan($number) or $number == 0) ? 0 : $number * INF))
于 2011-09-26T14:29:26.740 回答
9

您可以嵌套三元运算符:

echo $number, ': ',  ($number >= 0 ? ($number == 0 ? 0 : 1) : -1 )

这对浮点精度没有问题,并且避免了浮点除法。

于 2011-09-26T14:26:51.603 回答
6

这个表格有什么问题?

if ( $num < 0 )
{
  //negative
}
else if ( $num == 0 )
{
  //zero
}
else
{
  //positive
}

或三元:

$sign = $num < 0 ? -1 : ( $num > 0 ? 1 : 0 );

不确定absvs 值比较的性能,但您可以使用:

$sign = $num ? $num / abs($num) : 0;

你可以把它们中的任何一个变成一个函数:

function valueSign($num)
{
  return $sign = $num < 0 ? -1 : ( $num > 0 ? 1 : 0 );
  //or
  return $sign = $num ? $num / abs($num) : 0;
}

我想你可能在谈论gmp_cmp,你可以称之为gmp_cmp( $num, 0 );

于 2011-09-26T14:28:45.977 回答
4

我认为 gmp_sign 效率不高,因为它需要 GMP 或字符串。($n ? abs($n)/$n : 0) 在数学上是正确的,但除法需要时间。最小/最大解决方案似乎对浮点数变得不必要的复杂。

($n > 0) - ($n < 0) 总是做 2 个测试和一个减法 ($n < 0 ? -1 : ($n > 0 ? 1 : 0) 做一两个测试而不是算术,它应该是最有效的。但我不认为这种差异与大多数用例有关。

于 2015-08-16T17:15:49.520 回答
3

我知道这已经晚了,但是简单地将数字除以 abs() 本身呢?

就像是:

function sign($n) {
    return $n/(abs($n));
}

将 div 所需的任何错误处理设置为零。

于 2016-02-21T19:52:35.917 回答
2

使用strcmp文档

echo $number, ': ', strcmp($number, 0), "\n";
于 2011-09-26T14:30:29.180 回答
1

这是一个没有循环的:

function sign($number){
    echo $number, ': ', $number ? abs($number) / $number : 0, "\n";
}

$numbers = array(-100, 0, 100);

array_walk($numbers, 'sign');
于 2011-09-26T14:34:06.780 回答