public Number evaluate( final Number number1, final Number number2 ) throws EvaluationException { final BigDecimal bd1 = NumberUtil.getAsBigDecimal( number1 ); final BigDecimal bd2 = NumberUtil.getAsBigDecimal( number2 ); return NumberUtil.divide( bd1, bd2 ); }
protected long computeDays( final ParameterCallback parameters, final TypeRegistry typeRegistry ) throws EvaluationException { final Number date1 = typeRegistry.convertToNumber( parameters.getType( 0 ), parameters.getValue( 0 ) ); final Number date2 = typeRegistry.convertToNumber( parameters.getType( 1 ), parameters.getValue( 1 ) ); final BigDecimal dn1 = NumberUtil.performIntRounding( NumberUtil.getAsBigDecimal( date1 ) ); final BigDecimal dn2 = NumberUtil.performIntRounding( NumberUtil.getAsBigDecimal( date2 ) ); return dn2.longValue() - dn1.longValue(); }
public static BigDecimal divide(final BigDecimal bd1, final BigDecimal bd2) throws EvaluationException { if (bd2.signum() == 0) { // prevent a division by zero .. throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARITHMETIC_VALUE); } final BigDecimal divide = bd1.divide(bd2, LibFormulaBoot.GLOBAL_SCALE, BigDecimal.ROUND_HALF_UP); return NumberUtil.removeTrailingZeros(divide); } }
private BigDecimal compute( final Number value, final BigDecimal computedResult ) { if ( value == null ) { // no-op .. return computedResult; } return computedResult.add( NumberUtil.getAsBigDecimal( value ) ); } }
public TypeValuePair evaluate( final FormulaContext context, final ParameterCallback parameters ) throws EvaluationException { if ( parameters.getParameterCount() != 1 ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE ); } final TypeRegistry typeRegistry = context.getTypeRegistry(); final Number n = typeRegistry.convertToNumber( parameters.getType( 0 ), parameters.getValue( 0 ) ); if ( n == null ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE ); } // calculation is as follows // time * 24 so that we get the full hours (which we remove later) final BigDecimal bd = NumberUtil.getAsBigDecimal( n ); final BigDecimal hours = bd.multiply( HOURS ); final BigDecimal dayAndHoursAsInt = new BigDecimal( NumberUtil.performIntRounding( hours ).intValue() ); final BigDecimal minutesFraction = hours.subtract( dayAndHoursAsInt ); // Multiply the minutes with 60 to get the minutes as ints final BigDecimal minutes = minutesFraction.multiply( MINUTES ); // Fix for PRD-5499, contributed by Lionel Elie Mamane // final BigDecimal minutesAsInt = minutes.setScale( 0, BigDecimal.ROUND_HALF_UP ); final BigDecimal minutesAsInt = NumberUtil.performMinuteRounding( minutes ); return new TypeValuePair( NumberType.GENERIC_NUMBER, minutesAsInt ); } }
public TypeValuePair evaluateTyped() { try { final TypeValuePair typeValuePair = rootReference.evaluate(); if ( typeValuePair == null ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_NA_VALUE ); } final Type type = typeValuePair.getType(); if ( type.isFlagSet( Type.ERROR_TYPE ) ) { logger.debug( "Error: " + typeValuePair.getValue() ); } else if ( type.isFlagSet( Type.ARRAY_TYPE ) ) { final Object value = typeValuePair.getValue(); if ( value instanceof ArrayCallback ) { return new TypeValuePair( type, new StaticArrayCallback( (ArrayCallback) value ) ); } } else { final Object value = typeValuePair.getValue(); if ( value instanceof Number ) { return new TypeValuePair( type, NumberUtil.performTuneRounding( NumberUtil.getAsBigDecimal( (Number) value ) ) ); } } return typeValuePair; } catch ( EvaluationException ee ) { return new TypeValuePair( ErrorType.TYPE, ee.getErrorValue() ); } catch ( Exception e ) { logger.warn( "Evaluation failed unexpectedly: ", e ); return new TypeValuePair( ErrorType.TYPE, LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE ); } }
public static Date getJavaDate( final BigDecimal date, final boolean excelBugCompatible, final int zeroDate ) { int correction = 1; final BigDecimal wholeDays = NumberUtil.performIntRounding( date ); final int wholeDaysInt = wholeDays.intValue() - zeroDate; if ( excelBugCompatible ) { // if we deal with a date that is after the 28th februar, adjust the date by one to handle the fact // that excel thinks the 29th February 1900 exists. // by tuning this variable, we map the int-value for the 29th to the next day. if ( wholeDaysInt > 59 ) { correction = 0; } } final BigDecimal fractionNum = date.subtract( wholeDays ); final BigDecimal fraction = fractionNum.multiply( DAY_MILLISECONDS ); // the use of the calendar could be probably removed, as there is no magic in converting // a running number into a date. final GregorianCalendar calendar = new GregorianCalendar( 1900, 0, wholeDaysInt + correction ); calendar.set( Calendar.MILLISECOND, fraction.setScale( 0, BigDecimal.ROUND_HALF_UP ).intValue() ); return calendar.getTime(); } }
@Test public void testPerformMinuteRounding() { BigDecimal[][] test = { // =MINUTE(timevalue("00:00:59")) new BigDecimal[] { new BigDecimal( 0.9833333333333333333333333333333333333760 ), new BigDecimal( 0 ) }, // =MINUTE(timevalue("00:01:00")) =MINUTE("00:01:00") =MINUTE(1/(24*60)) new BigDecimal[] { new BigDecimal( 0.9999999999999999999999999999999999999360 ), new BigDecimal( 1 ) }, // =MINUTE(timevalue("00:01:59")) new BigDecimal[] { new BigDecimal( 1.9833333333333333333333333333333333333120 ), new BigDecimal( 1 ) }, // =MINUTE(timevalue("00:07:00")) new BigDecimal[] { new BigDecimal( 6.9999999999999999999999999999999999999840 ), new BigDecimal( 7 ) }, // =MINUTE(timevalue("00:09:00")) new BigDecimal[] { new BigDecimal( 9.0000000000000000000000000000000000000000 ), new BigDecimal( 9 ) }, // =MINUTE(timevalue("00:11:00")) new BigDecimal[] { new BigDecimal( 11.9833333333333333333333333333333333333920 ), new BigDecimal( 11 ) }, // =MINUTE(timevalue("00:23:00")) new BigDecimal[] { new BigDecimal( 22.9999999999999999999999999999999999999680 ), new BigDecimal( 23 ) }, // =MINUTE(timevalue("00:28:59")) new BigDecimal[] { new BigDecimal( 28.9833333333333333333333333333333333333120 ), new BigDecimal( 28 ) } }; for ( BigDecimal[] bigDecimal : test ) { BigDecimal result = NumberUtil.performMinuteRounding( bigDecimal[ 0 ] ); assertEquals( bigDecimal[ 1 ], result ); } } }
private BigDecimal compute(final Number value, final BigDecimal computedResult) { if (value == null) { // no-op .. return computedResult; } return computedResult.add(NumberUtil.getAsBigDecimal(value)); } }
if (value instanceof Number) return new TypeValuePair(type, NumberUtil.performTuneRounding(NumberUtil.getAsBigDecimal((Number) value)));
public static Date getJavaDate(final BigDecimal date, final boolean excelBugCompatible, final int zeroDate) { int correction = 1; final BigDecimal wholeDays = NumberUtil.performIntRounding(date); final int wholeDaysInt = wholeDays.intValue() - zeroDate; if (excelBugCompatible) { // if we deal with a date that is after the 28th februar, adjust the date by one to handle the fact // that excel thinks the 29th February 1900 exists. // by tuning this variable, we map the int-value for the 29th to the next day. if (wholeDaysInt > 59) { correction = 0; } } final BigDecimal fractionNum = date.subtract(wholeDays); final BigDecimal fraction = fractionNum.multiply(DAY_MILLISECONDS); // the use of the calendar could be probably removed, as there is no magic in converting // a running number into a date. final GregorianCalendar calendar = new GregorianCalendar(1900, 0, wholeDaysInt + correction); calendar.set(Calendar.MILLISECOND, fraction.setScale(0, BigDecimal.ROUND_HALF_UP).intValue()); return calendar.getTime(); } }
public TypeValuePair evaluate( final FormulaContext context, final ParameterCallback parameters ) throws EvaluationException { if ( parameters.getParameterCount() != 1 ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE ); } final TypeRegistry typeRegistry = context.getTypeRegistry(); final Number n = typeRegistry.convertToNumber( parameters.getType( 0 ), parameters.getValue( 0 ) ); if ( n == null ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE ); } final BigDecimal bd = NumberUtil.getAsBigDecimal( n ); final BigDecimal day = new BigDecimal( NumberUtil.performIntRounding( bd ).intValue() ); final BigDecimal dayFraction = bd.subtract( day ); final BigDecimal hourAndMinutesVal = dayFraction.multiply( HOUR_24 ); final BigDecimal hours = NumberUtil.performIntRounding( hourAndMinutesVal ); return new TypeValuePair( NumberType.GENERIC_NUMBER, hours ); } }
public Number evaluate( final Number number1, final Number number2 ) { if ( ( number1 instanceof Integer || number1 instanceof Short ) && ( number2 instanceof Integer || number2 instanceof Short ) ) { return new BigDecimal( number1.longValue() + number2.longValue() ); } final BigDecimal bd1 = NumberUtil.getAsBigDecimal( number1 ); final BigDecimal bd2 = NumberUtil.getAsBigDecimal( number2 ); return bd1.add( bd2 ); }
public Number evaluate(final Number number1, final Number number2) throws EvaluationException { final BigDecimal bd1 = NumberUtil.getAsBigDecimal(number1); final BigDecimal bd2 = NumberUtil.getAsBigDecimal(number2); return NumberUtil.divide(bd1, bd2); }
public static BigDecimal divide( final BigDecimal bd1, final BigDecimal bd2 ) throws EvaluationException { if ( bd2.signum() == 0 ) { // prevent a division by zero .. throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_ARITHMETIC_VALUE ); } final BigDecimal divide = bd1.divide( bd2, LibFormulaBoot.GLOBAL_SCALE, BigDecimal.ROUND_HALF_UP ); return NumberUtil.removeTrailingZeros( divide ); } }
public static BigDecimal normalizeDate( final BigDecimal fromSerialDate, final Type toType ) { if ( fromSerialDate == null ) { throw new IllegalArgumentException(); } if ( toType == null ) { throw new IllegalArgumentException(); } if ( toType.isFlagSet( Type.TIME_TYPE ) ) { final BigDecimal o = fromSerialDate.setScale( LibFormulaBoot.GLOBAL_SCALE, BigDecimal.ROUND_UP ); return o.subtract( new BigDecimal( o.intValue() ) ); // only return the decimal part // final Double d = new Double(fromSerialDate.doubleValue() // - fromSerialDate.intValue()); // return d; } else if ( toType.isFlagSet( Type.DATE_TYPE ) ) { return NumberUtil.performIntRounding( fromSerialDate ); } else { // else it must be date-time, so return it unchanged .. return fromSerialDate; } }
public TypeValuePair evaluate( final FormulaContext context, final ParameterCallback parameters ) throws EvaluationException { if ( parameters.getParameterCount() != 1 ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE ); } final TypeRegistry typeRegistry = context.getTypeRegistry(); final Number n = typeRegistry.convertToNumber( parameters.getType( 0 ), parameters.getValue( 0 ) ); if ( n == null ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE ); } // calculation is as follows // time * 24 so that we get the full hours (which we remove later) final BigDecimal bd = NumberUtil.getAsBigDecimal( n ); final BigDecimal hours = bd.multiply( MINUTES_PER_DAY ); final BigDecimal dayAndHoursAsInt = NumberUtil.performIntRounding( hours ); final BigDecimal minutesFraction = hours.subtract( dayAndHoursAsInt ); // Multiply the minutes with 60 to get the minutes as ints final BigDecimal seconds = minutesFraction.multiply( SECONDS ); final BigDecimal secondsAsInt = NumberUtil.performIntRounding( seconds ); return new TypeValuePair( NumberType.GENERIC_NUMBER, secondsAsInt ); } }
public Number evaluate(final Number number1, final Number number2) { if ((number1 instanceof Integer || number1 instanceof Short) && (number2 instanceof Integer || number2 instanceof Short)) { return new BigDecimal (number1.longValue() + number2.longValue()); } final BigDecimal bd1 = NumberUtil.getAsBigDecimal(number1); final BigDecimal bd2 = NumberUtil.getAsBigDecimal(number2); return bd1.add(bd2); }
public TypeValuePair evaluate( final FormulaContext context, final ParameterCallback parameters ) throws EvaluationException { final TypeValuePair sum = sumFunction.evaluate( context, parameters ); final Number n = context.getTypeRegistry().convertToNumber( sum.getType(), sum.getValue() ); if ( n == null ) { throw EvaluationException.getInstance( LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE ); } final BigDecimal divident = NumberUtil.getAsBigDecimal( n ); final BigDecimal divisor = new BigDecimal( parameters.getParameterCount() ); final BigDecimal avg = NumberUtil.divide( divident, divisor ); return new TypeValuePair( NumberType.GENERIC_NUMBER, avg ); } }
public static BigDecimal performTuneRounding( BigDecimal n ) { try { // no need to go further if the value is already an integer n.setScale( ROUND_SCALE ); return n; } catch ( ArithmeticException e ) { //ignore and continue } final BigDecimal round; if ( n.signum() < 0 ) { n = n.subtract( INT_TEST_DELTA ); round = n.setScale( ROUND_SCALE, BigDecimal.ROUND_UP ); } else { n = n.add( INT_TEST_DELTA ); round = n.setScale( ROUND_SCALE, BigDecimal.ROUND_DOWN ); } if ( n.compareTo( round ) == 0 ) { return n; } return NumberUtil.removeTrailingZeros( round ); }