Имя пользователя:
Пароль:
 

Название темы: Перевод числа в пропись
Показать сообщение отдельно

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Вот вариант на английском, можно перевести значения:

Код: Выделить весь код
$iNum = 10598
$sNumName = _NumberNumToName($iNum)
$sNumber = _NumberNameToNum($sNumName)

ConsoleWrite($sNumName & @LF)
ConsoleWrite($sNumber & @LF)

Func _NumberNameToNum($sWord)
	Local $sDigits = "zero|one|two|three|four|five|six|seven|eight|nine"
	Local $sTeens = "eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen"
	Local $sTens = "ten|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety"
	Local $sBig = "thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion|octillion|nonillion|" & _
		"decillion|undecillion|duodecillion|tredecillion|quattuordecillion|quindecillion|sexdecillion|septendecillion|octodecillion|novemdecillion|vigintillion"
	
	Local $asDigits = StringSplit($sDigits, "|", 2)
	Local $asTeens = StringSplit($sTeens, "|", 2)
	Local $asTens = StringSplit($sTens, "|", 2)
	Local $asBig = StringSplit($sBig, "|", 2)
	
	Local $sRet = ""
	Local $iTemp[3] = [0, 0, 0]
	Local $aWords
	
	; check...
	If Not StringRegExp($sWord, "^(minus\s+)?((((" & $sTens & ")\s+)?(" & $sDigits & ")|(" & $sTeens & ")|(" & $sTens & "))\s+(hundred|" & $sBig & ")(\s+and)?(\s+|\z))*(((" & $sTens & ")\s+)?(" & $sDigits & ")?|(" & $sTeens & ")|(" & $sTens & "))(\s+point(\s+(" & $sDigits & "))+)?$") Then
		Return SetError(1)
	EndIf
	
	$sWord = StringReplace($sWord, " and", "")
	
	For $i = 0 To 8
		$sWord = StringReplace($sWord, $asTeens[$i], "ten " & $asDigits[$i + 1])
	Next
	
	$aWords = StringSplit($sWord, " ")
	
	If StringInStr($sWord, " point ") Then
		Do
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$aWords[0]] Then
					$sRet = $n & $sRet
					ExitLoop
				EndIf
			Next
			
			$aWords[0] -= 1
		Until $aWords[$aWords[0]] <> "point"
		
		$sRet = "." & $sRet
		If $aWords[$aWords[0]] = "zero" Then $sRet = "0" & $sRet
	EndIf
	
	For $i = $aWords[0] To 1 Step -1
		If $i = 1 And $aWords[1] = "minus" Then
			$sRet = "-" & $sRet
			ExitLoop
		EndIf
		
		If StringInStr("|" & $sDigits & "|", "|" & $aWords[$i] & "|") Then ; Digit
			If $iTemp[0] <> 0 Then Return SetError(2, $i, "") ; Invalid word: @extended, expected large identifier not digit.
			
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$i] Then
					$iTemp[0] = $n
					ExitLoop
				EndIf
			Next
		ElseIf StringInStr("|" & $sTens & "|", "|" & $aWords[$i] & "|") Then ; Tens
			If $iTemp[1] <> 0 Then Return SetError(3, $i, "") ; Invalid word: @extended, expected large identifier not ten.
			
			For $n = 0 To UBound($asTens) - 1
				If $asTens[$n] = $aWords[$i] Then
					$iTemp[1] = $n + 1
					ExitLoop
				EndIf
			Next
		ElseIf $aWords[$i] = "hundred" Then ; hundred
			If $iTemp[2] <> 0 Then Return SetError(4, $i, "") ; Invalid word: @extended, expected large identifier not hundred.
			
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$i - 1] Then
					$iTemp[2] = $n
					$i -= 1
					ExitLoop
				EndIf
			Next
		ElseIf StringInStr("|" & $sBig & "|", "|" & $aWords[$i] & "|") Then ; BIG
			$sRet = $iTemp[2] & $iTemp[1] & $iTemp[0] & $sRet
			
			$iTemp[0] = 0
			$iTemp[1] = 0
			$iTemp[2] = 0
		Else
			Return SetError(4, $i, "") ; Invalid word: @extended, word not recognized.
		EndIf
	Next
	
	$sRet = $iTemp[2] & $iTemp[1] & $iTemp[0] & $sRet
	
	; No leading 0's
	While StringLeft($sRet, 1) = "0" And StringLeft($sRet, 2) <> "0."
		$sRet = StringTrimLeft($sRet, 1)
	WEnd
	
	; No trailing 0's if decimal
	If StringInStr($sRet, ".") Then
		While StringRight($sRet, 1) = "0"
			$sRet = StringTrimRight($sRet, 1)
		WEnd
		
		If StringRight($sRet, 1) = "." Then $sRet = StringTrimRight($sRet, 1)
	EndIf
	
	Return $sRet
EndFunc

Func _NumberNumToName($iNum)
	$iNum = String($iNum)
	$iNum = StringStripWS($iNum, 8)
	If Not StringRegExp($iNum, "^-?\d+?(\.\d+)?$") Then Return SetError(2, 0, "")
	If $iNum = "0" Then Return "zero"
	
	Local $asDigits[10] = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
	Local $asTeens[9] = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
	Local $asTens[9] = ["ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
	Local $asBig[21] = ["thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", _
		"decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion", "quindecillion", "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion"]
	
	; No leading 0's
	While StringLeft($iNum, 1) = "0" And StringLeft($iNum, 2) <> "0."
		$iNum = StringTrimLeft($iNum, 1)
	WEnd
	
	; No trailing 0's if decimal
	If StringInStr($iNum, ".") Then
		While StringRight($iNum, 1) = "0"
			$iNum = StringTrimRight($iNum, 1)
		WEnd
		
		If StringRight($iNum, 1) = "." Then $iNum = StringTrimRight($iNum, 1)
	EndIf
	
	Local $iTemp
	Local $iLen
	Local $sRet = ""
	Local $nDec = ""
	
	; Do decimal places later
	If StringInStr($iNum, ".") Then
		$nDec = StringMid($iNum, StringInStr($iNum, ".") + 1)
		$iNum = StringLeft($iNum, StringInStr($iNum, ".") - 1)
	EndIf
	
	; Check negative
	If StringLeft($iNum, 1) = "-" Then
		$iNum = StringTrimLeft($iNum, 1)
		$sRet &= "minus "
	EndIf
	
	; Very big numbers
	For $i = 21 To 1 Step -1
		If StringLen($iNum) > $i * 3 Then
			$iLen = Mod(StringLen($iNum), 3)
			If $iLen = 0 Then $iLen = 3
			
			$iTemp = StringLeft($iNum, $iLen)
			$iNum = StringTrimLeft($iNum, $iLen)
			
			$iTemp = _NumberNumToName($iTemp)
			If $iTemp = "" Or $iTemp = "0" Then ContinueLoop
			If Not @error Then $sRet &= $iTemp & " " & $asBig[$i - 1] & " "
		EndIf
	Next
	
	; hundreds
	If StringLen($iNum) >= 3 Then
		$iTemp = StringLeft($iNum, 1)
		$iNum = StringTrimLeft($iNum, 1)
		
		If $iTemp <> "0" Then $sRet &= $asDigits[Int($iTemp)] & " hundred "
		If $iNum <> "00" Then $sRet &= "and "
	EndIf
	
	If StringLen($iNum) = 2 And StringLeft($iNum, 1) = "1" And StringRight($iNum, 1) <> "0" Then
		$iTemp = StringRight($iNum, 1)
		$sRet &= $asTeens[Int($iTemp) - 1] & " "
		
		$iNum = ""
	Else
		; Tens
		If StringLen($iNum) = 2 Then
			$iTemp = StringLeft($iNum, 1)
			$iNum = StringTrimLeft($iNum, 1)
			
			If $iTemp <> "0" Then $sRet &= $asTens[Int($iTemp) - 1] & " "
		EndIf
		
		; Digits
		If StringLen($iNum) = 1 Then
			If $iNum <> "0" Then $sRet &= $asDigits[Int($iNum)] & " "
			
			$iNum = ""
		EndIf
	EndIf
	
	If $nDec <> "" Then
		If $sRet = "" Or $sRet = "minus " Then $sRet &= "zero "
		$sRet &= "point "
		
		Do
			$iTemp = StringLeft($nDec, 1)
			$nDec = StringTrimLeft($nDec, 1)
			
			$sRet &= $asDigits[Int($iTemp)] & " "
		Until $nDec = ""
	EndIf
	
	$sRet = StringTrimRight($sRet, 1)
	
	Return $sRet
EndFunc

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 15:07, 16-04-2012 | #2

Название темы: Перевод числа в пропись