1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jexl3;
19
20 import java.math.BigInteger;
21 import java.math.MathContext;
22
23
24
25
26 public class Arithmetic360 extends JexlArithmetic {
27 public Arithmetic360(final boolean astrict) {
28 super(astrict);
29 }
30
31 public Arithmetic360(final boolean astrict, final MathContext bigdContext, final int bigdScale) {
32 super(astrict, bigdContext, bigdScale);
33 }
34
35
36
37
38
39
40
41
42 @Override
43 public Object and(final Object left, final Object right) {
44 final Number l = asLongNumber(left);
45 final Number r = asLongNumber(right);
46 if (l != null && r != null) {
47 return narrowLong(left, right, l.longValue() & r.longValue());
48 }
49 return toBigInteger(left).and(toBigInteger(right));
50 }
51
52
53
54
55
56
57
58 protected Number asIntNumber(final Object value) {
59 return value instanceof Integer
60 || value instanceof Short
61 || value instanceof Byte
62 ? (Number) value
63 : null;
64 }
65
66
67
68
69
70
71 protected Long castLongNumber(final Object value) {
72 return value instanceof Long ? (Long) value : null;
73 }
74
75
76
77
78
79
80
81 @Override
82 public Object complement(final Object val) {
83 final long l = toLong(val);
84 return narrowLong(val, ~l);
85 }
86
87
88
89
90
91
92
93
94 protected Number narrowLong(final Object operand, final long result) {
95 if (!(operand instanceof Long)) {
96 final int ir = (int) result;
97 if (result == ir) {
98 return ir;
99 }
100 }
101 return result;
102 }
103
104
105
106
107
108
109
110
111
112 @Override
113 protected Number narrowLong(final Object lhs, final Object rhs, final long result) {
114 if (!(lhs instanceof Long || rhs instanceof Long)) {
115 final int ir = (int) result;
116 if (result == ir) {
117 return ir;
118 }
119 }
120 return result;
121 }
122
123
124
125
126
127
128
129
130 @Override
131 public Object or(final Object left, final Object right) {
132 final Number l = asLongNumber(left);
133 final Number r = asLongNumber(right);
134 if (l != null && r != null) {
135 return narrowLong(left, right, l.longValue() | r.longValue());
136 }
137 return toBigInteger(left).or(toBigInteger(right));
138 }
139
140
141
142
143
144
145
146
147 @Override
148 public Object shiftLeft(final Object left, final Object right) {
149 if (left == null && right == null) {
150 return controlNullNullOperands(JexlOperator.SHIFTLEFT);
151 }
152 final int r = toInteger(right);
153 Number l = asIntNumber(left);
154 if (l != null) {
155 return l.intValue() << r;
156 }
157 l = castLongNumber(left);
158 if (l != null) {
159 return l.longValue() << r;
160 }
161 return toBigInteger(left).shiftLeft(r);
162 }
163
164
165
166
167
168
169
170
171 @Override
172 public Object shiftRight(final Object left, final Object right) {
173 if (left == null && right == null) {
174 return controlNullNullOperands(JexlOperator.SHIFTRIGHT);
175 }
176 final int r = toInteger(right);
177 Number l = asIntNumber(left);
178 if (l != null) {
179 return l.intValue() >> r;
180 }
181 l = castLongNumber(left);
182 if (l != null) {
183 return l.longValue() >> r;
184 }
185 return toBigInteger(left).shiftRight(r);
186 }
187
188
189
190
191
192
193
194
195 @Override
196 public Object shiftRightUnsigned(final Object left, final Object right) {
197 if (left == null && right == null) {
198 return controlNullNullOperands(JexlOperator.SHIFTRIGHTU);
199 }
200 final int r = toInteger(right);
201 Number l = asIntNumber(left);
202 if (l != null) {
203 return l.intValue() >>> r;
204 }
205 l = castLongNumber(left);
206 if (l != null) {
207 return l.longValue() >>> r;
208 }
209 final BigInteger bl = toBigInteger(left);
210 return bl.signum() < 0? bl.negate().shiftRight(r) : bl.shiftRight(r);
211 }
212
213
214
215
216
217
218
219
220 @Override
221 public Object xor(final Object left, final Object right) {
222 final Number l = asLongNumber(left);
223 final Number r = asLongNumber(right);
224 if (l != null && r != null) {
225 return narrowLong(left, right, l.longValue() ^ r.longValue());
226 }
227 return toBigInteger(left).xor(toBigInteger(right));
228 }
229
230 }