Seite 1 von 2

Dec2Rome() »»» Dezimalzahlen in römische Zahlen umwandeln

Verfasst: 15.05.2007 23:29
von AND51
[Beitrag komplett überarbeitet]


Hallo!

Mein Weihnachtsgeschenk an euch: Einen funktionierenden Code, der arabische Dezimalsazahlen >=1 in römische Zahlen umwandelt.
Funktioniert garantiert richtig!

Würde mich freuen, wenn dieser Thread wieder auflebt und ihr vielleicht performantere Versionen postet!
Die Handhabung ist denkbar einfach: Oben steckt man einen positiven Quad rein, unten kommt die zahl in römischer Schreibweise wieder heraus. <)

Code: Alles auswählen

Procedure.s Dec2Rome(number.q) ; AND51 / Dec-2007
	Protected result.s, temp=number/1000
	If temp > 0 ;{ thounsand's
		result=Space(temp)
		ReplaceString(result, " ", "M", 2)
		number-temp*1000
	EndIf ;}
	While number > 99 ;{ hundred's
		temp=number/100
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "C", 2)
			Case 4
				result+"CD"
			Case 5 To 8
				result+"D"
				temp=5
			Case 9
				result+"CM"
		EndSelect
		number-temp*100
	Wend ;}
	While number > 9 ;{ ten's
		temp=number/10
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "X", 2)
			Case 4
				result+"XL"
			Case 5 To 8
				result+"L"
				temp=5
			Case 9
				result+"XC"
		EndSelect
		number-temp*10
	Wend ;}
	While number ;{ one's
		temp=number
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "I", 2)
			Case 4
				result+"IV"
			Case 5 To 8
				result+"V"
				temp=5
			Case 9
				result+"IX"
		EndSelect
		number-temp
	Wend ;}
	ProcedureReturn result
EndProcedure


For n=30 To 230 Step 21
	Debug Str(n)+" to rome: "+Dec2Rome(n)
Nextt
Viel Spaß damit! :allright:

Verfasst: 15.05.2007 23:43
von D@nte
OMFG AND -.-

Setzen (IX - IV + I)

4 = IV (5 - 1)
9 = IX (10 - 1)

Nette Idee aber in dem Fall noch stark verbesserungswürdig das gilt nämlich noch für'n paar Zahlen mehr...

90 = XC (100 - 10) etc pp
Da haste nen Umrechner ;p

In diesem Sinne
Errare humanum est
oder
veni, vidi, amitti

Verfasst: 15.05.2007 23:48
von AND51
Ja, du hast Recht! Danke für deinen Beitrag!!
Ich habe gerade eine Webseite gefunden, die das sher gut erklärt.
Jetzt habe ich es (hoffentlich) verstanden. Bis dahin dürft ihr aber ruhig auch was posten! :allright:

// Edit: Lese gerade auf Wikipedia, dass meine Darstellung doch korrekt ist. Die von D@nte angesprochene Schreibweise ist lediglich eine verkürzende Schreibweise; dennoch ist beides möglich: Wikipedia - Römische Zahlen

Verfasst: 16.05.2007 03:36
von Kaeru Gaman
AND51 hat geschrieben:// Edit: Lese gerade auf Wikipedia, dass meine Darstellung doch korrekt ist. Die von D@nte angesprochene Schreibweise ist lediglich eine verkürzende Schreibweise; dennoch ist beides möglich: Wikipedia - Römische Zahlen
OMFG

...meine güte... wer hat denn diesen beitrag geschrieben...
das ist ja ein riesen-sermon...

Verfasst: 16.05.2007 08:45
von Laurin
Jepp und die reden laufend von Etruskern und Griechen. Das hätte man besser in einen extra Abschnitt untergebracht.

Verfasst: 16.05.2007 10:09
von D@nte
ok, ich werd jetzt aber nicht sagen:
"ich nehm alles zurück und behaupte das Gegenteil"

Deine Darstellung der 4 als IIII ist auch richtig, hab zwar im Internet keine Quelle ausser wiki gefunden die 4 als IIII und nicht als IV darstellt gefunden, aber mein alte Wanduhr im Keller hat auch die IIII als 4. ;)
Allerdings wird auch in der Schule gelehrt das die römische Ziffer(nfolge) IV für 4 steht, deshalb hab ich auch nit weiter drüber nachgedacht als ich gepostet hab. Dementsprechend ist m.E. nach IV die einzige richtige Schreibweise für 4...

Könntest das Programm natürlich für nervensäge wie mich um die zwei anderen römischen Schreibweisen erweitern...

Verfasst: 16.05.2007 10:57
von Kaeru Gaman
> aber mein alte Wanduhr im Keller hat auch die IIII als 4.

das kenne ich auch, aber da bin ich davon ausgegangen, dass es deshalb ist,
weil die VI (&) meist auf dem kopf steht, damit man die beiden nicht verwechselt.

...die 9 wird ja grundsätzlich auf der uhr als IX geschrieben, nicht als VIIII, obwohl die XI auch dabei ist...

also, vorn un hinne inkonsistent, typisch mensch.

Verfasst: 24.12.2007 03:43
von AND51
Hallo!

Als Weihnachtsgeschenk an euch alle ein garantiert funktionierender Code, der jegliche, positive Quad-Zahl in römischer Schreibweise ausgibt:

Code: Alles auswählen

Procedure.s Dec2Rome(number.q) ; AND51 / Dec-2007
	Protected result.s, temp=number/1000
	If temp > 0 ;{ thounsand's
		result=Space(temp)
		ReplaceString(result, " ", "M", 2)
		number-temp*1000
	EndIf ;}
	While number > 99 ;{ hundred's
		temp=number/100
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "C", 2)
			Case 4
				result+"CD"
			Case 5 To 8
				result+"D"
				temp=5
			Case 9
				result+"CM"
		EndSelect
		number-temp*100
	Wend ;}
	While number > 9 ;{ ten's
		temp=number/10
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "X", 2)
			Case 4
				result+"XL"
			Case 5 To 8
				result+"L"
				temp=5
			Case 9
				result+"XC"
		EndSelect
		number-temp*10
	Wend ;}
	While number ;{ one's
		temp=number
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "I", 2)
			Case 4
				result+"IV"
			Case 5 To 8
				result+"V"
				temp=5
			Case 9
				result+"IX"
		EndSelect
		number-temp
	Wend ;}
	ProcedureReturn result
EndProcedure

For n=30 To 230 Step 21
	Debug Str(n)+" to rome: "+Dec2Rome(n)
Next
Viel Spaß damit! :allright:
Würde mich freuen, wenn optimiertere/performantere Versionen hier auftauchen würden!

@ Andre:
Könnte man diesen Code vielleicht ins CodeArchiv aufnehmen?

Verfasst: 24.12.2007 10:55
von Xaby
Hier mal meine Versionen ...

Meine war ja auch vor ANDy51s fertig :mrgreen:

Da es im römischen anscheinend nur 3999 Zahlen gibt, könnte man auch eine Tabelle erzeugen, vielleicht sogar per Hand und je nach dem, welche Zahl der Benutzer gern haben möchte, wird einfach an der Stelle in der Tabelle geschaut. :mrgreen:

Mit Anleitung. Prozeduren müsst ihr selbst draus machen :D

Funktionen für
arabisch zu römisch und
römisch zu arabisch

Das meiste an dem Code sind die Kommentare

Code: Alles auswählen

;/ Folker Linstedt
;/ 2007|12|23
;/ arabische Zahlen in römische Zahlen umwandeln


; I = 1, II = 2, III = 3, IV = 4, V = 5, VI = 6, VII = 7, VIII = 8, 9 = IX, 10 = X,
; XI = 11, XII = 12, ... 19 = XIX aber nicht IXX

; XXXIX = 39

;/ Regeln:
; - 5er können nicht addiert werden. 
; - 1er können maximal drei addiert werden! Beachte 39, 390, 3900
; - 1er kann höchstens einer abgezogen werden
; - es können einer nur von 5er gleicher Ordnung oder 1ern einer Ordnung höher abgezogen werden
; - es können gleichzeitig keine 1er addiert und subtraiert werden (entweder oder)

;/ maximale Zahl: MMMCMXCIX - 3999

;/ oft verwendete Zahl : MCMXCIX - 1999 (Jahr-2000-Problem Y2K)

;           1 = I
;  5 = V,  10 = X
; 50 = L, 100 = C,
;500 = D,1000 = M,    

;/ http://www.mathematische-basteleien.de/roemisch.htm


;/ 


Z$="2548" ;/ Beispiel-Zahl

;/ erwartetes Ergebnis: MMDXLVIII

R$="" ;/ römische Zahl

;/ Ansatz 1
; Z=Val(Z$)
; R$=RSet("",Z / 1000 ,"M")

;/ Ansatz 2
Dim R.s(4)

Procedure.s RepStr(R1$="",R2$="L",R3$="C")
  Sx$="I;II;III;IV;V;VI;VII;VIII;IX"
  If R1$
    Sx$=ReplaceString(Sx$,"X",R3$)
    Sx$=ReplaceString(Sx$,"V",R2$)
    Sx$=ReplaceString(Sx$,"I",R1$)
  EndIf
  ProcedureReturn Sx$
EndProcedure


R(1)=RepStr()
R(2)=RepStr("X")
R(3)=RepStr("C","D","M")
R(4)=RepStr("M","Y","K") ;/ geht erstmal nur für "M"

 Z$=InputRequester("Zahl eingeben","arabische Zahl","123")

If Val(Z$)<4000

  ;/ dieser Block erstellt römische Zahlen
  L=Len(Z$)  
  For i=1 to L
     R$+StringField(R(L+1-i),Val(Mid(Z$,i,1)),";")
  Next
  ;/


 MessageRequester("Ausgabe","arabische Zahl: "+Z$+" entspricht römischer Zahl: "+R$)


Else
  MessageRequester("HINWEIS","Diese Zahl ("+Z$+") kann nicht römisch dargestellt werden")
EndIf

;/ umgekehrt ...

Z$=InputRequester("Zahl eingeben","römische Zahl","DCCXXXIX") ; MCMXCIX

;/ Ansatz : Alle Zahlen addieren bzw. Abziehen und das Ergebnis wieder in römische Zahl wandeln und Strings vergleichen.

Z$=Trim(Z$)
;/ Groß-Kleinschreibung-Umwandlung eventuell ...

R$=Z$
Z=0

For h=1 to 4 
  For i=1 to 9
    SxF$=StringField(R(h),10-i,";")
    G=FindString(Z$,SxF$,1) 
    If G
      Z$=ReplaceString(Z$,SxF$,"") 
      Z+Pow(10,(h-1))*(10-i)
      
    EndIf
  Next
Next

Z$=Str(Z)
D$=""
  ;/ dieser Block erstellt römische Zahlen
  L=Len(Z$)  
  For i=1 to L
    D$+StringField(R(L+1-i),Val(Mid(Z$,i,1)),";")
  Next
  ;/
If D$=R$
  MessageRequester("Ausgabe","römische Zahl: "+R$+" entspricht arabischer Zahl: "+Str(Z))
Else
  MessageRequester("Hinweis : Fehler bei der Eingabe!",Str(Z)+" : Ihre Eingabe: "+R$+Chr(10)+" - Mögliches Ergebnis: "+D$) 
EndIf  
:allright: Frohes Weihnachtsfest und guten Rutsch :allright:

Verfasst: 24.12.2007 13:43
von AND51
> Da es im römischen anscheinend nur 3999 Zahlen gibt
Das konnte ich jetzt nicht nachvollziehen, auch wenn das irgendwo steht. Z. B. eine römische Legion war eine Truppe von 6000 Mann. Wie können die da nur bis 3999 zählen?
Mein Code stellt halt jeder Tausend ein 'M' voran, dann passt das schon - notfalls achtet der Coder eben selbst darauf, dass er keine Zahlen >3999 übergibt.

> könnte man auch eine Tabelle erzeugen
Das würde IMHO zu viel Speicher beanspruchen, sowohl in der EXe als auch zur Laufzeit im Speicher. AUßerdem hat man eben das Problem: Wenn jemand sagt: "Ich will aber Zahlen >3999!", dann kriegt man das mit einer Tabelle (Array) nicht hin, da der Zahlenbereich zu begrenzt ist.

> vielleicht sogar per Hand [erzeugen]
Wieso? Du hast doch meinen Code...

> und je nach dem, welche Zahl der Benutzer gern haben möchte, wird einfach an der Stelle in der Tabelle geschaut.
Das müsste man dann noch nicht einmal in einer Prozedur machen, es reicht auch schon ein globales Array, auf das man im weiteren Programmverlauf zugreift.

> Prozeduren müsst ihr selbst draus machen
Das ist ja eigentlich die Aufgabe des Posters... :D