Sign in to follow this  
Followers 0
Mat

integer to roman numerals

7 posts in this topic

#1 ·  Posted (edited)

I was trying to work out what happens when you use roman numerals with large numbers, and it turns out that by enclosing in brackets () you can multiply by 1000!

eg: (M) = 1000000

.....((M)) = 1000000000

etc.

so I made this! It can use different amounts of brackets, so you can if you like set $nMaxPar to 0 and have lots of M's!!!

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +- a couple = (M)

lol

here it is<== Downloads so far: CDXXIV

example: (-1 calculates brackets needed for you!)

; Example 1: standard numeral, low number
MsgBox (48, "Test 1", "42 = " & _Roman (42))
; Example 2: parenthesis numerals, high number
MsgBox (48, "Test 3", "4222222 (With parenthesis') = " & _Roman (422222))

Just a bit of fun, but I think it turned out alright!

MDiesel

Edited by mdiesel

Share this post


Link to post
Share on other sites



Finally got round to completing the function with a _MathNumeralToInt function. Code updated in post 1.

It took me a lot longer than it shouldve, becouse I completed it and then realised that I had done the entire logic bit wrong - as I was searchng only for the sequence of digits in the array. If that makes any sense...

basically, a couple of rewrites later I got there.

The new function also supports the brackets, so it is compatable with the original function

MDiesel

Share this post


Link to post
Share on other sites

I would suggest declaring $Numbers outside the functions so that it only gets created once. 'Cause if a user uses it a lot it's going to be noticeably slower with you declaring the array every time. Just my opinion.


My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites

But then you also have the problem then of global variables, and if you look at it, the 2 aren't the same, I will have a look though, it may be possible.

MDiesel

Share this post


Link to post
Share on other sites

found a much shorter + faster + better + more efficient way!!

Thanks to a vb script I dug up, I got the idea of having an array with digits, 10's + 100's, and forming it by adding them. something funny happens after you go past 18 digits, i can't seem to figure it out....

Func _Roman ($iNum)
   Local $asNum[3][10] = [["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], _
      ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], _
      ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]]
   Local $sRet = "", $i = 0, $iLen = StringLen ($iNum), $sBra = ""
   If $iLen > 3 Then
      $sBra = "(" & _Roman (StringTrimRight ($iNum, 3)) & ")"
      $iNum = StringRight ($iNum, 3)
      $iLen = 3
   EndIf
   For $i = $iLen To 1 Step -1
      $sRet = $asNum[$iLen - $i][int (StringMid ($iNum, $i, 1))] & $sRet
   Next
   Return $sBra & $sRet
EndFunc; ==> _Roman

I am working on a more efficient reversal. I will release that when its done!

code is updated in post 1

MDiesel

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

; ============================================================================================
; Function Name ...: _DecToRoman
; Description ........: Convert decimal to Roman
; Syntax.......: _DecToRoman ( $iDec )
; Parameters:
;       $iDec - decimal number from 0 to 3999 (Adding thousands adds character "M")
; Return values: Success - Returns the string
;                   Failure - Returns -1 (Number outside the specified range), @error - 1, 2
; Author(s) ..........: AZJIO, заимствовано здесь http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
; Remarks ..........: If 0, the empty string
; ============================================================================================
; Имя функции ...: _DecToRoman
; Описание ........: Преобразует десятичное число в римское
; Синтаксис.......: _DecToRoman ( $iDec )
; Параметры:
;       $iDec - десятичное число от 0 до 3999 (Добавление тысяч добавляет символ "M")
; Возвращаемое значение: Успешно - Возвращает строку
;                   Неудачно - Возвращает -1 (число вне указанного диапазона) и устанавливает @error 
; Автор ..........: AZJIO, Credits http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
; Примечания ..: Если 0, то пустая строка
; ============================================================================================
Func _DecToRoman($iDec)
    $iDec = Int($iDec) ; берём целую часть числа
    If $iDec < 1 Then
        If $iDec < 0 Then Return SetError(1, 0, -1)
        Return SetError(0, 0, '')
    EndIf
    If $iDec > 3999 Then Return SetError(2, 0, -1) ; если огромное число
    Local $r[13] = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
    Local $n[13] = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
    Local $sRim = ''
    
    For $i = 0 To 12
        While $iDec >= $n[$i]
            $iDec -= $n[$i]
            $sRim &= $r[$i]
        WEnd
    Next
    Return $sRim
EndFunc   ;==>_DecToRoman

; ============================================================================================
; Function Name ...: _RomanToDec
; Description ........: Converts Roman numbers to decimal
; Syntax.......: _RomanToDec ( $sRoman )
; Parameters:
;       $sRoman - Roman number
; Return values: Success - Returns decimal number
;                   Failure - Returns -1, @error = -1, if the number doesn't correspond to a format
; Author(s) ..........: AZJIO, http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
; 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
; ============================================================================================
; Имя функции ...: _RomanToDec
; Описание ........: Преобразует римские числа в десятичные
; Синтаксис.......: _RomanToDec ( $sRoman )
; Параметры:
;       $sRoman - римское число
; Возвращаемое значение: Успешно - Возвращает десятичное число
;                   Неудачно - Возвращает -1, @error = -1, если число не соответствует формату
; Автор ..........: AZJIO, http://forum.algolist.ru/algorithm-maths-mathematical/663-rimskie-chisla.html
; Примечания ..: Прверяется правильность числа, т.е. не только использование символов но и порядок. Только каноническое написание, то есть 99 пишется как XCIX, а не IC. Если символы в нижнем регистре то @extended = 1
; ============================================================================================
Func _RomanToDec($sRoman)
    Local $extended = 0
    If Not StringIsUpper($sRoman) Then $extended = 1
    If StringRegExp($sRoman, '(?i)([VLD])\1') Or StringRegExp($sRoman, '(?i)([IXCM])\1\1\1') Then Return SetError(-1, $extended, -1)
    Local $c[7] = ['C', 'C', 'X', 'X', 'I', 'I', ''], _
    $d[7] = [100, 100, 10, 10, 1, 1, 0], _
    $r[7] = ['M', 'D', 'C', 'L', 'X', 'V', 'I'], _
    $n[7] = [1000, 500, 100, 50, 10, 5, 1], _
    $iDec = 0
    
    For $i = 0 To 6
        $aTmp = StringRegExp($sRoman, '^(' & $r[$i] & '+' & $c[$i] & $r[$i] & '|' & $r[$i] & '+|' & $c[$i] & $r[$i] & ')(.*?)$', 3)
        If Not @error Then
            $iDec += StringLen($aTmp[0]) * $n[$i]
            If StringInStr($aTmp[0], $c[$i]) Then $iDec -= $d[$i] + $n[$i]
            $sRoman = $aTmp[1]
            If Not $sRoman Then ExitLoop
        EndIf
    Next
    If $sRoman Then Return SetError(-1, $extended, -1)
    Return $iDec
EndFunc   ;==>_RomanToDec

Edited by AZJIO

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0