Показване на суми на пари с думи

1. Общ преглед

В този урок ще видим как можем да преобразуваме парична сума в представяне на думи в Java.

Също така ще видим как може да изглежда персонализирана реализация чрез външна библиотека - Tradukisto.

2. Прилагане

Нека първо започнем с нашето собствено изпълнение. Първата стъпка е да декларираме два масива String със следните елементи:

public static String[] ones = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; public static String[] tens = { "", // 0 "", // 1 "twenty", // 2 "thirty", // 3 "forty", // 4 "fifty", // 5 "sixty", // 6 "seventy", // 7 "eighty", // 8 "ninety" // 9 };

Когато получим вход, ще трябва да обработим невалидните стойности (нулеви и отрицателни стойности). След като бъде получен валиден вход, можем да извлечем броя долари и центове в променливи:

 long dollars = (long) money; long cents = Math.round((money - dollars) * 100);

Ако броят дал е по-малко от 20, а след това ще получите най-подходящите от тях " елемент от масива на базата на индекса:

if (n < 20) { return ones[(int) n]; }

Ще използваме подобен подход за числа под 100, но сега трябва да използваме и десетки масив:

if (n < 100) { return tens[(int) n / 10] + ((n % 10 != 0) ? " " : "") + ones[(int) n % 10]; }

Правим това по подобен начин за числа, по-малки от хиляда.

След това използваме рекурсивни повиквания, за да се справим с номера, по-малки от един милион, както е показано по-долу:

if (n < 1_000_000) { return convert(n / 1000) + " thousand" + ((n % 1000 != 0) ? " " : "") + convert(n % 1000); }

Същият подход се използва за числа, които са по-малко от един милиард и т.н.

Ето основния метод, който може да бъде извикан да направи това преобразуване:

 public static String getMoneyIntoWords(double money) { long dollars = (long) money; long cents = Math.round((money - dollars) * 100); if (money == 0D) { return ""; } if (money  0) { dollarsPart = convert(dollars) + " dollar" + (dollars == 1 ? "" : "s"); } String centsPart = ""; if (cents > 0) { if (dollarParts.length() > 0) { centsPart = " and "; } centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s"); } return dollarsPart + centsPart; }

Нека тестваме нашия код, за да се уверим, че работи:

@Test public void whenGivenDollarsAndCents_thenReturnWords() { String expectedResult = "nine hundred twenty four dollars and sixty cents"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(924.6)); } @Test public void whenTwoBillionDollarsGiven_thenReturnWords() { String expectedResult = "two billion one hundred thirty three million two hundred" + " forty seven thousand eight hundred ten dollars"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(2_133_247_810)); } @Test public void whenThirtyMillionDollarsGiven_thenReturnWords() { String expectedResult = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(33_348_978)); }

Нека също да тестваме някои крайни случаи и да се уверим, че сме ги обхванали и:

@Test public void whenZeroDollarsGiven_thenReturnEmptyString() { assertEquals("", NumberWordConverter.getMoneyIntoWords(0)); } @Test public void whenNoDollarsAndNineFiveNineCents_thenCorrectRounding() { assertEquals( "ninety six cents", NumberWordConverter.getMoneyIntoWords(0.959)); } @Test public void whenNoDollarsAndOneCent_thenReturnCentSingular() { assertEquals( "one cent", NumberWordConverter.getMoneyIntoWords(0.01)); } 

3. Използване на библиотека

Сега, след като внедрихме собствен алгоритъм, нека направим това преобразуване, като използваме съществуваща библиотека.

Tradukisto е библиотека за Java 8+, която може да ни помогне да преобразуваме числата в техните представления на думи. Първо, трябва да го импортираме в нашия проект (най-новата версия на тази библиотека можете да намерите тук):

 pl.allegro.finance tradukisto 1.0.1 

Сега можем да използваме MoneyConverters е asWords () метод, за да направите това преобразуване:

public String getMoneyIntoWords(String input) { MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; return converter.asWords(new BigDecimal(input)); }

Нека тестваме този метод с прост тестов случай:

@Test public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { assertEquals( "three hundred ten £ 00/100", NumberWordConverter.getMoneyIntoWords("310")); }

Бихме могли да използваме и библиотеката ICU4J, за да направим това, но тя е голяма и се предлага с много други функции, които са извън обхвата на тази статия.

Разгледайте го обаче, ако е необходима поддръжка на Unicode и глобализацията.

4. Заключение

В тази бърза статия видяхме два подхода за това как да превърнем преобразуването на парична сума в думи.

Кодът за всички примери, обяснени тук, и много повече могат да бъдат намерени в GitHub.