/* * [Polish.java] * * Summary: Display a number in Polish words. * * Copyright: (c) 1999-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 1999-01-20 */ package com.mindprod.inwords; /** * Display a number in Polish words. *

* e.g. * -12345 -> "minus twelve thousand forty-five" *

* This class is based on a number table in the Berlitz Polish Phrase * Book & Dictionary * ISBN:2-8315-0876-2 and a program I found on the Internet written by * Gabriel Jaros * <gabriel@tubka.com.pl> in Polish in Visual Basic. *

* We need the following accented letters: * a, &aogonek \u0105 * c' &cacute \u0107 * e, &eogonek \u0119 * s' &sacute \u015b *

* They only render properly with NT and Internet Explorer. On * earlier OSes they display without accents. *

* Why is this code written in an unusual way? see inwords.use * * @author Roedy Green, Canadian Mind Products * @version 1.0 1999-01-20 * @since 1999-01-20 */ public final class Polish implements ToWords { private static final int FIRST_COPYRIGHT_YEAR = 1999; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 1999-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String MINUS = "minus"; private static final String ZERO = "zero"; private static final String[] groupName = { /* * American: unit, hundred, thousand, million, billion, trillion, * quadrillion, quintillion */ ""/* 1 */, ""/* * 100 sto handled specially since it is different for each * multiple. */, "tysi\u0105c"/* * 1000 tysiac tysyi&aogonek;c, varies in a very complex * way. */, "milion"/* 10 ^ 6 */, // 1 milion // 2 to 4 milliony // 5 to 21 milionów // 22 to 24 miliony // 25 to 31 milionów // 32 to 34 miliony // 35 to 41 milionów // .. // 95 to 99 mmilionów "miliard"/* 10 ^ 9 */, // 1 miliard // 2 to 4 miliardy // 5 to 21 miliardów // 22 to 24 miliardy // 25 to 31 miliardów // 32 to 34 miliardy // 35 to 41 miliard;w // .. // 95 to 99 miliardów "bilion"/* 10 ^ 12 guess */, // 1 bilion // 2 to 4 biliony // 5 to 21 bilionów // 22 to 24 biliony // 25 to 31 bilionów // 32 to 34 biliony // 35 to 41 bilion;w // .. // 95 to 99 bilionów "biliard"/* 10 ^ 15 guess */, // 1 biliard // 2 to 4 biliardy // 5 to 21 biliardów // 22 to 24 biliardy // 25 to 31 biliardów // 32 to 34 biliardy // 35 to 41 biliard;w // .. // 95 to 99 biliardów "trilion"/* 10 ^ 18 guess */, // 1 trilion // 2 to 4 triliony // 5 to 21 trilionów // 22 to 24 triliony // 25 to 31 trilionów // 32 to 34 triliony // 35 to 41 trilion;w // .. // 95 to 99 trilionów }; /* Polish is unusual. It has special words for each multiple of 100 */ private static final String[] hundredsGroupName = { "" /* 0 */, "sto" /* 100 */, "dwie\u015bcie" /* 200 dwiescie dwieście */, "trzysta" /* 300 */, "czterysta" /* 400 */, "pi\u0119\u0107set" /* 500 piecset pi&eogonek;ćset */, "sze\u015b\u0107set" /* 600 szescet sześćset */, "siedemset" /* 700 */, "osiemset" /* 800 */, "dziewi\u0119\u0107set" /* 900 dziewiecset dziewi&egonekćset */, }; private static final String[] lowName = { /* zero is shown as "" since it is never used in combined forms */ /* 0 .. 19 */ "", "jeden" /* 1 */, "dwa" /* 2 */, "trzy" /* 3 */, "cztery" /* 4 */, "pi\u0119\u0107" /* 5 piec pi&eogonek;ć */, "sze\u015b\u0107" /* 6 szesc sześć */, "siedem" /* 7 */, "osiem" /* 8 */, "dziewi\u0119\u0107" /* 9 dziewiec dziewi&eogonek;ć */, "dziesi\u0119\u0107" /* 10 dziesiec dziesi&eogonek;ć */, "jedena\u015bcie" /* 11 jedenascie jedenaście */, "dwana\u015bcie" /* 12 dwanascie dwanaście */, "trzyna\u015bcie" /* 13 trzynascie trzynaście */, "czterna\u015bcie" /* 14 czternascie czternaście */, "pi\u0119tna\u015bcie" /* 15 pietnascie pi&eogonek;etnaście */, "szesna\u015bcie" /* 16 szesnascie szesnaście */, "siedemna\u015bcie" /* 17 siedemnascie siedemnaście */, "osiemna\u015bcie" /* 18 osiemnascie osiemnaście */, "dziewi\u0119tna\u015bcie" /* * 19 dziewietsnascie * dziwi&eogonek;tnaście */ }; /* * Polish in unusual. The word for Thousand changes depending on the * multiple */ private static final String[] thousandsGroupName = { "" /* 0 */, "tysi\u0105c" /* 1000 tysiac tysyi&aogonek;c */, "tysi\u0105ce" /* 2000 tysiace tysyi&aogonek;ce */, "tysi\u0105ce" /* 3000 tysiace tysyi&aogonek;ce */, "tysi\u0105ce" /* 4000 tysiace tysyi&aogonek;ce */, "tysi\u0119cy" /* 5000 tysiecy tysyi&eogonek;cy */, "tysi\u0119cy" /* 6000 tysiecy tysyi&eogonek;cy */, "tysi\u0119cy" /* 7000 tysiecy tysyi&eogonek;cy */, "tysi\u0119cy" /* 8000 tysiecy tysyi&eogonek;cy */, "tysi\u0119cy" /* 9000 tysiecy tysyi&eogonek;cy */ }; private static final String[] tys = { /* 0, 10, 20, 30 ... 90 */ "" /* 0 */, "" /* 10 */, "dwadzie\u015bcia" /* 20 dwadziescia dwadzieścia */, "trzydzie\u015bci" /* 30 trzydziesci tryzydzieści */, "czterdzie\u015bci" /* 40 czterdziesci czterdzieści */, "pi\u0119\u0107dziesi\u0105t" /* * 50 piecdziesiat * pi&egonek;ćdiesi&aogonek;t */, "sze\u015b\u0107dzies\u0105t" /* * 60 szescdziesat * sześćdzies&aogonek;t */, "siedemdziesi\u0105t" /* 70 siedemdziesiat siedemdziesi&agononek,t */, "osiemdziesi\u0105t" /* 80 osiemdziesiat osiemdziesi&agononek;t */, "dziewi\u0119\u0107dziesi\u0105t" /* * 90 dziewiecdziesiat * dziewi&eogonek;ćdziesi&aogonek;t */ }; private static final int[] divisor = { /* * HowToProcess many of this group is needed to form one of the succeeding group. */ /* * American: unit, hundred, thousand, million, billion, trillion, * quadrillion, quintillion */ 100, 10, 1000, 1000, 1000, 1000, 1000, 1000 }; /* * In Polish the group name depends on the multiplier. There is a * different word for hundred in 100, 200, 300 etc. */ private static String getGroupName( int multiplier, int range ) { switch ( range ) { case 0:/* units */ return ""; case 1:/* hundreds */ /* mulitplier will always be 0 ..9 */ return hundredsGroupName[ multiplier ]; case 2:/* thousands */ if ( 10 <= multiplier && multiplier <= 19 ) { multiplier = 9; } else if ( multiplier >= 20 ) { multiplier = multiplier % 10; if ( multiplier == 0 ) { multiplier = 9; } } return thousandsGroupName[ multiplier ]; default:/* millions on up */ if ( multiplier < 10 ) { switch ( multiplier ) { case 0: return ""; case 1: return groupName[ range ]; case 2: case 3: case 4: return groupName[ range ] + 'y'; default: return groupName[ range ] + "\u00f3w"; } } else { // 10 .. 99 switch ( multiplier % 10 ) { case 2: case 3: case 4: return groupName[ range ] + 'y'; default: return groupName[ range ] + "\u00f3w"; } // end switch } } // end switch } // end getGroupName /** * test harness * * @param args not used */ public static void main( String[] args ) { Test.test( new Polish(), new DecimalDots() ); } // end main /** * convert long integer into Polish words. e.g. -12345 -> "minus twelve thousand forty-five" Handles negative and * positive integers on range -Long.MAX_VALUE .. Long.MAX_VALUE; It cannot handle Long.MIN_VALUE; * * @param num number to convert to words * * @return words */ @SuppressWarnings( { "WeakerAccess" } ) public String toWords( long num ) { if ( num == 0 ) { return ZERO; } boolean negative = ( num < 0 ); if ( negative ) { num = -num; } String s = ""; // Work least significant digit to most, right to left. // until high order part is all 0s. for ( int group = 0; num > 0; group++ ) { int remdr = ( int ) ( num % divisor[ group ] ); num = num / divisor[ group ]; if ( remdr == 0 ) { continue; } String t; if ( remdr == 1 ) { switch ( group ) { case 0: /* doing units */ t = lowName[ 1 ]; break; default: /* higher numbers, suppress one */ t = ""; break; } // end switch } // end if else if ( remdr < 10 ) { switch ( group ) { case 1: /* doing hundreds, count is part of groupname */ t = ""; break; default: t = lowName[ remdr ]; break; } // end switch } // end if else if ( remdr < 20 ) { t = lowName[ remdr ]; } // end if else if ( remdr < 100 ) { int units = remdr % 10; int tens = remdr / 10; t = tys[ tens ]; if ( units != 0 ) { t += " " + lowName[ units ]; } } // end if else { t = toWords( remdr ); } boolean leftPad = ( t.length() != 0 ); s = t + ( leftPad ? " " : "" ) + getGroupName( remdr, group ) + " " + s; } // end for s = s.trim(); if ( negative ) { s = MINUS + " " + s;/* guess word for negative */ } return s; } // end inWords } // end Polish