J’essaie de lire certaines valeurs BigDecimal de la chaîne. Disons que j’ai cette chaîne: “1,000,000,000.999999999999999” et je veux en extraire un BigDecimal. Quelle est la façon de le faire?
Tout d’abord, je n’aime pas les solutions utilisant des remplacements de chaînes (en remplaçant les virgules, etc.). Je pense qu’il devrait y avoir un formateur soigné pour faire ce travail pour moi.
J’ai trouvé une classe DecimalFormatter, mais comme elle opère par double, des quantités énormes de précision sont perdues.
Alors, comment puis-je le faire?
Découvrez setParseBigDecimal
dans DecimalFormat. Avec ce setter, parse
retournera un BigDecimal pour vous.
Ssortingng value = "1,000,000,000.999999999999999"; BigDecimal money = new BigDecimal(value.replaceAll(",", "")); System.out.println(money);
Code complet pour prouver qu’aucune NumberFormatException
n’est levée:
import java.math.BigDecimal; public class Tester { public static void main(Ssortingng[] args) { // TODO Auto-generated method stub Ssortingng value = "1,000,000,000.999999999999999"; BigDecimal money = new BigDecimal(value.replaceAll(",", "")); System.out.println(money); } }
Sortie
1000000000.999999999999999
L’exemple de code suivant fonctionne bien (les parameters régionaux doivent être obtenus dynamicment)
import java.math.BigDecimal; import java.text.NumberFormat; import java.text.DecimalFormat; import java.text.ParsePosition; import java.util.Locale; class TestBigDecimal { public static void main(Ssortingng[] args) { Ssortingng str = "0,00"; Locale in_ID = new Locale("in","ID"); //Locale in_ID = new Locale("en","US"); DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(in_ID); nf.setParseBigDecimal(true); BigDecimal bd = (BigDecimal)nf.parse(str, new ParsePosition(0)); System.out.println("bd value : " + bd); } }
Le code pourrait être plus propre, mais cela semble faire l’affaire pour différents environnements.
import java.math.BigDecimal; import java.text.DecimalFormatSymbols; import java.util.Locale; public class Main { public static void main(Ssortingng[] args) { final BigDecimal numberA; final BigDecimal numberB; numberA = ssortingngToBigDecimal("1,000,000,000.999999999999999", Locale.CANADA); numberB = ssortingngToBigDecimal("1.000.000.000,999999999999999", Locale.GERMANY); System.out.println(numberA); System.out.println(numberB); } private static BigDecimal ssortingngToBigDecimal(final Ssortingng formattedSsortingng, final Locale locale) { final DecimalFormatSymbols symbols; final char groupSeparatorChar; final Ssortingng groupSeparator; final char decimalSeparatorChar; final Ssortingng decimalSeparator; Ssortingng fixedSsortingng; final BigDecimal number; symbols = new DecimalFormatSymbols(locale); groupSeparatorChar = symbols.getGroupingSeparator(); decimalSeparatorChar = symbols.getDecimalSeparator(); if(groupSeparatorChar == '.') { groupSeparator = "\\" + groupSeparatorChar; } else { groupSeparator = Character.toSsortingng(groupSeparatorChar); } if(decimalSeparatorChar == '.') { decimalSeparator = "\\" + decimalSeparatorChar; } else { decimalSeparator = Character.toSsortingng(decimalSeparatorChar); } fixedSsortingng = formattedSsortingng.replaceAll(groupSeparator , ""); fixedSsortingng = fixedSsortingng.replaceAll(decimalSeparator , "."); number = new BigDecimal(fixedSsortingng); return (number); } }
Voici comment je le ferais:
public Ssortingng cleanDecimalSsortingng(Ssortingng input, boolean americanFormat) { if (americanFormat) return input.replaceAll(",", ""); else return input.replaceAll(".", ""); }
Évidemment, si cela se passait dans le code de production, ce ne serait pas si simple.
Je ne vois aucun problème à supprimer simplement les virgules de la chaîne.
J’avais besoin d’une solution pour convertir un Ssortingng en BigDecimal sans connaître l’environnement local et être indépendant des parameters régionaux. Je n’ai pas trouvé de solution standard pour ce problème, j’ai donc écrit ma propre méthode d’assistance. Peut-être que ça aide aussi quelqu’un d’autre:
Mise à jour: Attention! Cette méthode d’assistance ne fonctionne que pour les nombres décimaux, donc les nombres ont toujours un point décimal! Sinon, la méthode d’assistance pourrait donner un résultat erroné pour les nombres compris entre 1000 et 999999 (plus / moins). Merci à bezmax pour son excellente consortingbution!
static final Ssortingng EMPTY = ""; static final Ssortingng POINT = '.'; static final Ssortingng COMMA = ','; static final Ssortingng POINT_AS_STRING = "."; static final Ssortingng COMMA_AS_STRING = ","; /** * Converts a Ssortingng to a BigDecimal. * if there is more than 1 '.', the points are interpreted as thousand-separator and will be removed for conversion * if there is more than 1 ',', the commas are interpreted as thousand-separator and will be removed for conversion * the last '.' or ',' will be interpreted as the separator for the decimal places * () or - in front or in the end will be interpreted as negative number * * @param value * @return The BigDecimal expression of the given ssortingng */ public static BigDecimal toBigDecimal(final Ssortingng value) { if (value != null){ boolean negativeNumber = false; if (value.containts("(") && value.contains(")")) negativeNumber = true; if (value.endsWith("-") || value.startsWith("-")) negativeNumber = true; Ssortingng parsedValue = value.replaceAll("[^0-9\\,\\.]", EMPTY); if (negativeNumber) parsedValue = "-" + parsedValue; int lastPointPosition = parsedValue.lastIndexOf(POINT); int lastCommaPosition = parsedValue.lastIndexOf(COMMA); //handle '1423' case, just a simple number if (lastPointPosition == -1 && lastCommaPosition == -1) return new BigDecimal(parsedValue); //handle '45.3' and '4.550.000' case, only points are in the given Ssortingng if (lastPointPosition > -1 && lastCommaPosition == -1){ int firstPointPosition = parsedValue.indexOf(POINT); if (firstPointPosition != lastPointPosition) return new BigDecimal(parsedValue.replace(POINT_AS_STRING, EMPTY)); else return new BigDecimal(parsedValue); } //handle '45,3' and '4,550,000' case, only commas are in the given Ssortingng if (lastPointPosition == -1 && lastCommaPosition > -1){ int firstCommaPosition = parsedValue.indexOf(COMMA); if (firstCommaPosition != lastCommaPosition) return new BigDecimal(parsedValue.replace(COMMA_AS_STRING, EMPTY)); else return new BigDecimal(parsedValue.replace(COMMA, POINT)); } //handle '2.345,04' case, points are in front of commas if (lastPointPosition < lastCommaPosition){ parsedValue = parsedValue.replace(POINT_AS_STRING, EMPTY); return new BigDecimal(parsedValue.replace(COMMA, POINT)); } //handle '2,345.04' case, commas are in front of points if (lastCommaPosition < lastPointPosition){ parsedValue = parsedValue.replace(COMMA_AS_STRING, EMPTY); return new BigDecimal(parsedValue); } throw new NumberFormatException("Unexpected number format. Cannot convert '" + value + "' to BigDecimal."); } return null; }
Bien sûr, j'ai testé la méthode:
@Test(dataProvider = "testBigDecimals") public void toBigDecimal_defaultLocaleTest(Ssortingng ssortingngValue, BigDecimal bigDecimalValue){ BigDecimal convertedBigDecimal = DecimalHelper.toBigDecimal(ssortingngValue); Assert.assertEquals(convertedBigDecimal, bigDecimalValue); } @DataProvider(name = "testBigDecimals") public static Object[][] bigDecimalConvertionTestValues() { return new Object[][] { {"5", new BigDecimal(5)}, {"5,3", new BigDecimal("5.3")}, {"5.3", new BigDecimal("5.3")}, {"5.000,3", new BigDecimal("5000.3")}, {"5.000.000,3", new BigDecimal("5000000.3")}, {"5.000.000", new BigDecimal("5000000")}, {"5,000.3", new BigDecimal("5000.3")}, {"5,000,000.3", new BigDecimal("5000000.3")}, {"5,000,000", new BigDecimal("5000000")}, {"+5", new BigDecimal("5")}, {"+5,3", new BigDecimal("5.3")}, {"+5.3", new BigDecimal("5.3")}, {"+5.000,3", new BigDecimal("5000.3")}, {"+5.000.000,3", new BigDecimal("5000000.3")}, {"+5.000.000", new BigDecimal("5000000")}, {"+5,000.3", new BigDecimal("5000.3")}, {"+5,000,000.3", new BigDecimal("5000000.3")}, {"+5,000,000", new BigDecimal("5000000")}, {"-5", new BigDecimal("-5")}, {"-5,3", new BigDecimal("-5.3")}, {"-5.3", new BigDecimal("-5.3")}, {"-5.000,3", new BigDecimal("-5000.3")}, {"-5.000.000,3", new BigDecimal("-5000000.3")}, {"-5.000.000", new BigDecimal("-5000000")}, {"-5,000.3", new BigDecimal("-5000.3")}, {"-5,000,000.3", new BigDecimal("-5000000.3")}, {"-5,000,000", new BigDecimal("-5000000")}, {null, null} }; }
resultSsortingng = subjectSsortingng.replaceAll("[^.\\d]", "");
va supprimer tous les caractères sauf les chiffres et le sharepoint votre chaîne.
Pour le rendre compatible avec les parameters régionaux, vous pouvez utiliser getDecimalSeparator()
partir de java.text.DecimalFormatSymbols
. Je ne connais pas Java, mais ça pourrait ressembler à ceci:
sep = getDecimalSeparator() resultSsortingng = subjectSsortingng.replaceAll("[^"+sep+"\\d]", "");
L’ancien sujet, mais le plus facile peut-être, est d’utiliser les communs Apache NumberUtils qui ont une méthode createBigDecimal (valeur de chaîne) ….
Je suppose (espère) que cela prend en compte les parameters régionaux, sinon cela serait plutôt inutile.
S’il vous plaît essayez ceci son travail pour moi
BigDecimal bd ; Ssortingng value = "2000.00"; bd = new BigDecimal(value); BigDecimal currency = bd;