Comment obtenir le signe d'un nombre?
Est-il un (simple) pour obtenir le "signe" d'un certain nombre (entier) en PHP comparable à gmp_sign
Docs:
- -1 négatif
- 0 zéro
- 1 positif
Je me souviens il y a une sorte de fonction de comparaison qui peut le faire, mais je ne suis pas capable de le trouver pour le moment.
J'ai rapidement compilé ce (Démo) qui fait le travail, mais peut-être il ya quelque chose de plus chouette (comme un seul appel de fonction?), Je voudrais une carte le résultat sur un tableau:
$numbers = array(-100, 0, 100);
foreach($numbers as $number)
{
echo $number, ': ', $number ? abs($number) / $number : 0, "\n";
}
(ce code peut s'exécuter en précision en virgule flottante de problèmes probablement)
Connexes: Demande n ° 19621 Mathématiques a besoin d'un "signe()" fonction
- Pourquoi ne pas installer
gmp
? - Geret'kal: Parfois, vous êtes à la recherche de commentaires, de droit? 😉
- Essayez codereview.SE 🙂
- Bonne question, peut-être parce qu'il est déjà installé? De me laisser tenter 🙂
Vous devez vous connecter pour publier un commentaire.
Ici est un petit one-liner qui va le faire pour vous de manière efficace et fiable:
$n
. En outre, IEEE flotteurs de faire suivre la loi du tiers exclu (¬(A > B) ⇒ A ≤ B
,¬(A < B) ⇒ A ≥ B
), de sorte que vous ne sera pas obtenir un nombre différent de zéro satisfaisant les deux conditions et de donner un signe incorrect de0
. Enfin, les deux-0
et0
sont traités comme égaux à zéro par l'IEEE specs, il en sera à la fois le retour de faux dans les deux conditions, ce qui donne un signe de0
. Il va travailler pour toutes les entrées numériques. AlimentationNAN
dans la fonction rendements1 - 1 = 0
qui est une réponse que tout, je suppose.En PHP 7, vous devez utiliser le combiné opérateur de comparaison (
<=>
):Une variante de ce qui précède, dans ma question, j'ai testé et qui fonctionne aussi bien et n'a pas la virgule flottante problème:
Edit: Le code ci-dessus a un défaut pour les nombres réels (question a propos des nombres entiers) dans la gamme de plus de
-1
et plus petit que1
qui peut être résolu par la suite shorty:Que l'on a toujours une faille pour le flotteur
NAN
rendant retour-1
toujours. Qui pourrait ne pas être correcte. Au lieu de cela on peut avoir envie de retourner0
ainsi:0.3
(ou tous les numéros de-1
à1
)Vous pouvez imbriquer des opérateurs ternaires:
Cela n'a aucun problème avec précision en virgule flottante et évite une division à virgule flottante.
Quel est le problème avec ce formulaire?
ou ternaire:
Pas sûr de la performance de
abs
vs comparaison de la valeur, mais vous pouvez utiliser:et vous pourriez faire de l'un d'eux dans une fonction:
Je suppose que vous pourriez parler de
gmp_cmp
, ce que vous pourriez appeler commegmp_cmp( $num, 0 );
(-1, 0, 1)
.Je pense que gmp_sign n'est pas très efficace, car il attend un GMP ou chaîne.
($n ? abs($n)/$n : 0) est mathématiquement correct, mais la division de coûts en temps.
Le min/max des solutions semblent inutilement complexe pour des flotteurs.
($n > 0) - ($n < 0) a toujours fait 2 tests et une soustraction
($n < 0 ? -1 : ($n > 0 ? 1 : 0) un ou deux essais et pas de l'arithmétique, il devrait être plus efficace.
Mais je ne crois pas que la différence sera pertinente pour la plupart des cas d'utilisation.
Je sais que c'est tard, mais qu'en est simplement diviser le nombre par l'abs() de lui-même?
Quelque chose comme:
Mettre tout ce que la gestion d'erreur que vous voulez pour le div par zéro.
Utilisation
strcmp
Docs:-1, 0 or 1
, cependant, je vais essayer dans le code. Merci!$number
est en fait une chaîne de caractères (ce qui représente zéro, comme"n/a"
), cela ne fonctionne pas (min(max) fonctionne ici). Juste de noter, c'est un côté les cas, il suffit de laisser cette pour la note. Il est généralement assez bien travaillé, mais pas pour les variables de chaîne de caractères représentant la valeur numérique0
comme nous le savons, dans PHP. @rocksportrocker: Il n'y a pas vraiment réelle des types comme string ou intever en PHP, donc l'argument de conversion semble faux dans mes yeux. Serait la micro-optimisation pour rien de toute façon à surveiller de près à elle.strcmp("110","12")
dire12
biger que110
(cette fonction comparer des chaînes de caractères char par char)Voici l'un sans boucle: