java entier arrondissement (division)
J'ai eu une surprise avec la division entière pas arrondi vers le bas comme prévu.
Code Simple:
public class HelloMath {
public static void main(String[] args) {
for (int s=1; s< 20; s++)
{
int div = 1<<s;
int res = (int) ((float)-8/ s);
System.out.printf("Bit %d, result %d\n", s, res);
}
}
}
Même avec de l'explicite (float) jette, la sortie est:
Bit 1, result -8
Bit 2, result -4
Bit 3, result -2
Bit 4, result -2
Bit 5, result -1
Bit 6, result -1
Bit 7, result -1
Bit 8, result -1
Bit 9, result 0
Bit 10, result 0
Bit 11, result 0
Bit 12, result 0
Bit 13, result 0
Bit 14, result 0
Bit 15, result 0
Bit 16, result 0
Bit 17, result 0
Bit 18, result 0
Bit 19, result 0
Je m'attendais à -1 tout le chemin vers le bas.
Le code réel où ce qui se passe ne ce:
public static int fluidTo8th(int fluid)
{
if (0 == fluid)
return 0; //Technically, this isn't needed :-).
int wholePart = (fluid-1) * 8 / RealisticFluids.MAX_FLUID; //-1 gets rounding correct;
//consider fluid of exactly 1/8th.
return 1+wholePart;
}
RealisticFluids.MAX_FLUID a de la valeur (1<<20).
Le code est censé prendre une entrée qui est de 1 à MAX_FLUID (0 ne devrait se produire que si le bloc d'entrée d'air), et de retourner un nombre de 0 à 7 -- 1 à 1/8e de max est 0, 1/8e de +1 à 2/8 2, 7/8e + 1-8/8 7.
J'attends de math entier pour le tour de toutes les fractions vers le bas. Mais ce n'est pas le cas -- je me retrouve avec tout-en-un les erreurs de tous sur la place que 5.999 des vents jusqu'à devenir 6 au lieu de 5.
- Où est ce comportement documenté?
- Quelle est la meilleure façon de contourner pour obtenir l'arrondi vers le bas que je l'ai attendu?
(code contexte: https://github.com/keybounce/Finite-Fluids/blob/master/src/main/java/com/mcfht/realisticfluids/Util.java)
div
, au lieu de par s
. Je veux dire, vous n'avez créer div
pour une raison, je suppose.Lorsque
s = 1
, en divisant -8 par s
est -8, et en divisant -8 par div
(1<<1=2) -4, alors, pourquoi vous attendez à -1? --- Quand s = 9
, en divisant -8 par s
est 0 (arrondi vers le bas à partir de -0.8888889), et en divisant -8 par div
(1<<9=512) est 0 (arrondi vers le bas à partir de -0.015625), alors, pourquoi vous attendez à -1?OriginalL'auteur Keybounce | 2016-07-22
Vous devez vous connecter pour publier un commentaire.
Division entière en Java ne pas arrondir vers le bas comme vous le comprenez (ie. à la valeur la plus faible). Dans la terminologie de Java, en arrondissant les moyens l'arrondi vers zéro.
Voici la section pertinente de la JLS, qui dit explicitement
La façon la plus simple pour obtenir l'arrondi que vous voulez est de faire floating point de la division au lieu de cela, et d'utiliser
Math.floor
à la ronde.RoundingMode
:DOWN
: mode d'Arrondi à l'arrondi vers zéro,UP
: mode d'Arrondi à tour loin de zéro,FLOOR
: mode d'Arrondi à tour vers l'infini négatif,CEILING
: mode d'Arrondi à tour vers l'infini positif.Très bon +1. Maintenant, pour un plein de répondre, d'expliquer à l'OP pourquoi "je m'attendais à -1 tout le chemin vers le bas" est un trompe l'attente. Astuce: en Divisant par
s
, pasdiv
, et même alors, pours=1
/div = 1<<s = 2
, vous ne parvenez toujours pas à obtenir -1, si l'utilisation des
oudiv
.OriginalL'auteur resueman
Tout d'abord, vous ne faites pas de division entière: Vous êtes en train de faire floating point de la division.
(float)-8
est un flottant expression. Par conséquent, las
dans(float)-8/s
obtient promu (float) avant la division arrive.Puis flottant, point de résultat est converti en int. Reuseman dit que l'entier de la division de tours vers zéro. Eh bien, float->int conversion complète également vers zéro.
OriginalL'auteur Solomon Slow