/* * [SwissFrench.java] * * Summary: Display a number is Swiss French (Vaudaios) words. * * Copyright: (c) 2006-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-17 */ package com.mindprod.inwords; /** * Display a number is Swiss French (Vaudaios) words. *

* e.g. * -12345 -> "moins douze mille trois cent quarante-cinq". *

* Special thanks go to Jonathan Revusky <jrevusky@bigfoot.com> * for helping prod * my recall of high school French, and makes correction after * correction. * Then later to jpmartin@yahoo.com who found several remaining errors. * * @author Roedy Green, Canadian Mind Products * @version 1.0 1999-01-17 * @since 1999-01-17 */ public final class SwissFrench implements ToWords { private static final int FIRST_COPYRIGHT_YEAR = 1999; private static final String AND = "et"; /** * 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 = "moins"; private static final String PLURAL = "s"; private static final String ZERO = "z\u00e9ro"; private static final String[] groupName = { /* * We only need up to a quintillion, since a long is about 9 * 10 ^ 18 */ /* * American: unit, hundred, thousand, million, billion, trillion, * quintillion */ "" /* 1 */, "cent" /* 100 */, "mille" /* 1,000 */, "million" /* 1,000,000 */, "milliard" /* 1,000,000,000 */, "billion" /* 1,000,000,000,000 */, "trillion" /* 1,000,000,000,000,000 */, }; private static final String[] lowName = { /* zero is shown as "" since it is never used in combined forms */ /* 0 .. 19 */ "" /* 0 */, "un" /* 1 */, "deux" /* 2 */, "trois" /* 3 */, "quatre" /* 4 */, "cinq" /* 5 */, "six" /* 6 */, "sept" /* 7 */, "huit" /* 8 */, "neuf" /* 9 */, "dix" /* 10 */, "onze" /* 11 */, "douze" /* 12 */, "treize" /* 13 */, "quatorze" /* 14 */, "quinze" /* 15 */, "seize" /* 16 */, "dix-sept" /* 17 */, "dix-huit" /* 18 */, "dix-neuf" /* 19 */, "vingt" /* 20 */ }; private static final String[] tys = { /* 0, 10, 20, 30 ... 90 */ "", /* 0 */ "", /* 10 */ "vingt" /* 20 */, "trente" /* 30 */, "quarante" /* 40 */, "cinquante" /* 50 */, "soixante" /* 60 */, "septante" /* 70 */, "huitante" /* 80 */, "nonante" /* 90 */ }; 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, * quintillion */ 100, 10, 1000, 1000, 1000, 1000, 1000000 }; /** * test harness * * @param args not used */ public static void main( String[] args ) { Test.test( new SwissFrench(), new DecimalDots() ); } // end main /** * convert long integer into French words. e.g. -12345 -> "moins douze mille trois cent quarante-cinq" 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 ) { // suppress one before any group, not "un cent", but "cent". if ( group == 0 ) { t = lowName[ 1 ]; } else { t = ""; } } else if ( remdr < 20 ) { t = lowName[ remdr ]; } else if ( remdr < 100 ) { int units = remdr % 10; int tens = remdr / 10; t = tys[ tens ]; switch ( units ) { case 0: /* e.g. vingt */ break; case 1: if ( tens == 0 ) { /* trois cents un */ t += " " + lowName[ 1 ]; } else { /* e.g. vingt et un */ t += " " + AND + " " + lowName[ 1 ]; } break; default: /* e.g. vingt-trois */ t += "-" + lowName[ units ]; break; } // end switch } else { t = toWords( remdr ); } boolean leftPad = ( t.length() != 0 ); // sometimes add s to groupname to make it plural. boolean plural; switch ( group ) { case 1:// cent is only pluralised for even 100s, i.e. // nothing // to the right. plural = remdr > 1 && s.trim().equals( "" ); break; case 0:// units has no word, so does not need plural case 2:// mille not pluralized plural = false; break; default:// rest, plural if more than one group plural = remdr > 1; break; } s = t + ( leftPad ? " " : "" ) + groupName[ group ] + ( plural ? PLURAL : "" ) + " " + s; } // end for s = s.trim(); if ( negative ) { s = MINUS + " " + s; } return s; } // end inWords } // end SwissFrench