How do you find a roman numeral equivalent of an integer. Is there a java library which provides this capability?
I did find a similar question, but I would prefer an out of the box API abstraction for this issue. Its just painful to handle all possible combinations in your code.
When calculating with Roman numerals, the order of the numerals is irrelevant. Exceptions: If a smaller unit is to the left of a larger unit, it is subtracted from the larger unit: IV, IX, IL, IC, ID, IM; VL, VC, VD, VM; XL, XC, XD, XM; LD, LM as well as CD and CM.
Let us understand this using an example. We can convert CXI to the decimal number form in the following way: Each Roman numeral represents a number. C, X, and I represent 100, 10, and 1, respectively. Now all the numbers are added, CXI = C + X + I = 100 + 10 + 1 = 111.
Here is a link for many languages including Java. Here's an extract of relevance:
public class RN {
enum Numeral {
I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
int weight;
Numeral(int weight) {
this.weight = weight;
}
};
public static String roman(long n) {
if( n <= 0) {
throw new IllegalArgumentException();
}
StringBuilder buf = new StringBuilder();
final Numeral[] values = Numeral.values();
for (int i = values.length - 1; i >= 0; i--) {
while (n >= values[i].weight) {
buf.append(values[i]);
n -= values[i].weight;
}
}
return buf.toString();
}
public static void test(long n) {
System.out.println(n + " = " + roman(n));
}
public static void main(String[] args) {
test(1999);
test(25);
test(944);
test(0);
}
}
This is the code I am using, right next to the excel column name converter. Why isnt there an apache library for this stuff?
private static final char[] R = {'ↂ', 'ↁ', 'M', 'D', 'C', 'L', 'X', 'V', 'I'};
// or, as suggested by Andrei Fierbinteanu
// private static final String[] R = {"X\u0305", "V\u0305", "M", "D", "C", "L", "X", "V", "I"};
private static final int MAX = 10000; // value of R[0], must be a power of 10
private static final int[][] DIGITS = {
{},{0},{0,0},{0,0,0},{0,1},{1},
{1,0},{1,0,0},{1,0,0,0},{0,2}};
public static String int2roman(int number) {
if (number < 0 || number >= MAX*4) throw new IllegalArgumentException(
"int2roman: " + number + " is not between 0 and " + (MAX*4-1));
if (number == 0) return "N";
StringBuilder sb = new StringBuilder();
int i = 0, m = MAX;
while (number > 0) {
int[] d = DIGITS[number / m];
for (int n: d) sb.append(R[i-n]);
number %= m;
m /= 10;
i += 2;
}
return sb.toString();
}
Edit:
Now that I look at it again, the loop can be condensed to
for (int i = 0, m = MAX; m > 0; m /= 10, i += 2) {
int[] d = DIGITS[(number/m)%10];
for (int n: d) sb.append(R[i-n]);
}
making the code even less readable ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With