-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnum2roman.m
111 lines (99 loc) · 3.65 KB
/
num2roman.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
function varargout=num2roman(n)
%NUM2ROMAN Roman numerals.
% NUM2ROMAN(N) returns modern Roman numeral form of integer N, which can
% be scalar (returns a string), vector or matrix (returns a cell array of
% strings, same size as N).
%
% The function uses strict rules whith substractive notation and commonly
% found 'MMMM' form for 4000. It includes also parenthesis notation for
% large numbers (multiplication by 1000). It considers only the integer
% part of N.
%
% Examples:
% num2roman(1968)
% num2roman(10.^(0:7))
% reshape(num2roman(1:100),10,10)
%
% See also ROMAN2NUM.
%
% Author: François Beauducel <[email protected]>
% Institut de Physique du Globe de Paris
% Created: 2005
% Modified: 2021-01-05
% Copyright (c) 2005-2021, François Beauducel, covered by BSD License.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in
% the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
error(nargchk(1,1,nargin))
if ~isnumeric(n)
error('N must be numeric array (scalar, vector or matrix).')
end
s = cell(size(n));
for k = 1:numel(n)
m = max(floor((log10(n(k)) - log10(5000))/3) + 1,0);
for i = m:-1:0
if isnan(n(k))
ss = '?';
else
ss = roman(fix(n(k)/10^(3*i)));
end
if i == m
s{k} = ss;
else
s{k} = ['(',s{k},')',ss];
end
n(k) = mod(n(k),10^(3*i));
end
end
% converts to string if n is a scalar
if numel(n) == 1
s = s{1};
end
% converts to string if n is empty
if isempty(n)
s = '';
end
% only display without output argument
if nargout == 0
disp(s)
else
varargout{1} = s;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function x=roman(n)
% this subfunction converts numbers up to 4999
r = reshape('IVXLCDM ',2,5); % the 3 last blank chars are to avoid error for n >= 1000
x = '';
m = floor(log10(n)) + 1; % m is the number of digit
% n is processed sequentially for each digit
for i = m:-1:1
ii = fix(n/10^(i-1)); % ii is the digit (0 to 9)
% Roman numeral is a concatenation of r(1:2,i) and r(1,i+1)
% combination with regular rules (exception for 4000 = MMMM)
% Note: the expression uses REPMAT behavior which returns empty
% string for N <= 0
x = [x,repmat(r(1,i),1,ii*(ii < 4 | (ii==4 & i==4)) + (ii == 9) + (ii==4 & i < 4)), ...
repmat([r(2,i),repmat(r(1,i),1,ii-5)],1,(ii >= 4 & ii <= 8 & i ~= 4)), ...
repmat(r(1,i+1),1,(ii == 9))];
n = n - ii*10^(i-1); % substract the most significant digit
end