Existe-t-il un moyen de trouver la valeur absolue d'un nombre sans utiliser la méthode Math.abs () en Java.
Si vous regardez dans Math.abs, vous pourrez probablement trouver la meilleure réponse:
Par exemple, pour les flotteurs:
/*
* Returns the absolute value of a {@code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
Oui:
abs_number = (number < 0) ? -number : number;
Pour les entiers, cela fonctionne bien (sauf pour Integer.MIN_VALUE
, dont la valeur absolue ne peut pas être représentée par int
).
Pour les nombres à virgule flottante, les choses sont plus subtiles. Par exemple, cette méthode - et toutes les autres méthodes publiées jusqu'à présent - ne gérera pas le zéro négatif correctement.
Pour éviter de devoir traiter vous-même de telles subtilités, mon conseil serait de vous en tenir à Math.abs()
.
Comme ça:
if (number < 0) {
number *= -1;
}
Puisque Java est un langage typé statiquement, je pense qu'une méthode abs qui prend un int renvoie un int, si elle attend un float, un float, pour un double, un double. Peut-être qu'il pourrait toujours retourner le type boxed ou unboxed pour les doubles et les doubles et ainsi de suite.
Vous avez donc besoin d'une méthode par type, mais vous avez maintenant un nouveau problème: pour octet, short, int, long, la plage pour les valeurs négatives est 1 fois plus grande que pour les valeurs positives.
Alors, que devrait être retourné pour la méthode
byte abs (byte in) {
// @todo
}
Si l'utilisateur appelle abs sur -128? Vous pouvez toujours renvoyer le type immédiatement supérieur afin que la plage s'adapte à toutes les valeurs d'entrée possibles. Cela posera des problèmes pendant longtemps, là où aucun type plus grand n’existe, et incite l’utilisateur à toujours rejeter la valeur après test - peut-être un problème.
La deuxième option consiste à lancer une exception arithmétique. Cela empêchera le transtypage et la vérification du type de retour pour les situations dans lesquelles l'entrée est connue pour être limitée, telle que X.MIN_VALUE ne puisse pas se produire. Pensez à MOIS, représenté par int.
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
L'habitude "ignorons les rares cas de MIN_VALUE" n'est pas une option. Commencez par faire fonctionner le code - puis faites-le rapidement. Si l'utilisateur a besoin d'une solution plus rapide, mais boguée, il devrait l'écrire lui-même. La solution la plus simple qui puisse fonctionner signifie: simple, mais pas trop simple.
Puisque le code ne repose pas sur l'état, la méthode peut et doit être rendue statique. Cela permet un test rapide:
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
J'attrape la première exception et la laisse courir dans la seconde, juste pour la démonstration.
Il y a une mauvaise habitude dans la programmation, à savoir que les programmeurs tiennent beaucoup plus à la rapidité qu'au bon code. Quel dommage!
Si vous êtes curieux de savoir pourquoi il y a une valeur plus négative que positive, j'ai un diagramme pour vous .
Utilisez la classe Math
Math.abs(num);
Bien que cela ne devrait pas être un goulot d'étranglement car les problèmes de branchement des processeurs modernes ne sont normalement pas un problème, mais dans le cas des nombres entiers, vous pouvez opter pour une solution sans branche, comme indiqué ici: http: //graphics.stanford .edu/~ seander/bithacks.html # IntegerAbs .
(x + (x >> 31)) ^ (x >> 31);
Toutefois, cela échoue dans le cas évident d'Integer.MIN_VALUE. Il s'agit donc d'une utilisation à vos risques et périls.
-num sera égal à num pour Integer.MIN_VALUE comme
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Vous pouvez utiliser :
abs_num = (num < 0) ? -num : num;
Dans le cas de la valeur absolue d'un entier x sans utiliser Math.abs (), des conditions ou des opérations binaires, vous trouverez ci-dessous une solution possible en Java.
(int)(((long)x*x - 1)%(double)x + 1);
Étant donné que Java traite a%b
en tant que a - a/b * b
, le signe du résultat sera le même que "a", peu importe le signe de "b"; (x*x-1)%x
sera égal à abs(x)-1
; le transtypage "long" sert à éviter les débordements et double
permet de diviser par zéro.
Encore une fois, x = Integer.MIN_VALUE
provoquera un débordement en raison de la soustraction de 1.
Voici une solution à une ligne qui renverra la valeur absolue d'un nombre:
abs_number = (num < 0) ? -num : num;