37

gmp_signDocsに匹敵するPHPで数値(整数)の「符号」を取得する(簡単な)方法はありますか:

  • -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

41

PHP 7 では、複合比較演算子( <=>)を使用する必要があります。

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

私がテストした私の質問の上記のバリアントは、同様に機能し、浮動小数点の問題はありません:

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

編集:上記のコードには、次の短いもので修正できる範囲よりも大きい範囲-1と小さい範囲の浮動小数点数(整数についての質問でした)に欠陥があります:1

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 );

対値比較のパフォーマンスはわかりませんabsが、次を使用できます。

$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 に答える
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 に答える