129 lines
5.5 KiB
Java
129 lines
5.5 KiB
Java
/* ====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
==================================================================== */
|
|
|
|
package org.apache.poi.ss.formula.functions;
|
|
|
|
import org.apache.poi.ss.formula.OperationEvaluationContext;
|
|
import org.apache.poi.ss.formula.eval.*;
|
|
|
|
/**
|
|
* Implementation for Excel DELTA() function.<p/>
|
|
* <p/>
|
|
* <b>Syntax</b>:<br/> <b>DEC2HEX </b>(<b>number</b>,<b>places</b> )<br/>
|
|
* <p/>
|
|
* Converts a decimal number to hexadecimal.
|
|
*
|
|
* The decimal integer you want to convert. If number is negative, places is ignored
|
|
* and this function returns a 10-character (40-bit) hexadecimal number in which the
|
|
* most significant bit is the sign bit. The remaining 39 bits are magnitude bits.
|
|
* Negative numbers are represented using two's-complement notation.
|
|
*
|
|
* <ul>
|
|
* <li>If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value.</li>
|
|
* <li>If number is nonnumeric, this function returns the #VALUE! error value.</li>
|
|
* </ul>
|
|
*
|
|
* <h2>places</h2>
|
|
*
|
|
* The number of characters to use. The places argument is useful for padding the
|
|
* return value with leading 0s (zeros).
|
|
*
|
|
* <ul>
|
|
* <li>If this argument is omitted, this function uses the minimum number of characters necessary.</li>
|
|
* <li>If this function requires more than places characters, it returns the #NUM! error value.</li>
|
|
* <li>If this argument is nonnumeric, this function returns the #VALUE! error value.</li>
|
|
* <li>If this argument is negative, this function returns the #NUM! error value.</li>
|
|
* <li>If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point.</li>
|
|
* </ul>
|
|
*
|
|
* @author cedric dot walter @ gmail dot com
|
|
*/
|
|
public final class Dec2Hex extends Var1or2ArgFunction implements FreeRefFunction {
|
|
|
|
private final static long MIN_VALUE = new Long("-549755813888").longValue();
|
|
private final static long MAX_VALUE = new Long("549755813887").longValue();
|
|
private final static int DEFAULT_PLACES_VALUE = 10;;
|
|
|
|
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval number, ValueEval places) {
|
|
ValueEval veText1;
|
|
try {
|
|
veText1 = OperandResolver.getSingleValue(number, srcRowIndex, srcColumnIndex);
|
|
} catch (EvaluationException e) {
|
|
return e.getErrorEval();
|
|
}
|
|
String strText1 = OperandResolver.coerceValueToString(veText1);
|
|
Double number1 = OperandResolver.parseDouble(strText1);
|
|
|
|
//If this number argument is non numeric, this function returns the #VALUE! error value.
|
|
if (number1 == null) {
|
|
return ErrorEval.VALUE_INVALID;
|
|
}
|
|
|
|
//If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value.
|
|
if (number1.longValue() < MIN_VALUE || number1.longValue() > MAX_VALUE) {
|
|
return ErrorEval.NUM_ERROR;
|
|
}
|
|
|
|
int placesNumber = 0;
|
|
if (number1 < 0) {
|
|
placesNumber = DEFAULT_PLACES_VALUE;
|
|
} else {
|
|
ValueEval placesValueEval;
|
|
try {
|
|
placesValueEval = OperandResolver.getSingleValue(places, srcRowIndex, srcColumnIndex);
|
|
} catch (EvaluationException e) {
|
|
return e.getErrorEval();
|
|
}
|
|
String placesStr = OperandResolver.coerceValueToString(placesValueEval);
|
|
Double placesNumberDouble = OperandResolver.parseDouble(placesStr);
|
|
|
|
//non numeric value
|
|
if (placesNumberDouble == null) {
|
|
return ErrorEval.VALUE_INVALID;
|
|
}
|
|
|
|
//If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point.
|
|
placesNumber = placesNumberDouble.intValue();
|
|
|
|
if (placesNumber < 0) {
|
|
return ErrorEval.NUM_ERROR;
|
|
}
|
|
}
|
|
|
|
String hex = "";
|
|
if (placesNumber != 0) {
|
|
hex = String.format("%0"+placesNumber+"X", number1.intValue() & 0x0FFFFF);
|
|
}
|
|
else {
|
|
hex = Integer.toHexString(number1.intValue());
|
|
}
|
|
|
|
return new StringEval(hex.toUpperCase());
|
|
}
|
|
|
|
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
return this.evaluate(srcRowIndex, srcColumnIndex, arg0, new StringEval(String.valueOf(DEFAULT_PLACES_VALUE)));
|
|
}
|
|
|
|
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
|
|
if (args.length != 2) {
|
|
return ErrorEval.VALUE_INVALID;
|
|
}
|
|
return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]);
|
|
}
|
|
|
|
} |