Decimal Number <-> Roman Numerals Converter

Started by MrBcx, August 13, 2024, 12:02:35 AM

Previous topic - Next topic

MrBcx

Quote from: RAW on August 18, 2024, 02:02:33 AM

@ MrBCX
Quote
Did you not read this in the source code?

Yes, I have. The end of the number for Roman numerals is 9999. The number 10000 cannot be represented in Roman numerals.
Therefore my statement "10 x MMMMMMMMMMM = 10,000" is wrong.
If someone wants to represent numbers up to 1,000,000, then the Latin representation can be chosen. 

There are only number words ... Thx

https://en.wikipedia.org/wiki/Latin_numerals
https://www.arndt-bruenner.de/mathe/scripts/numeraliatab.htm

No problem.   Those are interesting links.  I don't have a particular fascination or need for the ancient
systems but I was impressed by the brevity of the two functions in the code that I converted to BCX.

RAW


@ MrBCX
Quote
Did you not read this in the source code?

Yes, I have. The end of the number for Roman numerals is 9999. The number 10000 cannot be represented in Roman numerals.
Therefore my statement "10 x MMMMMMMMMMM = 10,000" is wrong.
If someone wants to represent numbers up to 1,000,000, then the Latin representation can be chosen. 

There are only number words ... Thx

https://en.wikipedia.org/wiki/Latin_numerals
https://www.arndt-bruenner.de/mathe/scripts/numeraliatab.htm

Robert

Quote from: MrBcx on August 13, 2024, 12:02:35 AM

'====================================================================
'           Decimal Number <-> Roman Numerals Converter
'====================================================================
' by SierraKen at QB64PE forum
' Enhancements by BPLUS at QB64PE forum
' Converted to BCX BASIC by MrBcx (August 2024)       (Public Domain)
'====================================================================

DIM B AS STRING
DIM C AS STRING
DIM i AS INTEGER
DIM r AS STRING

B = STRING$(15, 32)

FOR i = 1 TO 3999
    r = Romanize$(i)
    C = B
    MID$(C, 1, LEN(r)) = r
    PRINT i, " ", C, " ", Numeralize(r)
NEXT
PAUSE

'====================================================================

FUNCTION Romanize (number AS INTEGER) AS STRING
    DIM values[14] AS INTEGER
    DIM symbols[14] AS STRING
    DIM romanNum AS STRING
    DIM num AS INTEGER
    DIM i AS INTEGER

    IF number < 1 OR number > 3999 THEN
        FUNCTION = "Number out of range. Please enter a number between 1 and 3999."
    ELSE
        values[1] = 1000: symbols[1] = "M"
        values[2] = 900: symbols[2] = "CM"
        values[3] = 500: symbols[3] = "D"
        values[4] = 400: symbols[4] = "CD"
        values[5] = 100: symbols[5] = "C"
        values[6] = 90: symbols[6] = "XC"
        values[7] = 50: symbols[7] = "L"
        values[8] = 40: symbols[8] = "XL"
        values[9] = 10: symbols[9] = "X"
        values[10] = 9: symbols[10] = "IX"
        values[11] = 5: symbols[11] = "V"
        values[12] = 4: symbols[12] = "IV"
        values[13] = 1: symbols[13] = "I"

        romanNum = ""
        num = number

        FOR i = 1 TO 13
            WHILE num >= values[i]
                romanNum = romanNum + symbols[i]
                num = num - values[i]
            WEND
        NEXT i

        FUNCTION = romanNum
    END IF
END FUNCTION

'====================================================================

FUNCTION Numeralize (Roman AS STRING) AS INTEGER
    DIM tot AS INTEGER
    DIM copy AS STRING
    DIM place AS INTEGER

    copy = Roman

    place = INSTR(copy, "CM")
    IF place THEN tot = tot + 900: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "CD")
    IF place THEN tot = tot + 400: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "XC")
    IF place THEN tot = tot + 90: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "XL")
    IF place THEN tot = tot + 40: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "IX")
    IF place THEN tot = tot + 9: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "IV")
    IF place THEN tot = tot + 4: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "M")
    WHILE place
        tot = tot + 1000
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "M")
    WEND

    place = INSTR(copy, "D")
    WHILE place
        tot = tot + 500
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "D")
    WEND

    place = INSTR(copy, "C")
    WHILE place
        tot = tot + 100
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "C")
    WEND

    place = INSTR(copy, "L")
    WHILE place
        tot = tot + 50
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "L")
    WEND

    place = INSTR(copy, "X")
    WHILE place
        tot = tot + 10
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "X")
    WEND

    place = INSTR(copy, "V")
    WHILE place
        tot = tot + 5
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "V")
    WEND

    place = INSTR(copy, "I")
    WHILE place
        tot = tot + 1
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "I")
    WEND

    FUNCTION = tot
END FUNCTION



Hi MrBCX:

Thanks for this. It's a great, easy to understand, and I think clever, example of the use of the BCX MID statement.

Definitely BCX Doc material.

MrBcx

Quote from: RAW on August 13, 2024, 12:39:37 PM
Hi,

10 x MMMMMMMMMM = 10.000

What is the number for the year -3456 ?

Did you not read this in the source code?

IF number < 1 OR number > 3999 THEN
        FUNCTION = "Number out of range. Please enter a number between 1 and 3999."

    ELSE
      |
      |

RAW

Hi,

10 x MMMMMMMMMM = 10.000

What is the number for the year -3456 ?



MrBcx

#3
Quote from: jbk on August 13, 2024, 07:05:43 AM
this could be helpful to someone trying to convert code from QB64 to BCX 👍

The conversion didn't require much and it's easy to use ChatGPT to do the heavy lifting.

* Change arrays from parenthesis to square brackets
* Change function returns from "FuncName ="   to "FUNCTION = " 
* Change STRING$(15, " ") to STRING$(15, ASC(" "))  or more simply STRING$(15,32)

Everything else was purely cosmetic.  I removed all sigils ($,%) from function and variable names.

The code is also useful for its core purpose: converting between two systems of numbers :-)

jbk

this could be helpful to someone trying to convert code from QB64 to BCX 👍

MrBcx


'====================================================================
'           Decimal Number <-> Roman Numerals Converter
'====================================================================
' by SierraKen at QB64PE forum
' Enhancements by BPLUS at QB64PE forum
' Converted to BCX BASIC by MrBcx (August 2024)       (Public Domain)
'====================================================================

DIM B AS STRING
DIM C AS STRING
DIM i AS INTEGER
DIM r AS STRING

B = STRING$(15, 32)

FOR i = 1 TO 3999
    r = Romanize$(i)
    C = B
    MID$(C, 1, LEN(r)) = r
    PRINT i, " ", C, " ", Numeralize(r)
NEXT
PAUSE

'====================================================================

FUNCTION Romanize (number AS INTEGER) AS STRING
    DIM values[14] AS INTEGER
    DIM symbols[14] AS STRING
    DIM romanNum AS STRING
    DIM num AS INTEGER
    DIM i AS INTEGER

    IF number < 1 OR number > 3999 THEN
        FUNCTION = "Number out of range. Please enter a number between 1 and 3999."
    ELSE
        values[1] = 1000: symbols[1] = "M"
        values[2] = 900: symbols[2] = "CM"
        values[3] = 500: symbols[3] = "D"
        values[4] = 400: symbols[4] = "CD"
        values[5] = 100: symbols[5] = "C"
        values[6] = 90: symbols[6] = "XC"
        values[7] = 50: symbols[7] = "L"
        values[8] = 40: symbols[8] = "XL"
        values[9] = 10: symbols[9] = "X"
        values[10] = 9: symbols[10] = "IX"
        values[11] = 5: symbols[11] = "V"
        values[12] = 4: symbols[12] = "IV"
        values[13] = 1: symbols[13] = "I"

        romanNum = ""
        num = number

        FOR i = 1 TO 13
            WHILE num >= values[i]
                romanNum = romanNum + symbols[i]
                num = num - values[i]
            WEND
        NEXT i

        FUNCTION = romanNum
    END IF
END FUNCTION

'====================================================================

FUNCTION Numeralize (Roman AS STRING) AS INTEGER
    DIM tot AS INTEGER
    DIM copy AS STRING
    DIM place AS INTEGER

    copy = Roman

    place = INSTR(copy, "CM")
    IF place THEN tot = tot + 900: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "CD")
    IF place THEN tot = tot + 400: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "XC")
    IF place THEN tot = tot + 90: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "XL")
    IF place THEN tot = tot + 40: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "IX")
    IF place THEN tot = tot + 9: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "IV")
    IF place THEN tot = tot + 4: MID$(copy, place, 2) = "  "

    place = INSTR(copy, "M")
    WHILE place
        tot = tot + 1000
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "M")
    WEND

    place = INSTR(copy, "D")
    WHILE place
        tot = tot + 500
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "D")
    WEND

    place = INSTR(copy, "C")
    WHILE place
        tot = tot + 100
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "C")
    WEND

    place = INSTR(copy, "L")
    WHILE place
        tot = tot + 50
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "L")
    WEND

    place = INSTR(copy, "X")
    WHILE place
        tot = tot + 10
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "X")
    WEND

    place = INSTR(copy, "V")
    WHILE place
        tot = tot + 5
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "V")
    WEND

    place = INSTR(copy, "I")
    WHILE place
        tot = tot + 1
        MID$(copy, place, 1) = " "
        place = INSTR(copy, "I")
    WEND

    FUNCTION = tot
END FUNCTION