Convertir un Nombre en Lettre‎ [ FR ]

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
alid0381
Posts: 28
Joined: 09 May 2012 10:37

Convertir un Nombre en Lettre‎ [ FR ]

#1 Post by alid0381 » 15 Apr 2013 06:48

Hi everybody,

I want to create a small program in Ms-Dos

This can convert a number in letter :arrow:

I do not know where I begin :!: :?:

For Ex :
1 981 : mille neuf cent quatre-vingt-un

Aacini
Expert
Posts: 1927
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Convertir un Nombre en Lettre‎ [ FR ]

#2 Post by Aacini » 15 Apr 2013 15:06

These types of conversions are linked to the base language, so there is no way to write a general solution. The Batch file below achieve such conversion, but in Spanish language. You may use it as a guide and adjust it for your particular language.

EDIT: I slighlty modified the original code so now it is more precise and a little bit smaller.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Convert a number to equivalent words in Spanish
rem Antonio Perez Ayala

rem Define words for numbers 1 to 20
set i=1
for %%a in (uno  dos  tres  cuatro  cinco       seis      siete      ocho      nueve diez
            once doce trece catorce quince dieciseis diecisiete dieciocho diecinueve veinte) do (
   set word[!i!]=%%a
   set /A i+=1
)

rem Define words for numbers 21 to 29
for /L %%a in (1,1,9) do (
   set word[2%%a]=veinti!word[%%a]!
)

rem Define words for numbers 30 to 100 step 10
set i=30
for %%a in (treinta cuarenta cincuenta sesenta setenta ochenta noventa cien) do (
   set word[!i!]=%%a
   set /A i+=10
)

rem Define words for numbers 200 to 900 step 100
set i=200
for %%a in (doscientos trescientos cuatrocientos quinientos seiscientos setecientos ochocientos novecientos) do (
   set word[!i!]=%%a
   set /A i+=100
)

rem Adjust the number to 12 digits with leading zeros
set digits12=000000000000%1
set digits12=%digits12:~-12%

rem Convert the 12 digits
set words12=
call :Convert6Digits %digits12:~0,6%
if defined words6 (
   if "%words6:~-4%" equ "uno " (
      set words12=%words6:~0,-4%un millon
      if "%words6%" neq "uno " set words12=!words12!es
   ) else (
      set words12=%words6%millones
   )
   set "words12=!words12! "
)
call :Convert6Digits %digits12:~6%
set words12=%words12%%words6%
if not defined words12 set words12=cero

rem Capitalize the first word
set firstLetter=%words12:~0,1%
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set firstLetter=!firstLetter:%%a=%%a!
set result=%firstLetter%%words12:~1%
echo %result%

goto :EOF


:Convert6Digits number
set digits6=%1
set words6=
call :Convert3Digits %digits6:~0,3%
if defined words3 (
   if "%words3:~-4%" equ "uno " (
      set "words6=%words3:~0,-2% mil "
   ) else (
      set "words6=%words3%mil "
   )
)
call :Convert3Digits %digits6:~3%
set words6=%words6%%words3%
exit /B


:Convert3Digits num
set digits3=%1
set digit1=%digits3:~0,1%
set digits23=%digits3:~1%
if %digits23:~0,1% equ 0 set digits23=%digits23:~1%
set words3=
if %digit1% neq 0 (
   rem Convert hundreds
   set words3=!word[%digit1%00]!
   rem Convert "cien" to "ciento" if there are tens/units
   if %digit1% equ 1 if %digits23% neq 0 set words3=ciento
   set "words3=!words3! "
)
if %digits23% neq 0 (
   rem Convert tens and units
   if %digits23% geq 30 (
      rem Convert tens 90..30
      set words3=%words3%!word[%digits3:~1,1%0]!
      rem Convert the units, if any
      if %digits3:~2% neq 0 (
         set words3=!words3! y !word[%digits3:~2%]!
      )
   ) else (
      rem Convert tens/units 29..1
      set words3=%words3%!word[%digits23%]!
   )
   set "words3=!words3! "
)
exit /B

For example:

Code: Select all

C:\>NumToWords.bat 0
Cero

C:\>NumToWords.bat 1
Uno

C:\>set /A var=0x7FFFFFFF
2147483647

C:\>NumToWords.bat %var%
Dos mil ciento cuarenta y siete millones cuatrocientos ochenta y tres mil seiscientos cuarenta y siete


Antonio

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#3 Post by trebor68 » 16 Apr 2013 17:17

Numbers greater than one million have several names. I've created a batch file that shows this.

The number can be entered as a parameter but without a space, comma or dot. The number can consist of up to 36 digits.

The display will show the number in the first column as a mathematical expression.
The second column shows the number of how these are used in the U.S., Canada and modern Great Britain.
The third column shows the number as it is used in traditional Britain.
The last column shows the number as it is used in traditional Europe.

The small numbers of thousand were shown in batch file of Aacini. Thanks to Aacini.

Code: Select all

@echo off
setlocal enableextensions
::
:: number with max 36 digits without spaces, commas or points
if "%1" equ "" (set number=18446744073709551615) else set number=%~1
echo.
echo  number: %number%
echo.
call :countblocks %number% blocks
echo count blocks: %blocks% + 1
echo.
:: view number with spaces
echo.|set /p".=       "
for /l %%a in (%blocks%,-1,0) do (
  call :block %number% %%a blockn
  echo.|set /p".=!blockn! "
)
echo.
echo.
:: view number with letters
:: echo.|set /p".=    "
for /l %%a in (%blocks%,-1,0) do (
  call :block %number% %%a blockn
  call :letterblock %%a potenz englnum1 englnum2 europnum
  echo   !blockn!!potenz!  !blockn! !englnum1!  !blockn! !englnum2!  !blockn! !europnum!
)
echo.
goto :eof

:: countblocks num Ret-var
:countblocks
setlocal enableextensions
set anz=-1
:count1
set /a t2=-3-3*anz
set test=%~1
if %t2% neq 0 set test=!test:~0,%t2%!
if "%test%" neq "" (
  set test=!test:~-3!
  set /a anz+=1
  goto :count1
)
set result=%anz%
endlocal & set %2=%result%
goto :eof

:: block num block Ret-var
:block
setlocal enableextensions
set test=%~1
set /a t2=0-3*%2
if %2 neq 0 set test=!test:~0,%t2%!
if "%test%" neq "" (
  set test=!test:~-3!
  set test=   !test!
  set test=!test:~-3!
)
set result=%test%
endlocal & set %3=%result%
goto :eof

:: letterblock num Ret-var1 Ret-var2 Ret-var3 Ret-var4
:letterblock
setlocal enableextensions
set /a t1=3*%1
set "t1= * 10^^^^%t1%        "
set var1=%t1:~0,11%

if %1 equ 0 (set var2=" ") & (set var3=" ") & set var4=" "
if %1 equ 1 (set var2="thousand") & (set var3="thousand") & set var4="thousand"
if %1 equ 2 (set var2="million") & (set var3="million") & set var4="million"
if %1 equ 3 (set var2="billion") & (set var3="thousand million") & set var4="milliard"
if %1 equ 4 (set var2="trillion") & (set var3="billion") & set var4="billion"
if %1 equ 5 (set var2="quadrillion") & (set var3="thousand billion") & set var4="billiard"
if %1 equ 6 (set var2="quintillion") & (set var3="trillion") & set var4="trillion"
if %1 equ 7 (set var2="sextillion") & (set var3="thousand trillion") & set var4="trilliard"
if %1 equ 8 (set var2="septillion") & (set var3="quadrillion") & set var4="quadrillion"
if %1 equ 9 (set var2="octillion") & (set var3="thousand quadrillion") & set var4="quadrilliard"
if %1 equ 10 (set var2="nonillion") & (set var3="quintillion") & set var4="quintillion"
if %1 equ 11 (set var2="decillion") & (set var3="thousand quintillion") & set var4="quintilliard"

set "var2=%var2:"=%           "
set var2=%var2:~0,11%
set "var3=%var3:"=%                    "
set var3=%var3:~0,20%
set "var4=%var4:"=%            "
set var4=%var4:~0,12%

endlocal & (set %2=%var1%) & (set %3=%var2%) & (set %4=%var3%) & (set %5=%var4%)
goto :eof


Here a example with 36 digits.

Code: Select all

C:\Test2>test38b 123456789012345678901234567890123456

 number: 123456789012345678901234567890123456

count blocks: 11 + 1

       123 456 789 012 345 678 901 234 567 890 123 456

  123 * 10^33  123 decillion    123 thousand quintillion  123 quintilliard
  456 * 10^30  456 nonillion    456 quintillion           456 quintillion
  789 * 10^27  789 octillion    789 thousand quadrillion  789 quadrilliard
  012 * 10^24  012 septillion   012 quadrillion           012 quadrillion
  345 * 10^21  345 sextillion   345 thousand trillion     345 trilliard
  678 * 10^18  678 quintillion  678 trillion              678 trillion
  901 * 10^15  901 quadrillion  901 thousand billion      901 billiard
  234 * 10^12  234 trillion     234 billion               234 billion
  567 * 10^9   567 billion      567 thousand million      567 milliard
  890 * 10^6   890 million      890 million               890 million
  123 * 10^3   123 thousand     123 thousand              123 thousand
  456 * 10^0   456              456                       456

Aacini
Expert
Posts: 1927
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Convertir un Nombre en Lettre‎ [ FR ]

#4 Post by Aacini » 16 Apr 2013 20:14

I like it! :D

Code: Select all

@echo off
setlocal EnableDelayedExpansion

call :letterblock

:: number with max 36 digits without spaces, commas or points
if "%1" equ "" (set number=18446744073709551615) else set number=%~1
echo/
echo  number: %number%
echo/
set blocks=0
:countBlocks
   set block[%blocks%]=%number:~-3%
   set /A blocks+=1
   set number=%number:~0,-3%
if defined number goto countBlocks
set /A blocks-=1
set var=  !block[%blocks%]!
set block[%blocks%]=%var:~-3%
echo count blocks: %blocks% + 1
echo/
:: view number with spaces
set "line=       "
for /l %%n in (%blocks%,-1,0) do (
   set "line=!line!!block[%%n]! "
)
echo %line%
echo/
:: view number with letters
for /l %%n in (%blocks%,-1,0) do (
   echo   !block[%%n]!!potenz[%%n]!  !block[%%n]! !englnum1[%%n]!  !block[%%n]! !englnum2[%%n]!  !block[%%n]! !europnum[%%n]!
)
echo/
goto :eof

:letterblock
for /L %%i in (0,1,11) do (
   set /a t1=3*%%i
   set "t1= * 10^^!t1! "
   set potenz[%%i]=!t1:~0,8!
)
set i=0
for %%a in (" " thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion) do (
   set "var2=%%~a          "
   set englnum1[!i!]=!var2:~0,11!
   set /A i+=1
)
set i=0
for %%a in (" " thousand million "thousand million" billion "thousand billion" trillion "thousand trillion" quadrillion "thousand quadrillion" quintillion "thousand quintillion") do (
   set "var3=%%~a                    "
   set englnum2[!i!]=!var3:~0,20!
   set /A i+=1
)
set i=0
for %%a in (" " thousand million milliard billion billiard trillion trilliard quadrillion quadrilliard quintillion quintilliard) do (
   set "var4=%%~a           "
   set europnum[!i!]=!var4:~0,12!
   set /A i+=1
)
goto :eof

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Convertir un Nombre en Lettre‎ [ FR ]

#5 Post by foxidrive » 16 Apr 2013 20:44

trebor68 wrote:Numbers greater than one million have several names. I've created a batch file that shows this.

The number can be entered as a parameter but without a space, comma or dot. The number can consist of up to 36 digits.



I tried it with several digits, and 4 digits, and it hangs with the CPU usage rising.

Code: Select all

d:\abc>a 12345678

 number: 12345678

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#6 Post by trebor68 » 17 Apr 2013 02:49

This error is coming when "CMD /v:off".

I have found the error in my batch file.

Please change any row with "setlocal enableextensions" to this entry "setlocal enableextensions EnableDelayedExpansion".

Thanks to Aacini and Foxdrive for your postings.
Last edited by trebor68 on 17 Apr 2013 02:59, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Convertir un Nombre en Lettre‎ [ FR ]

#7 Post by foxidrive » 17 Apr 2013 02:56

That fixed it. Thanks - nice job.

Aacini
Expert
Posts: 1927
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Convertir un Nombre en Lettre‎ [ FR ]

#8 Post by Aacini » 17 Apr 2013 03:08

I have combined trebor68's code with the mine and produced a program that convert a number up to 36 digits to words in English language (US and Canada version).

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Convert a number to equivalent words in English
rem Antonio Perez Ayala

rem Define words for numbers 1 to 20
set i=1
for %%a in (one    two    three    four     five    six     seven     eight    nine     ten
            eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty) do (
   set word[!i!]=%%a
   set /A i+=1
)

rem Define words for numbers 30 to 100 step 10
set i=30
for %%a in (thirty forty fifty sixty seventy eighty ninety hundred) do (
   set word[!i!]=%%a
   set /A i+=10
)

rem Define words for blocks of 3 digits by position (in US and Canada)
set i=1
for %%a in (thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion) do (
   set "block3[!i!]=%%a "
   set /A i+=1
)

if "%~1" neq "" (set number=%~1) else set number=0

rem Divide the number in blocks of 3 digits each
set blocks=-1
:nextBlock
   set /A blocks+=1
   set block[%blocks%]=%number:~-3%
   set number=%number:~0,-3%
if defined number goto nextBlock

rem Show the number as comma-separated 3-digits blocks
set result=
for /L %%i in (%blocks%,-1,0) do (
   set result=!result!!block[%%i]!,
)
echo %result:~0,-1%

rem Convert the number to words
set result=00!block[%blocks%]!
set block[%blocks%]=%result:~-3%
set result=
for /L %%i in (%blocks%,-1,0) do (
   call :ConvertBlock %%i
   if defined words3 set "result=!result!!words3!!block3[%%i]!"
)
if not defined result set "result=zero "

rem Capitalize the first word
set firstLetter=%result:~0,1%
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set firstLetter=!firstLetter:%%a=%%a!
set result=%firstLetter%%result:~1,-1%
echo %result%

goto :EOF


:ConvertBlock index
set digits3=!block[%1]!
set digit1=%digits3:~0,1%
if %digits3:~1,1% neq 0 (set digits23=%digits3:~1%) else set digits23=%digits3:~2%
set words3=
if %digit1% neq 0 (
   rem Convert hundreds
   if %digit1% equ 1 (set words3=a hundred) else set words3=!word[%digit1%]! hundred
   rem Add "and" if there are tens/units
   if %digits23% neq 0 set words3=!words3! and
   set "words3=!words3! "
)
if %digits23% neq 0 (
   rem Convert tens and units
   if %digits23% geq 20 (
      rem Convert tens 90..20
      set words3=%words3%!word[%digits3:~1,1%0]!
      rem Convert the units, if any
      if %digits3:~2% neq 0 set words3=!words3!-!word[%digits3:~2%]!
   ) else (
      rem Convert tens/units 19..1
      set words3=%words3%!word[%digits23%]!
   )
   set "words3=!words3! "
)
exit /B
For example:

Code: Select all

C:\Users\Antonio\Documents
>NumToWords2 0
0
Zero

C:\Users\Antonio\Documents
>NumToWords2 1
1
One

C:\Users\Antonio\Documents
>NumToWords2 %max32bits%
2,147,483,647
Two billion a hundred and forty-seven million four hundred and eighty-three thou
sand six hundred and forty-seven

C:\Users\Antonio\Documents
>NumToWords2 123456789012345678901234567890123456
123,456,789,012,345,678,901,234,567,890,123,456
A hundred and twenty-three decillion four hundred and fifty-six nonillion seven
hundred and eighty-nine octillion twelve septillion three hundred and forty-five
 sextillion six hundred and seventy-eight quintillion nine hundred and one quadr
illion two hundred and thirty-four trillion five hundred and sixty-seven billion
 eight hundred and ninety million a hundred and twenty-three thousand four hundr
ed and fifty-six

However, it seems that my method is not precise in certain cases when it change "one hundred" by "a hundred", but my English-Spanish dictionary have not examples of very large numbers! :mrgreen: Perhaps you may help me in this point...

Antonio

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#9 Post by trebor68 » 17 Apr 2013 03:44

In the code from Aacini is coming a error when "CMD /e:off".

Please also change the row with "setlocal EnableDelayedExpansion" to this entry "setlocal EnableExtensions EnableDelayedExpansion".


Note for viewing in German language.
Numbers up to 999 999 are written as one word.
Numbers from 1 000 000 to be written with the words "Million", "Milliarde", "Billion" etc..

Here the examples (colors only for the overview):
312 723 = dreihundertzwölftausendsiebenhundertdreiundzwanzig
1 234 678 901 = eine Milliarde zweihundertvierundreißig Millionen sechshundertachtundsiebzigtausendneunhunderteins

Aacini
Expert
Posts: 1927
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Convertir un Nombre en Lettre‎ [ FR ]

#10 Post by Aacini » 18 Apr 2013 11:13

trebor68 wrote:Note for viewing in German language.
Numbers up to 999 999 are written as one word.
Numbers from 1 000 000 to be written with the words "Million", "Milliarde", "Billion" etc..

How are those 999 999 names of numbers formed?

In Spanish language, names for numbers 1..20 are unique. Although numbers 21..29 are also unique, they are easily formed with "veinti" prefix + unit. With the names for tens 30..90 and hundreds 100..900 you may form any number although there are a couple special rules.

In English language it is slightly simpler because just numbers 1..20 are unique; numbers from 21 to 99 are formed by combining ten+"-"+unit although there are also a couple special rules: "one hundred" is changed by "a hundred" and word "and" is included after "hundred" (or "thousand" or "million", etc...) if there are ten+unit part (I am still trying to completely understand this rule).

It seems to me that in German language is easier because we must not insert the space between hundred, ten and unit parts. Could you post the names of numbers in German language and the specials rules, if any? I would like to have a number-to-words conversion program with as many languages as possible.

Could someone post the same data for another language? French perhaps?

Antonio

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Convertir un Nombre en Lettre‎ [ FR ]

#11 Post by Endoro » 18 Apr 2013 13:34


foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Convertir un Nombre en Lettre‎ [ FR ]

#12 Post by foxidrive » 18 Apr 2013 15:12

Aacini wrote:In English language it is slightly simpler because just numbers 1..20 are unique; numbers from 21 to 99 are formed by combining ten+"-"+unit although there are also a couple special rules: "one hundred" is changed by "a hundred" and word "and" is included after "hundred" (or "thousand" or "million", etc...) if there are ten+unit part (I am still trying to completely understand this rule).


In English when speaking of physics and maths you would say "One hundred and 25 thousand" and not "A hundred and 25 thousand"

The syntax "A hundred and thirty one" would be used for numbers below two hundred, IMO, and usually only in a casual fashion. "One hundred and thirty one" is quite acceptable in English.

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#13 Post by trebor68 » 19 Apr 2013 06:46

Here the rules for numbers in German language:

Code: Select all

German language

I use "-" here only for a better overview. The word is writing without this sign.
When I write block number see this:
100,000,000,000,000
 4   3   2   1   0  block

number 0 = null

numbers 1 to 20
ein zwei  drei     vier     fünf     sechs    sieben   acht     neun     zehn
elf zwölf dreizehn vierzehn fünfzehn sechzehn siebzehn achtzehn neunzehn zwanzig

numbers 30 to 90 step 10
dreißig vierzig fünfzig sechzig siebzig achtzig neunzig

numbers 21 to 99 without the numbers ending with 0
First the number 1 to 9 by following "und" and then the number 20 to 90.

example number 21: ein-und-zwanzig
To understand in English words: one-and-twenty


numbers 100 to 999
x00 = number 1 to 9 following by "hundert"
xyy = number 1 to 9 following "hundert" and following by the other number

example number 153:
ein-hundert-drei-und-fünfzig


numbers 1,000 to 999,999
Between the two blocks write "tausend".

example number 14,742
vierzehn-tausend-sieben-hundert-zwei-und-vierzig


numbers equal or greater 1,000,000
Any block two and greater have a special word that beginn with a capital letter.

block 2 to 13
Million Milliarde Billion Billiarde Trillion Trilliarde Quadrillion Quadrilliarde Quintillion Quintilliarde Sextillion Sextilliarde

1,xxx,xxx = eine Million
2,xxx,xxx = zwei Millionen
2,500,000 = zwei Millionen fünf-hundert-tausend

Also the other words:
..llion    when 1
..llionen  when 2 up to 999; suffix -en marks the plural
..lliarde  when 1
..lliarden when 2 up to 999; suffix -n marks the plural

###

Hint to the number 1 in value.
1 = "ein", "eine" or "eins"

block 0
  1 = eins
 11 = elf
 x1 = ein-und-xxx
100 = ein-hundert
101 = ein-hundert-eins
111 = ein-hundert-elf
1x1 = ein-hundert-ein-und-xxx

block 1 differences to block 0
  1 = ein-tausend
 x1 = ein-und-xxx-tausend
101 = ein-hundert-ein-tausend

block 2 (and greater) differences to block 0
  1 = eine Million
 x1 = ein-und-xxx Millionen
101 = ein-hundert-ein Millionen

In English you used comma to seperated the great numbers. 1,234,567
In German we used space or point to seperated the great numbers. 1 234 567 or 1.234.567

For the French language found this link: http://www.graner.net/nicolas/nombres/nom.php
There you can input a number to see the result in French.

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#14 Post by trebor68 » 21 Apr 2013 15:19

Here the rules for numbers in France language. Checked with the link last posting and wikipedia.

Code: Select all

===  France and Canada  ===

:: CP850 "é" (ALT+130) = CP1252 "‚" (ALT+0130)
0 = zéro

numbers 1 to 20
  1    2     3        4      5      6       7       8         9     10
 un  deux  trois   quatre  cinq    six    sept    huit      neuf    dix
onze douze treize quatorze quinze seize dix-sept dix-huit dix-neuf vingt


20 to 100 step 10
vingt trente quarante cinquante soixante --- quatre-vingt --- cent

60 to 79 will use as "60 + (1 to 19)"
80 to 99 will use as "80 + (1 to 19)"

Any numbers xy (with y not 0 or 1) are write as "xxx-yyy"
also number 70 = soixante-dix
also number 90 = quatre-vingt-dix
also number 91 = quatre-vingt-onze

Any numbers x1 (with x are 2, 3, 4, 5, 6, 8) are write as "xxx et un"
only number 71 = "soixante et onze"

Hint to number 80.
If 80 at the end of the double block (six digits) then write -s at the end of the word.
xxx,x80 = quatre-vingts
x80,xxx = quatre-vingt mille

x80,xxx,xxx = quatre-vingts millions
x80,xxx,xxx,xxx = "quatre-vingts milliards" but "quatre-vingt mille millions"


numbers 100 to 999
xy is a number of 1 up to 99
between the hundred and other number is one space

1xy = cent <space> xy
2xy = deux cents <space> xy
up to
9xy = neuf cents <space> xy


numbers 1000 to 999999
1000 = mille

  1,yyy = mille yyy
xxx,yyy = xxx mille yyy



numbers 1,000,000 and greater
yyy,zzz is a number 1 up to 999,999

  1,yyy,zzz =  un million  yyy mille zzz
xxx,yyy,zzz = xxx millions yyy mille zzz

  1,xxx,yyy,zzz =     mille     xxx millions yyy mille zzz
www,xxx,yyy,zzz = www mille     xxx millions yyy mille zzz
also
  1,xxx,yyy,zzz =  un milliard  xxx millions yyy mille zzz
www,xxx,yyy,zzz = www milliards xxx millions yyy mille zzz


France will use the long scale
1,000^1  = mille
1,000^2  = un million
1,000^3  = mille millions = un milliard
1,000^4  = un billion
1,000^5  = mille billions = un billiard


#####

===  Suisse  ===
70, 71, 72 ... = "septante", "septante et un", "septante-deux" ...
80, 81, 82 ... = "huitante", "huitante et un", "huitante-deux" ...
and also
80, 81, 82 ... = "quatre-vints", "quatre-vint-un", "quatre-vint-deux" ...
90, 91, 92 ... = "nonante", "nonante et un", "nonante-deux" ...

===  Belgium  ===
70, 71, 72 ... = "septante", "septante et un", "septante-deux" ...
80, 81, 82 ... = "quatre-vints", "quatre-vint-un", "quatre-vint-deux" ...
90, 91, 92 ... = "nonante", "nonante et un", "nonante-deux" ...


The following code will see the words for the very large numbers (million, billion, trillion, etc).

Code: Select all

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set scale=short
if "%1" equ "" (
  echo.
  echo    %0 [/country=GER^|US^|FR] [/scale=short^|long] xxx
  echo.
  echo       /country   select specifical settings of informations
  echo       /scale     short - use only million, billion, trillion, ...
  echo                  long  - use million, milliard, billion, billiard, ...
  echo       xxx        number of the block for the searching result
  echo                       block number 2 = million
  echo                       block number 3 = billion or milliard
  echo                       block number 4 = trillion or billion
  echo                  use min 2 up to max value
  echo                  if '/scale=short' use max 1 000 000
  echo                  if '/scale=long' use max 1 999 999
  echo.
  goto :eof
)
:again
if /i "%1" equ "/country" (set land=%2) & shift & shift
if /i "%1" equ "/scale" (set scale=%2) & shift & shift & goto :again
if "%1" neq "" (set completenumber=%1) & shift & if "%1" neq "" goto :again
::
:: possible in this time for variable land are: GER, US, FR
if not defined land set land=US
::
::
:: numbers 1 to 9 not combination prefix
set i=1
for %%a in (mi bi tri quadri quinti sexti septi octi noni) do (
  set blockSolo[!i!]=%%a
  set /a i+=1
)
:: numbers 1 to 9 with combination prefix
set i=1
for %%a in (un duo tre quattuor quinqua se septe octo nove) do (
  set blockComb1[!i!]=%%a
  set /a i+=1
)
:: numbers 10 to 90 step 10 with combination prefix
set i=1
for %%a in (deci viginti triginta quadraginta quinquaginta sexaginta septuaginta octoginta nonaginta) do (
  set blockComb2[!i!]=%%a
  set /a i+=1
)
:: numbers 100 to 900 step 100 with combination prefix
set i=1
for %%a in (centi ducenti trecenti quadringenti quingenti sescenti septingenti octingenti nongenti) do (
  set blockComb3[!i!]=%%a
  set /a i+=1
)


:: change names to the other language
if /i %land% equ GER (
  set blockSolo[8]=okti
  set blockComb1[8]=okto
  set blockComb2[1]=dezi
  set blockComb2[8]=oktoginta
  set blockComb3[1]=zenti
  set blockComb3[2]=duzenti
  set blockComb3[3]=trezenti
  set blockComb3[6]=seszenti
  set blockComb3[8]=oktingenti
)

:: CP850 "é" (ALT+130) = CP1252 "‚" (ALT+0130)
if /i %land% equ FR (
  set blockComb2[1]=d‚ci
)
::
::
:: change the value from short scale to long scale
set gesblock=%completenumber%
set /a tsdnum="gesblock & 1"
if /i %scale% equ long (set /a gesblock=gesblock / 2) else set /a gesblock-=1
if %gesblock% geq 1000 (set /a number=gesblock / 1000) & goto :firstround

:secondround
set /a number="gesblock %% 1000", gesblock=-gesblock
(set "res1=") & (set "res2=") & set "res3="

:firstround
::
:: number is coming as parameter (1 to 999)
::
set /a number=1000%number%, number="number %% 1000"
set /a num1="number %% 10", num2="number %% 100" /10, num3=number /100

set res1=!blockComb1[%num1%]!
set res2=!blockComb2[%num2%]!
set res3=!blockComb3[%num3%]!

if %number% lss 10 (set res1=!blockSolo[%number%]!) & goto :display

:: change the number 5 from "quinqua" to "quin"
:: GER only x15    #    US only 0x5    #    x is any digit at the position
if /i %land% equ GER if %num2%%num1% equ 15 set res1=quin
if /i %land% equ US  if %num3%%num2%%num1% equ 0%num2%5 set res1=quin

:: insert letters "n", "m", "s" and "x"
for %%a in (17 19 37 39 47 49 57 59 67 69 77 79
    107 109 207 209 307 309 407 409 507 509 607 609 707 709) do if %number% equ %%a set res1=%res1%n

for %%a in (27 29 87 89 807 809) do if %number% equ %%a set res1=%res1%m

for %%a in (23 26 33 36 43 46 53 56 83 103 803
    303 306 403 406 503 506) do if %number% equ %%a set res1=%res1%s

for %%a in (86 106 806) do if %number% equ %%a set res1=%res1%x

:: numbers less 100 change last letter from "a" to "i"
if %number% lss 100 if %num2% gtr 2 set res2=%res2:~0,-1%i

:display
:: any following variable RESULT and SUFFIX will make the big number name
set result=%result%%res1%%res2%%res3%
if %gesblock% geq 1000 (set result=%result%lli) & goto :secondround
if %number% equ 0 set result=%result%ni

if %tsdnum%%scale% equ 1long (
  set suffix=lliard
  if /i %land% equ GER set suffix=!suffix!e
) else set suffix=llion
set result=%result%%suffix%

if /i %land% equ GER (
rem Capitalize the first word
  set firstLetter=!result:~0,1!
  for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set firstLetter=!firstLetter:%%a=%%a!
  set result=!firstLetter!!result:~1!
)

if %completenumber% leq 1 (
  echo     Error: Use a higher number. Start without parameter.
) else if %gesblock% leq -1000000 (
  echo     Error: Use a less number. Start without parameter.
) else echo  %completenumber%  %result%


Here some results from the display:

Code: Select all

C:\Test2>for /l %a in (2,1,11) do @Test40Z /country=GER /scale=long %a
 2  Million
 3  Milliarde
 4  Billion
 5  Billiarde
 6  Trillion
 7  Trilliarde
 8  Quadrillion
 9  Quadrilliarde
 10  Quintillion
 11  Quintilliarde

C:\Test2>for /l %a in (2,1,11) do @Test40Z /country=us /scale=short %a
 2  million
 3  billion
 4  trillion
 5  quadrillion
 6  quintillion
 7  sextillion
 8  septillion
 9  octillion
 10  nonillion
 11  decillion

C:\Test2>Test40Z /country=fr /scale=long 31
 31  quinquadécilliard


The last result is understand as 10^(3*31) = 1000^31 = 10^93 = 10^(6*15+3) = 1,000,000^15 * 1,000.
The factorial of 67 = 36 quinquadécilliard (France, long scale) = 36 trigintillion (US, short scale) = 36 * 10^93.

trebor68
Posts: 146
Joined: 01 Jul 2011 08:47

Re: Convertir un Nombre en Lettre‎ [ FR ]

#15 Post by trebor68 » 23 Apr 2013 08:30

Here the code to convert numbers in words in French language.
Thanks to Aacini for the basic batch file.

Direct in the file are setting to the regional code. This is not change with parameter.
Why "regional code"? The French language is spoken and written in different countries, but there are some differences in the numbers of 70 to 99.

The regional code can setting with one of this:
SET "region=FR"
SET "region=FR_BE"
SET "region=FR_CH"


With the parameter "/FILE" will use the batch file characters that are correct in output to a file.
Without the parameter is this correct at the screen. This parameter is only important when the number is 0.

Code: Select all

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Convert a number to equivalent words in French language
rem Basic batch file from Antonio Perez Ayala
rem Changes from Robert Staatz

rem Use "/FILE" as parameter for correct spelling in a file
if /i "%1" equ "/file" ( (set screenfile=FILE) & shift) else if /i "%2" equ "/file" set screenfile=FILE

rem Defining the region to numbers from 70 to 99
rem region FR    - France and Canada:  70 = soixante-dix  #  80 = quatre-vingts  #  90 = quatre-vingt-dix
rem region FR_BE - Belgium          :  70 = septante      #  80 = quatre-vingts  #  90 = nonante
rem region FR_CH - Switzerland      :  70 = septante      #  80 = huitante       #  90 = nonante
set "region=FR"

rem Define words for numbers 1 to 20
set i=1
for %%a in (un   deux  trois  quatre   cinq   six   sept     huit     neuf     dix
            onze douze treize quatorze quinze seize dix-sept dix-huit dix-neuf vingt) do (
   set word[!i!]=%%a
   set /A i+=1
)

rem Define words for numbers 30 to 100 step 10
set i=30
for %%a in (trente quarante cinquante soixante soixante-dix quatre-vingt quatre-vingt-dix cent) do (
   set word[!i!]=%%a
   set /A i+=10
)
if /i %region% equ FR_BE (set word[70]=septante) & (set word[90]=nonante)
if /i %region% equ FR_CH (set word[70]=septante) & (set word[80]=huitante) & (set word[90]=nonante)

rem Define words for blocks of 3 digits by position (in France)
set i=1
for %%a in (mille million milliard billion billiard trillion trilliard quadrillion quadrilliard quintillion quintrilliard) do (
   set "block3[!i!]=%%a "
   set /A i+=1
)

rem Define word for number 0 for correct display on the screen or in the file
rem zéro  #  screen display CP850 "é" (ALT+130) = file CP1252 "‚" (ALT+0130)
rem zéro  #  screen display CP850 "ú" (ALT+233) = file CP1252 "é" (ALT+130)
if defined screenfile (set word[0]=zéro) else set word[0]=z‚ro

if "%~1" neq "" (set number=%~1) else set number=0

rem Divide the number in blocks of 3 digits each
set blocks=-1
:nextBlock
   set /A blocks+=1
   set block[%blocks%]=%number:~-3%
   set number=%number:~0,-3%
if defined number goto nextBlock

rem Show the number as space-separated 3-digits blocks
set result=
for /L %%i in (%blocks%,-1,0) do (
   set "result=!result!!block[%%i]! "
)
echo %result:~0,-1%

rem Convert the number to words
set result=00!block[%blocks%]!
set block[%blocks%]=%result:~-3%
set result=
for /L %%i in (%blocks%,-1,0) do (
   call :ConvertBlock %%i
   if defined words3 (
      set "result=!result!!words3!!block3[%%i]!"
      if %%i geq 2 if "!words3!" neq "!word[1]! " set "result=!result:~0,-1!s "
   )
)
if not defined result set "result=!word[0]! "

rem Capitalize the first word
set firstLetter=%result:~0,1%
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set firstLetter=!firstLetter:%%a=%%a!
set result=%firstLetter%%result:~1,-1%
echo %result%

goto :EOF


:ConvertBlock index
set digits3=!block[%1]!
set digit1=%digits3:~0,1%
if %digits3:~1,1% neq 0 (set digits23=%digits3:~1%) else set digits23=%digits3:~2%
set words3=
if %digit1% neq 0 (
   rem Convert hundreds
   set words3=!word[%digit1%]! !word[100]!
   if %digit1% neq 1 set words3=!words3!s
   rem if %digit1% equ 1 (set words3=un cent) else set words3=!word[%digit1%]! cents
   set "words3=!words3! "
)
if %digits23% neq 0 (
   rem Convert tens and units
   if %digits23% geq 20 (
      rem Convert tens 90..20
      set words2=!word[%digits3:~1,1%0]!
      rem Convert the units, if any
      if %digits3:~2% neq 0 set words1=-!word[%digits3:~2%]!

      rem Only when the unit is 1 will change
      if %digits3:~2% equ 1 set words1= et un
      if %digits23%%region% equ 71FR    set words1= et onze
      if %digits23%%region% equ 91FR    set words1=-onze
      if %digits23%%region% equ 81FR    set words1=-un
      if %digits23%%region% equ 81FR_BE set words1=-un

      rem Only the 80 need the suffix "-s", but not when "mille" follows
      if %digits23%%region% equ 80FR    if not %1 equ 1 set words2=!words2!s
      if %digits23%%region% equ 80FR_BE if not %1 equ 1 set words2=!words2!s

      rem Numbers 70+x are understand as 60+(10+x) and also numbers 90+x as 80+(10+x)
      set "hnum="
      if %digits3:~1,1%%region% equ 7FR (
         set /a hnum=digits23 - 60
         set words2=!word[60]!
      )
      if %digits3:~1,1%%region% equ 9FR (
         set /a hnum=digits23 - 80
         set words2=!word[80]!
      )
      if !hnum!%region% equ 10FR set words1=-!word[10]!
      if !hnum!%region% equ 12FR set words1=-!word[12]!
      if !hnum!%region% equ 13FR set words1=-!word[13]!
      if !hnum!%region% equ 14FR set words1=-!word[14]!
      if !hnum!%region% equ 15FR set words1=-!word[15]!
      if !hnum!%region% equ 16FR set words1=-!word[16]!
      if !hnum!%region% equ 17FR set words1=-!word[17]!
      if !hnum!%region% equ 18FR set words1=-!word[18]!
      if !hnum!%region% equ 19FR set words1=-!word[19]!

      set words3=%words3%!words2!!words1!
   ) else (
      rem Convert tens/units 19..1
      set words3=%words3%!word[%digits23%]!
   )
   set "words3=!words3! "
)
exit /B

Post Reply