/* * [Esperanto.java] * * Summary: Display a number in Esperanto 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-12 * 1.1 1999-01-13 add milionoj etc. * 1.2 1999-01-16 minor tidying to hightlight asymmetry. * 1.3 1999-01-21 make all language specific String literals into named constants. */ package com.mindprod.inwords; /** * Display a number in Esperanto words. *

* e.g. * -12345 -> "minus dek du mil tricent kvardek kvin". *

* Special thanks go to Erik Max Francis <max@alcyone.com> * who provided all the information about Esperanto counting * used to write this program. * Manuel M Campagna <ah514@FreeNet.Carleton.CA> helped iron * out the bugs. *

* Esperanto counting is pretty weird. It is not nearly * as regular as other parts of the language. *

* Why is this code written in an unusual way? see inwords.use * * * @author Roedy Green, Canadian Mind Products * @version 1.3 1999-01-21 make all language specific String literals into named constants. * @since 1999-01-12 */ public final class Esperanto 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 PLURAL = "j"; private static final String ZERO = "nul"; private static final String[] digitName = { /* names of digits 0..9 */ /* zero is shown as "" since is "nul" in not used in combinations */ /* * nine - nau should be shown with breve (u shaped) accent above the u * \u016d but only IE/NT supports Unicode, so we show it with a * circumflex \u00fb. */ "", "unu", "du", "tri", "kvar", "kvin", "ses", "sep", "ok", "na\u00fb" /* na� naû */ }; private static final String[] groupName = { /* lack of lead space for dek (ten) and cent (100) is deliberate. */ /* We only need up to a triliono, since a long is about 9 * 10 ^ 18 */ /* After triliono comes triliardo, kvariliono, kvariliardo ... */ /* Note a US trillion = 10 ^ 12 = duiliono */ /* * American: unit, ten, hundred, thousand, million, billion, trillion, * quadrillion, quintillion */ "", "dek", "cent", "mil", "miliono", "miliardo", "duiliono", "duiliardo", "triliono" }; private static final int[] divisor = { /* * how many of this group is needed to form one of the succeeding group. */ /* * American: unit, ten, hundred, thousand, million, billion, trillion, * quadrillion, quintillion */ 10, 10, 10, 1000, 1000, 1000, 1000, 1000, 1000 }; /** * test harness * * @param args not used */ public static void main( String[] args ) { Test.test( new Esperanto() ); } // end main /** * convert long integer into Esperanto words e.g. -12345 -> "minus dek du mil tricent kvardek kvin". 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 ]; String t; switch ( remdr ) { case 0: continue; case 1: t = ( group == 0 ) ? digitName[ 1 ] : ""; break; case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: t = digitName[ remdr ]; break; default: t = toWords( remdr ); break; } // end switch // sometimes add j to groupname to make it plural. boolean plural = ( remdr > 1 ) && ( group > 3 );// only above 1000 // considered plural boolean before = ( group > 2 );// space before 1000 up s = t + ( before ? " " : "" ) + groupName[ group ] + ( plural ? PLURAL + " " : " " ) + s; } // end for s = s.trim(); if ( negative ) { s = MINUS + " " + s; } return s; } // end inWords } // end Esperanto