Advertisement
AZJIO

ConvertingNumbers.au3 (UDF)

Jun 9th, 2014
844
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 15.93 KB | None | 0 0
  1. #include-once
  2. #include <BigNum.au3> ; http://www.autoitscript.com/forum/topic/83529-bignum-udf/
  3.  
  4. ; ============================================================================================
  5. ; Function Name ...: _NumToDec
  6. ; Description ........: Converts a number into a decimal
  7. ; Syntax.......: _NumToDec($num, $sSymbol)
  8. ; Parameters:
  9. ;       $num - number
  10. ;       $sSymbol - A set of symbols defining the sequence
  11. ;       $casesense - (0,1,2) corresponds to flag StringInStr
  12. ; Return values: Success - Returns a decimal number, @extended - the number of characters in the discharge
  13. ;                   Failure - Returns $num, and sets @error:
  14. ;                  |1 - $sSymbol contains less than 2 characters
  15. ;                  |2 - The symbol is not found in the character set
  16. ; Author(s) ..........: AZJIO
  17. ; Remarks ..........: For the 16 - Dec
  18. ; ============================================================================================
  19. ; Имя функции ...: _NumToDec
  20. ; Описание ........: Конвертирует указанное число в десятичное
  21. ; Синтаксис.......: _NumToDec($num, $sSymbol[, $casesense = 0])
  22. ; Параметры:
  23. ;       $num - число
  24. ;       $sSymbol - Набор символов определяющих последовательность для каждого разряда
  25. ;       $casesense - Регистро-зависимость (0,1,2), соответствует флагам StringInStr
  26. ; Возвращаемое значение: Успешно - Возвращает десятичное число, @extended определяет предыдущее количество символов в разряде
  27. ;                   Неудачно - Возвращает число переданное в параметре $num и устанавливает @error:
  28. ;                  |1 - $sSymbol содержит менее 2 символов
  29. ;                  |2 - Символ числа не найден в наборе символов
  30. ; Автор ..........: AZJIO
  31. ; Примечания ..: Не используйте функцию для конвертирования из 16 - ричных чисел, для этого есть Dec
  32. ; ============================================================================================
  33. Func _NumToDec($num, $sSymbol, $casesense = 0)
  34.     Local $i, $iPos, $Len, $n, $Out
  35.     $Len = StringLen($sSymbol)
  36.     If $Len < 2 Then Return SetError(1, 0, $num)
  37.    
  38.     $n = StringSplit($num, '')
  39.     For $i = 1 To $n[0]
  40.         $iPos = StringInStr($sSymbol, $n[$i], $casesense)
  41.         If Not $iPos Then Return SetError(2, 0, $num)
  42.         $Out = _BigNum_Add(_BigNum_Mul($iPos - 1, _BigNum_Pow($Len, $n[0] - $i)), $Out)
  43.     Next
  44.     Return SetError(0, $Len, $Out)
  45. EndFunc
  46.  
  47. ; ============================================================================================
  48. ; Function Name ...: _DecToNum
  49. ; Description ........: Converts a number from the decimal system to the specified
  50. ; Syntax.......: _DecToNum ( $iDec, $Symbol )
  51. ; Parameters:
  52. ;       $iDec - decimal number
  53. ;       $Symbol - A set of symbols defining the sequence
  54. ; Return values: Success - Returns the new number, @extended - the number of characters in the discharge
  55. ;                   Failure - Returns $iDec, @error = 1
  56. ; Author(s) ..........: AZJIO
  57. ; Remarks ..........: For the 16, 8 - Hex, StringFormat
  58. ; ============================================================================================
  59. ; Имя функции ...: _DecToNum
  60. ; Описание ........: Конвертирует десятичное число в указанное
  61. ; Синтаксис.......: _DecToNum ( $iDec, $Symbol )
  62. ; Параметры:
  63. ;       $iDec - десятичное число
  64. ;       $Symbol - Набор символов определяющих последовательность в разряде
  65. ; Возвращаемое значение: Успешно - Возвращает число в новой разрядности, @extended определяет количество символов в разряде
  66. ;                   Неудачно - Возвращает число переданное в параметре $iDec устанавливает @error равным 1
  67. ; Автор ..........: AZJIO
  68. ; Примечания ..: Не используйте функцию для конвертирования в 16, 8 - ричные числа, для этого есть Hex, StringFormat
  69. ; ============================================================================================
  70. Func _DecToNum($iDec, $Symbol)
  71.     Local $Out, $ost
  72.     $Symbol = StringSplit($Symbol, '')
  73.     If @error Or $Symbol[0] < 2 Then Return SetError(1, 0, $iDec)
  74.     Do
  75.         $ost = _BigNum_Mod($iDec, $Symbol[0])
  76.         $iDec = _BigNum_Div(_BigNum_Sub($iDec, $ost), $Symbol[0])
  77.         $Out = $Symbol[$ost + 1] & $Out
  78.     Until Not Number($iDec)
  79.     Return SetError(0, $Symbol[0], $Out)
  80. EndFunc
  81.  
  82. ; ============================================================================================
  83. ; Function Name ...: _DecToRoman
  84. ; Description ........: Convert decimal to Roman
  85. ; Syntax.......: _DecToRoman ( $iDec )
  86. ; Parameters:
  87. ;       $iDec - decimal number from 0 to 3999 (Adding thousands adds character "M")
  88. ; Return values: Success - Returns the string
  89. ;                   Failure - Returns -1 (Number outside the specified range), @error - 1, 2
  90. ; Author(s) ..........: AZJIO, заимствовано здесь http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
  91. ; Remarks ..........: If 0, the empty string
  92. ; ============================================================================================
  93. ; Имя функции ...: _DecToRoman
  94. ; Описание ........: Преобразует десятичное число в римское
  95. ; Синтаксис.......: _DecToRoman ( $iDec )
  96. ; Параметры:
  97. ;       $iDec - десятичное число от 0 до 3999 (Добавление тысяч добавляет символ "M")
  98. ; Возвращаемое значение: Успешно - Возвращает строку
  99. ;                   Неудачно - Возвращает -1 (число вне указанного диапазона) и устанавливает @error
  100. ; Автор ..........: AZJIO, Credits http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
  101. ; Примечания ..: Если 0, то пустая строка
  102. ; ============================================================================================
  103. Func _DecToRoman($iDec)
  104.     $iDec = Int($iDec) ; берём целую часть числа
  105.     If $iDec < 1 Then
  106.         If $iDec < 0 Then Return SetError(1, 0, -1)
  107.         Return SetError(0, 0, '')
  108.     EndIf
  109.     If $iDec > 3999 Then Return SetError(2, 0, -1) ; если огромное число
  110.     Local $r[13] = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
  111.     Local $n[13] = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
  112.     Local $sRim = ''
  113.    
  114.     For $i = 0 To 12
  115.         While $iDec >= $n[$i]
  116.             $iDec -= $n[$i]
  117.             $sRim &= $r[$i]
  118.         WEnd
  119.     Next
  120.     Return $sRim
  121. EndFunc   ;==>_DecToRoman
  122.  
  123. ; ============================================================================================
  124. ; Function Name ...: _RomanToDec
  125. ; Description ........: Converts Roman numbers to decimal
  126. ; Syntax.......: _RomanToDec ( $sRoman )
  127. ; Parameters:
  128. ;       $sRoman - Roman number
  129. ; Return values: Success - Returns decimal number
  130. ;                   Failure - Returns -1, @error = -1, if the number doesn't correspond to a format
  131. ; Author(s) ..........: AZJIO, http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
  132. ; Remarks ..........: Verify that number, i.e. not only the use but also the order of the characters. Only the canonical written, i.e. 99 is written as XCIX, not IC. If characters in lower case then @extended = 1
  133. ; ============================================================================================
  134. ; Имя функции ...: _RomanToDec
  135. ; Описание ........: Преобразует римские числа в десятичные
  136. ; Синтаксис.......: _RomanToDec ( $sRoman )
  137. ; Параметры:
  138. ;       $sRoman - римское число
  139. ; Возвращаемое значение: Успешно - Возвращает десятичное число
  140. ;                   Неудачно - Возвращает -1, @error = -1, если число не соответствует формату
  141. ; Автор ..........: AZJIO, http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
  142. ; Примечания ..: Прверяется правильность числа, т.е. не только использование символов но и порядок. Только каноническое написание, то есть 99 пишется как XCIX, а не IC. Если символы в нижнем регистре то @extended = 1
  143. ; ============================================================================================
  144. Func _RomanToDec($sRoman)
  145.     Local $extended = 0
  146.     If Not StringIsUpper($sRoman) Then $extended = 1
  147.     If StringRegExp($sRoman, '(?i)([VLD])\1') Or StringRegExp($sRoman, '(?i)([IVXLCDM])\1\1\1') Then Return SetError(-1, $extended, -1)
  148.     Local $c[7] = ['C', 'C', 'X', 'X', 'I', 'I', ''], _
  149.     $d[7] = [100, 100, 10, 10, 1, 1, 0], _
  150.     $r[7] = ['M', 'D', 'C', 'L', 'X', 'V', 'I'], _
  151.     $n[7] = [1000, 500, 100, 50, 10, 5, 1], _
  152.     $iDec = 0
  153.    
  154.     For $i = 0 To 6
  155.         $aTmp = StringRegExp($sRoman, '^(' & $r[$i] & '+' & $c[$i] & $r[$i] & '|' & $r[$i] & '+|' & $c[$i] & $r[$i] & ')(.*?)$', 3)
  156.         If Not @error Then
  157.             $iDec += StringLen($aTmp[0]) * $n[$i]
  158.             If StringInStr($aTmp[0], $c[$i]) Then $iDec -= $d[$i] + $n[$i]
  159.             $sRoman = $aTmp[1]
  160.             If Not $sRoman Then ExitLoop
  161.         EndIf
  162.     Next
  163.     If $sRoman Then Return SetError(-1, $extended, -1)
  164.     Return $iDec
  165. EndFunc   ;==>_RomanToDec
  166.  
  167. ; ============================================================================================
  168. ; Function Name ...: _NumberNumToName
  169. ; AutoIt Version ....: 3.2.12.1+
  170. ; Description ........: Converts a number to text consisting of words
  171. ; Syntax................: _NumberNumToName($iNum, $iRusLng = 0)
  172. ; Parameters:
  173. ;       $iNumber - любое целое число от 0 до 9223372036854775806
  174. ;       $iRusLng - (0, 1) language settings
  175. ;                  |0 - in English (Default)
  176. ;                  |1 - in Russian
  177. ; Return values ....: Success - Returns a string
  178. ;                   Failure - empty string, @error = 1, if the string contains no numbers
  179. ; Author(s) ..........: AZJIO, G.Sandler (CreatoR) (transformation and modernization of the VBS-script found in Google)
  180. ; link ..................: http://forum.oszone.net/post-1900913.html#post1900913 discussion and adding CreatoR'om English language support
  181. ; ============================================================================================
  182. ; Имя функции ...: _NumberNumToName
  183. ; Описание ........: Преобразует число в запись прописью
  184. ; Синтаксис.......: _NumberNumToName($iNum, $iRusLng = 0)
  185. ; Параметры:
  186. ;       $iNumber - любое целое число от 0 до 9223372036854775806
  187. ;       $iRusLng - (0, 1) языковые установки
  188. ;                  |0 - на английском языке (по умолчанию)
  189. ;                  |1 - на русском языке
  190. ; Возвращаемое значение: Успешно - число прописью
  191. ;                   Неудачно - пустая строка, @error = 1, если строка содержит не цифры
  192. ; Автор ..........: AZJIO, G.Sandler (CreatoR), преобразование и модернизация VBS-скрипта, найденного в Google
  193. ; Ссылка ..........: http://forum.oszone.net/post-1900913.html#post1900913 обсуждение и добавление CreatoR'ом поддержки английского языка
  194. ; ============================================================================================
  195. Func _NumberNumToName($iNum, $iRusLng = 0)
  196.     Local $aN, $aNum, $c, $i, $j, $n, $r, $sText
  197.  
  198.     $iNum = StringStripWS($iNum, 8) ; удаляем пробелы
  199.  
  200.     If $iNum = '0' Then
  201.         If $iRusLng Then Return 'Ноль'
  202.         Return 'Zero'
  203.     EndIf
  204.  
  205.     $iNum = Int($iNum) ; берём целую часть числа
  206.     If Not StringIsDigit($iNum) Or $iNum > 9223372036854775806 Or $iNum = 0 Then Return SetError(1, 0, '') ; если не цифры или огромное число, то вылет
  207.  
  208.     $iNum = StringRegExpReplace($iNum, '(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))', '\1 ') ; dwerf
  209.     $aNum = StringSplit($iNum, ' ')
  210.  
  211.     If $iRusLng Then
  212.         Dim $a[4][10] = _
  213.                 [ _
  214.                 [' десять', ' одиннадцать', ' двенадцать', ' тринадцать', ' четырнадцать', ' пятнадцать', ' шестнадцать', ' семнадцать', ' восемнадцать', ' девятнадцать'], _
  215.                 ['', ' сто', ' двести', ' триста', ' четыреста', ' пятьсот', ' шестьсот', ' семьсот', ' восемьсот', ' девятьсот'], _
  216.                 ['', '', ' двадцать', ' тридцать', ' сорок', ' пятьдесят', ' шестьдесят', ' семьдесят', ' восемьдесят', ' девяносто'], _
  217.                 ['', '', '', ' три', ' четыре', ' пять', ' шесть', ' семь', ' восемь', ' девять'] _
  218.                 ]
  219.  
  220.         Dim $aBitNum[7] = ['', ' тысяч', ' миллион', ' миллиард', ' триллион', ' квадриллион', ' квинтиллион']
  221.     Else
  222.         Dim $a[4][10] = _
  223.                 [ _
  224.                 [' ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'], _
  225.                 ['', 'hundred', ' two hundred', ' three hundred', ' four hundred', ' five hundred', ' six hundred', ' seven hundred', ' eight hundred', ' nine hundred'], _
  226.                 ['', '', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'], _
  227.                 ['', '', '', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine'] _
  228.                 ]
  229.  
  230.         Dim $aBitNum[7] = ['', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion']
  231.     EndIf
  232.  
  233.     $aNum[1] = StringFormat('%03s', $aNum[1]) ; дополняем нулями недостающие разряды
  234.     $sText = ''
  235.  
  236.     For $i = 1 To $aNum[0]
  237.         If $aNum[$i] = '000' Then ContinueLoop
  238.  
  239.         $aN = StringSplit($aNum[$i], '')
  240.         $r = $aNum[0] - $i
  241.  
  242.         For $j = 1 To $aN[0]
  243.             $n = Number($aN[$j])
  244.             If Not $n Then ContinueLoop
  245.  
  246.             $c = $j
  247.  
  248.             Switch $j
  249.                 Case 3
  250.                     Switch $n ; для чисел 1 или 2
  251.                         Case 1
  252.                             If $iRusLng Then
  253.                                 If $r = 1 Then ; разряд единиц (не десятков и сотен)
  254.                                     $sText &= " одна"
  255.                                 Else
  256.                                     $sText &= " один"
  257.                                 EndIf
  258.                             Else
  259.                                 $sText &= " one"
  260.                             EndIf
  261.                         Case 2
  262.                             If $iRusLng Then
  263.                                 If $r = 1 Then
  264.                                     $sText &= " две"
  265.                                 Else
  266.                                     $sText &= " два"
  267.                                 EndIf
  268.                             Else
  269.                                 $sText &= " two"
  270.                             EndIf
  271.                     EndSwitch
  272.                 Case 2 ; для чисел от 10 до 19
  273.                     If $n = 1 Then
  274.                         $c = 0
  275.                         $n = Number($aN[3])
  276.                         $aN[3] = 0
  277.                     EndIf
  278.             EndSwitch
  279.  
  280.             $sText &= $a[$c][$n] ; присоединения числа из массива
  281.         Next
  282.  
  283.         $sText &= $aBitNum[$r]
  284.  
  285.         Switch $n ; окончания для раряда кратного 1000, при $j=3 в конце цикла
  286.             Case 1
  287.                 If $r = 1 And $iRusLng Then ; одна тысяч<а>
  288.                     $sText &= "а"
  289.                 EndIf
  290.             Case 2, 3, 4
  291.                 If $r = 1 Then ; 2,3,4 тысяч<и>
  292.                     If $iRusLng Then
  293.                         $sText &= "и"
  294.                     Else
  295.                         $sText &= "s"
  296.                     EndIf
  297.                 ElseIf $r > 1 Then ; 2,3,4 милион<а>
  298.                     If $iRusLng Then
  299.                         $sText &= "а"
  300.                     Else
  301.                         $sText &= "s"
  302.                     EndIf
  303.                 EndIf
  304.             Case Else
  305.                 If $r > 1 Then ; 5-9 милион<ов>
  306.                     If $iRusLng Then
  307.                         $sText &= "ов"
  308.                     Else
  309.                         $sText &= "s"
  310.                     EndIf
  311.                 EndIf
  312.         EndSwitch
  313.     Next
  314.  
  315.     Return StringStripWS($sText, 3)
  316. EndFunc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement