Dans Java 9, le système BigDecimal # ROUND_ ~
est finalement devenu @ Deprecated
.
Néanmoins, dans les blogs et les entrées qui expliquent BigDecimal
, en expliquant BigDecimal # setScale
, BigDecimal # divide
, etc., il est expliqué en utilisant le systèmeBigDecimal # ROUND_ ~
. Que voulez-vous dire? Tout est «@ obsolète» dans Java 9, n'est-ce pas?
J'ai décidé d'écrire un article parce que je me sens mal à l'aise récemment.
Tout d'abord, des bases.
Il est essentiellement généré par la méthode suivante.
BigDecimal value = BigDecimal.valueOf(1234.567);//Génération à partir d'un système numérique
BigDecimal value = new BigDecimal("1234.567");//Généré à partir d'une chaîne
Puisque «0», «1», «10» sont déjà définis, utilisez-les.
BigDecimal.ZERO
BigDecimal.ONE
BigDecimal.TEN
La génération à partir de la chaîne de caractères est telle que spécifiée par la chaîne de caractères dans scale
.
System.out.println(new BigDecimal("1234.567").scale()); // → 3
System.out.println(new BigDecimal("1234.56700").scale());// → 5
Utilisez BigDecimal # valueOf
pour générer à partir d'un nombre (double). Il serait ridicule de le générer avec «new».
BigDecimal value = new BigDecimal(1234.567);// NG!!Génération à partir d'un système numérique
System.out.println(value);// → 1234.5670000000000072759576141834259033203125
ResultSet#getBigDecimal
Lors de l'obtention de ResultSet
, il y a ResultSet # getBigDecimal
, alors utilisez ceci.
BigDecimal value = rs.getBigDecimal("COL");
Ce qui suit est inutile, donc NG
BigDecimal value = BigDecimal.valueOf(rs.getDouble("COL"));
BigDecimal value = new BigDecimal(rs.getString("COL"));
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a + b
BigDecimal value = a.add(b);
System.out.println(value);// 579
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a - b
BigDecimal value = a.subtract(b);
System.out.println(value);// -333
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a * b
BigDecimal value = a.multiply(b);
System.out.println(value);// 56088
Utilisez BigDecimal # scaleByPowerOfTen
.
BigDecimal src = BigDecimal.valueOf(0.123);
BigDecimal value = src.scaleByPowerOfTen(2);//Centuple(10 au carré)
System.out.println(value);// 12.3
C'est beaucoup plus propre que src.multiply (BigDecimal.valueOf (100))
, et vous n'avez pas besoin de créer une instance de 100
.
Utilisez BigDecimal # negate
.
BigDecimal src = BigDecimal.valueOf(123);
BigDecimal value = src.negate();
System.out.println(value);// -123
Veuillez arrêter d'écrire ce qui suit.
BigDecimal value = src.multiply(BigDecimal.valueOf(-1));
import java.math.RoundingMode;
//・ ・ ・
BigDecimal a = BigDecimal.valueOf(123);
BigDecimal b = BigDecimal.valueOf(456);
// value = a / b
BigDecimal value = a.divide(b, 3 /* ← scale */, RoundingMode.HALF_UP /*← Arrondi*/);
System.out.println(value);// 0.270
RoundingMode
ne sont pas disponiblesLe style d'écriture suivant est NG
BigDecimal value = a.divide(b, 3, BigDecimal.ROUND_HALF_UP);
Pour plus d'informations sur le Mode arrondi
, veuillez consulter [en bas](# mode arrondi) pour plus de détails.
échelle
Il existe également une méthode BigDecimal # divide
qui ne spécifie pas scale
,
Lorsqu'elle n'est pas divisible, ʻArithmeticException se produira, il est donc préférable d'utiliser la version spécifiée
scale`.
Utilisez BigDecimal # scaleByPowerOfTen
.
BigDecimal src = BigDecimal.valueOf(8);
BigDecimal value = src.scaleByPowerOfTen(-2);// 1/100(dix-Au carré)
System.out.println(value);// 0.08
import java.math.RoundingMode;
//・ ・ ・
BigDecimal src = BigDecimal.valueOf(123.456);
//Arrondi
BigDecimal value = src.setScale(2, RoundingMode.HALF_UP);
System.out.println(value); // → 123.46
//Rassembler
BigDecimal value = src.setScale(2, RoundingMode.UP);
//Tronquer
BigDecimal value = src.setScale(2, RoundingMode.DOWN);
RoundingMode
ne sont pas disponiblesLe style d'écriture suivant est NG
BigDecimal value = src.setScale(2, BigDecimal.ROUND_HALF_UP);
Pour plus d'informations sur le Mode arrondi
, veuillez consulter [en bas](# mode arrondi) pour plus de détails.
BigDecimal#toPlainString
BigDecimal # toString
peut être exponentiel, donc je pense qu'il est préférable d'utiliser BigDecimal # toPlainString
.
BigDecimal value = new BigDecimal("0.0000001");
System.out.println(value.toString()); // → 1E-7
System.out.println(value.toPlainString());// → 0.0000001
jackson a également une option pour utiliser toPlainString
.
JsonGenerator.Feature.html#WRITE_BIGDECIMAL_AS_PLAIN
Les deux «BigDecimal # toString» et «BigDecimal # toPlainString» considèrent «scale» dans la chaîne et sont conservés même si la fraction est suivie de «0».
Si vous souhaitez désactiver cette option, utilisez BigDecimal # stripTrailingZeros
.
Vous n'avez pas à travailler dur avec les expressions régulières.
BigDecimal value = new BigDecimal("1.000000");
System.out.println(value); // → 1.000000
System.out.println(value.stripTrailingZeros());// → 1
BigDecimal # stripTrailingZeros
a un bogue jusqu'à java7.
JDK-6480539 : BigDecimal.stripTrailingZeros() has no effect on zero itself ("0.0")・
long ・
double`BigDecimal value = BigDecimal.valueOf(12345);
int i = value.intValue();
long l = value.longValue();
double d = value.doubleValue();
Il y a aussi «float» et «BigInteger».
Il existe une version de conversion en nombres entiers qui lève une exception lorsque des informations sont perdues hors tolérance. Inversement, la version normale est ignorée même si des informations sont perdues.
int i = value.intValueExact();
long l = value.longValueExact();
Il existe également des versions «byte», «short» et «BigInteger» de la famille de méthodes «-ValueExact».
Puisque BigDecimal # equals
renvoie false
si scale
ne correspond pas,
Si vous écrivez un système qui ne vous intéresse pas, tel que «scale», vous devez juger si le résultat de «compareTo» correspond à «0».
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
System.out.println(value1.equals(value2)); // false
System.out.println(value1.compareTo(value2) == 0);// true
HashMap
BigDecimal # equals
・ BigDecimal # hashCode
considère également scale
, donc
Écrire un système qui ne vous intéresse pas, tel que «scale», peut vous blesser.
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
Map<BigDecimal, String> map = new HashMap<>();
map.put(value1, "data");
System.out.println(map.get(value2));// null
Dans ce cas, vous voudrez peut-être stabiliser scale
avec BigDecimal # stripTrailingZeros
.
BigDecimal value1 = new BigDecimal("123.0"); // scale=1
BigDecimal value2 = new BigDecimal("123.00");// scale=2
Map<BigDecimal, String> map = new HashMap<>();
map.put(value1.stripTrailingZeros(), "data");
System.out.println(map.get(value2.stripTrailingZeros()));// data
BigDecimal # stripTrailingZeros
a un bogue jusqu'à java7.
JDK-6480539 : BigDecimal.stripTrailingZeros() has no effect on zero itself ("0.0")RoundingMode
RoundingMode
est défini par ʻenum`, et il y a diverses choses telles que" arrondir "," arrondir vers le bas "," arrondir à l'infini positif "et" arrondir à l'infini négatif "en plus de" arrondir ", donc javadoc une fois. Je pense que tu devrais vérifier ça.
Ce qui suit est une transcription de Rounding Mode javadoc.
CEILING C'est un mode à rouler pour approcher l'infini positif. DOWN Ce mode s'arrondit pour approcher 0. FLOOR C'est un mode à rouler pour approcher l'infini négatif. HALF_DOWN Il s'agit d'un mode d'arrondi qui arrondit au "nombre le plus proche" (si les nombres des deux côtés sont égaux, ils sont tronqués). HALF_EVEN Mode d'arrondi pour arrondir au "nombre le plus proche" (cependant, si les nombres des deux côtés sont à distances égales, arrondissez au côté pair). HALF_UP Mode d'arrondi pour arrondir au «nombre le plus proche» (cependant, si les nombres des deux côtés sont égaux, arrondissez). UNNECESSARY Un mode d'arrondi qui indique que le résultat de l'opération requise est précis et ne nécessite pas d'arrondi. UP Ce mode arrondit à 0.
RoundingMode
ne sont pas disponiblesN'utilisez pas le système BigDecimal # ROUND_ ~
et les méthodes qui supposent l'utilisation de ceux-ci. (@ Déprécié
dans Java 9)
Il devrait y avoir une paire de méthodes qui utilisent RoundingMode
pour chacune, alors utilisons-les.
La méthode qui est devenue «@ obsolète» dans 9 est un héritage de l'ère 1.4. Cependant, quand je cherche habituellement sur Google avec "BigDecimal division", je suis désespéré parce que toutes les pages utilisant "BigDecimal.ROUND_HALF_UP" sortent.
Recommended Posts