Line 0
Link Here
|
|
|
1 |
package org.apache.poi.ss.formula.functions; |
2 |
|
3 |
import org.apache.poi.ss.formula.OperationEvaluationContext; |
4 |
import org.apache.poi.ss.formula.eval.ErrorEval; |
5 |
import org.apache.poi.ss.formula.eval.OperandResolver; |
6 |
import org.apache.poi.ss.formula.eval.StringEval; |
7 |
import org.apache.poi.ss.formula.eval.ValueEval; |
8 |
|
9 |
import java.math.BigInteger; |
10 |
|
11 |
/** |
12 |
* Implementation for Excel HEX2DEC() function.<p/> |
13 |
* <p/> |
14 |
* <b>Syntax</b>:<br/> <b>HEX2DEC </b>(<b>number</b>)<br/> |
15 |
* <p/> |
16 |
* Converts a hexadecimal number to decimal. |
17 |
* <p/> |
18 |
* Number is the hexadecimal number you want to convert. Number cannot contain more than 10 characters (40 bits). |
19 |
* The most significant bit of number is the sign bit. |
20 |
* The remaining 39 bits are magnitude bits. Negative numbers are represented using two's-complement notation. |
21 |
* Remark |
22 |
* If number is not a valid hexadecimal number, HEX2DEC returns the #NUM! error value. |
23 |
* |
24 |
* @author cedric dot walter @ gmail dot com |
25 |
*/ |
26 |
public class Hex2Dec extends Fixed1ArgFunction implements FreeRefFunction { |
27 |
|
28 |
public static final FreeRefFunction instance = new Hex2Dec(); |
29 |
|
30 |
@Override |
31 |
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { |
32 |
String number = OperandResolver.coerceValueToString(numberVE); |
33 |
if (number.length() > 10) { |
34 |
return ErrorEval.NUM_ERROR; |
35 |
} |
36 |
|
37 |
String unsigned = ""; |
38 |
boolean isPositive = false; |
39 |
boolean isNegative = false; |
40 |
if (number.length() < 10) { |
41 |
unsigned = number; |
42 |
isPositive = true; |
43 |
} else { |
44 |
//remove sign bit |
45 |
unsigned = number.substring(1); |
46 |
isNegative = |
47 |
number.startsWith("8") || number.startsWith("9") || |
48 |
number.startsWith("A") || number.startsWith("B") || |
49 |
number.startsWith("C") || number.startsWith("D") || |
50 |
number.startsWith("E") || number.startsWith("F"); |
51 |
} |
52 |
|
53 |
String result = ""; |
54 |
if (isPositive) { |
55 |
try { |
56 |
result = String.valueOf(Integer.parseInt(unsigned, 16)); |
57 |
} catch (NumberFormatException ee) { |
58 |
// number is not a valid hexadecimal number |
59 |
return ErrorEval.NUM_ERROR; |
60 |
} |
61 |
} else { |
62 |
if (isNegative) { |
63 |
BigInteger temp = new BigInteger(unsigned, 16); |
64 |
BigInteger subtract = BigInteger.ONE.shiftLeft(unsigned.length() * 4); |
65 |
temp = temp.subtract(subtract); |
66 |
result = String.valueOf(temp.longValue()); |
67 |
} else { |
68 |
try { |
69 |
result = String.valueOf(Integer.parseInt(unsigned, 16)); |
70 |
} catch (NumberFormatException ee) { |
71 |
// number is not a valid hexadecimal number |
72 |
return ErrorEval.NUM_ERROR; |
73 |
} |
74 |
} |
75 |
} |
76 |
|
77 |
return new StringEval(result); |
78 |
} |
79 |
|
80 |
@Override |
81 |
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { |
82 |
if (args.length != 1) { |
83 |
return ErrorEval.VALUE_INVALID; |
84 |
} |
85 |
return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); |
86 |
} |
87 |
} |