Réponses:
Vous faites 157/32
ce qui divise deux entiers l'un avec l'autre, ce qui aboutit toujours à un entier arrondi vers le bas. Par conséquent, le (int) Math.ceil(...)
ne fait rien. Il existe trois solutions possibles pour réaliser ce que vous voulez. Je recommande d' utiliser l' option 1 ou l' option 2 . Veuillez NE PAS utiliser l' option 0 .
## Option 0
Convertissez a
et b
en un double, et vous pouvez utiliser la division et Math.ceil
comme vous le souhaitez. Cependant, je déconseille fortement l'utilisation de cette approche, car la double division peut être imprécise. Pour en savoir plus sur l'imprécision des doubles, consultez cette question .
int n = (int) Math.ceil((double) a / b));
##Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
Vous faites a / b
avec toujours floor si a
et b
sont tous les deux des entiers. Ensuite, vous avez une instruction if en ligne qui vérifie si vous devez ou non plafonner au lieu de floor. Donc +1 ou +0, s'il y a un reste avec la division, vous avez besoin de +1. a % b == 0
vérifie le reste.
##Option 2
Cette option est très courte, mais peut-être pour certains moins intuitive. Je pense que cette approche moins intuitive serait plus rapide que l'approche de double division et comparaison:
veuillez noter que cela ne fonctionne pas pour b < 0
.
int n = (a + b - 1) / b;
Pour réduire les risques de débordement, vous pouvez utiliser ce qui suit. Cependant, veuillez noter que cela ne fonctionne pas pour a = 0
et b < 1
.
int n = (a - 1) / b + 1;
## Explication derrière "l'approche moins intuitive"
Depuis la division de deux entiers en Java (et la plupart des autres langages de programmation), le résultat sera toujours plancher. Alors:
int a, b;
int result = a/b (is the same as floor(a/b) )
Mais nous ne voulons pas floor(a/b)
, mais ceil(a/b)
, et en utilisant les définitions et les graphiques de Wikipedia :
Avec ces graphiques de la fonction du sol et du plafond, vous pouvez voir la relation.
Vous pouvez le voir floor(x) <= ceil(x)
. Nous avons besoin floor(x + s) = ceil(x)
. Nous devons donc trouver s
. Si nous supposons que 1/2 <= s < 1
ce sera juste (essayez quelques chiffres et vous verrez que c'est le cas, j'ai moi-même du mal à le prouver). Et 1/2 <= (b-1) / b < 1
donc
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
Ce n'est pas une vraie preuve, mais j'espère que vous en êtes satisfait. Si quelqu'un peut mieux l'expliquer, je l'apprécierais aussi. Demandez-le peut-être sur MathOverflow .
157/32 est int/int
, ce qui entraîne un int
.
Essayez d'utiliser le double littéral - 157/32d
, ce int/double
qui donne un double
.
157/32
est une division entière car tous les littéraux numériques sont des entiers sauf indication contraire avec un suffixe ( d
pour double l
pour long)
la division est arrondie vers le bas (à 4) avant d'être convertie en un double (4.0) qui est ensuite arrondi (à 4.0)
si vous utilisez une variable, vous pouvez éviter cela
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Personne n'a mentionné le plus intuitif:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
Cette solution corrige l' imprécision de la double division.
En Java, l'ajout d'un .0 en fera un double ...
int total = (int) Math.ceil(157.0 / 32.0);
Lors de la division de deux entiers, par exemple,
int c = (int) a / (int) b;
le résultat est un int
, dont la valeur est a
divisée par b
, arrondie vers zéro. Parce que le résultat est déjà arrondi, ceil()
ne fait rien. Notez que cet arrondi n'est pas le même que floor()
, qui arrondit à l'infini négatif. Donc, 3/2
égal 1
(et floor(1.5)
égal 1.0
, mais (-3)/2
égal -1
(mais floor(-1.5)
égal -2.0
).
Ceci est important parce que si a/b
toujours les mêmes que floor(a / (double) b)
, vous pourriez tout mettre en œuvre ceil()
des a/b
comme -( (-a) / b)
.
La suggestion d'obtenir ceil(a/b)
de
int n = (a + b - 1) / b;
, ce qui équivaut à a / b + (b - 1) / b
, ou(a - 1) / b + 1
fonctionne parce que ceil(a/b)
est toujours un supérieur à floor(a/b)
, sauf quand a/b
est un nombre entier. Donc, vous voulez le faire passer (ou dépasser) le nombre entier suivant, sauf s'il a/b
s'agit d'un nombre entier. L'ajout 1 - 1 / b
fera cela. Pour les nombres entiers, cela ne les poussera pas tout à fait au nombre entier suivant. Pour tout le reste, ce sera le cas.
Yikes. J'espère que cela a du sens. Je suis sûr qu'il existe une manière plus élégante mathématiquement de l'expliquer.
Aussi pour convertir un nombre entier en nombre réel, vous pouvez ajouter un point:
int total = (int) Math.ceil(157/32.);
Et le résultat de (157/32.) Sera réel aussi. ;)
int total = (int) Math.ceil( (double)157/ (double) 32);
Java fournit uniquement la division /
par étage par défaut. Mais nous pouvons écrire un plafond en termes de plancher . Voyons voir:
Tout entier y
peut être écrit avec le formulaire y == q*k+r
. Selon la définition de la division de plancher (ici floor
) qui arrondit r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
et de division de plafond (ici ceil
) qui arrondit r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
où l' on peut remplacer r+1
par r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Ensuite, nous substituons la première équation à la troisième pour q
obtenir
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Enfin, étant donné tout entier y
où y = q*k+r+1
pour certains q
, k
, r
, nous avons
ceil(y, k) == floor(y-1, k) + 1
Et nous avons terminé. J'espère que cela t'aides.
ceil
est défini comme tel à partir de la définition intuitive, en particulier lorsque nous prenons le ceil d'un entier, c'est-à-dire r1 = k. Étant donné que les cas extrêmes sont ce qui est délicat à ce sujet, je pense qu'il faut le préciser un peu plus.
Il existe deux méthodes par lesquelles vous pouvez arrondir votre double valeur.
Si vous voulez que votre réponse 4.90625 soit 4, vous devez utiliser Math.floor et si vous voulez que votre réponse 4.90625 soit 5, vous pouvez utiliser Math.ceil
Vous pouvez vous référer au code suivant pour cela.
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
int total = (157-1)/32 + 1
ou plus général
(a-1)/b +1