001 /* 002 * JBoss, Home of Professional Open Source. 003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors 004 * as indicated by the @author tags. See the copyright.txt file in the 005 * distribution for a full listing of individual contributors. 006 * 007 * This is free software; you can redistribute it and/or modify it 008 * under the terms of the GNU Lesser General Public License as 009 * published by the Free Software Foundation; either version 2.1 of 010 * the License, or (at your option) any later version. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this software; if not, write to the Free 019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 021 */ 022 package org.jboss.dna.common.math; 023 024 import java.math.BigDecimal; 025 import java.util.Comparator; 026 import java.util.Random; 027 import java.util.concurrent.TimeUnit; 028 029 public class DurationOperations implements MathOperations<Duration>, Comparator<Duration> { 030 031 public Class<Duration> getOperandClass() { 032 return Duration.class; 033 } 034 035 public Duration add( Duration value1, Duration value2 ) { 036 if (value1 == null) return value2 != null ? value2 : createZeroValue(); 037 if (value2 == null) return value1; 038 return value1.add(value2); 039 } 040 041 public Duration subtract( Duration value1, Duration value2 ) { 042 if (value1 == null) return negate(value2); 043 if (value2 == null) return value1; 044 return value1.subtract(value2); 045 } 046 047 public Duration multiply( Duration value1, Duration value2 ) { 048 if (value1 == null || value2 == null) return createZeroValue(); 049 return value1.multiply(value2.longValue()); 050 } 051 052 public double divide( Duration value1, Duration value2 ) { 053 if (value1 == null || value2 == null) throw new IllegalArgumentException(); 054 return value1.divide(value2); 055 } 056 057 public Duration negate( Duration value ) { 058 if (value == null) return createZeroValue(); 059 return value.multiply(value.longValue() * -1); 060 } 061 062 public Duration increment( Duration value ) { 063 if (value == null) return createZeroValue(); 064 return value.add(1l, TimeUnit.NANOSECONDS); 065 } 066 067 public Duration maximum( Duration value1, Duration value2 ) { 068 if (value1 == null) return value2; 069 if (value2 == null) return value1; 070 return new Duration(Math.max(value1.longValue(), value2.longValue())); 071 } 072 073 public Duration minimum( Duration value1, Duration value2 ) { 074 if (value1 == null) return value2; 075 if (value2 == null) return value1; 076 return new Duration(Math.min(value1.longValue(), value2.longValue())); 077 } 078 079 public int compare( Duration value1, Duration value2 ) { 080 if (value1 == null) return value2 != null ? -1 : 0; 081 if (value2 == null) return 1; 082 return value1.compareTo(value2); 083 } 084 085 public BigDecimal asBigDecimal( Duration value ) { 086 return value != null ? value.toBigDecimal() : null; 087 } 088 089 public Duration fromBigDecimal( BigDecimal value ) { 090 return value != null ? new Duration(value.longValue()) : null; 091 } 092 093 public Duration createZeroValue() { 094 return new Duration(0l); 095 } 096 097 public Duration create( int value ) { 098 return new Duration(value); 099 } 100 101 public Duration create( long value ) { 102 return new Duration(value); 103 } 104 105 public Duration create( double value ) { 106 return new Duration((long)value); 107 } 108 109 public double sqrt( Duration value ) { 110 return Math.sqrt(value.longValue()); 111 } 112 113 public Comparator<Duration> getComparator() { 114 return this; 115 } 116 117 public Duration random( Duration minimum, Duration maximum, Random rng ) { 118 Duration difference = subtract(maximum, minimum); 119 return new Duration(minimum.getDuratinInNanoseconds() + rng.nextInt(difference.intValue())); 120 } 121 122 public double doubleValue( Duration value ) { 123 return value.doubleValue(); 124 } 125 126 public float floatValue( Duration value ) { 127 return value.floatValue(); 128 } 129 130 public int intValue( Duration value ) { 131 return value.intValue(); 132 } 133 134 public long longValue( Duration value ) { 135 return value.longValue(); 136 } 137 138 public short shortValue( Duration value ) { 139 return value.shortValue(); 140 } 141 142 public int getExponentInScientificNotation( Duration value ) { 143 long v = Math.abs(value.getDuratinInNanoseconds()); 144 int exp = 0; 145 if (v > 1l) { 146 while (v >= 10l) { 147 v /= 10l; 148 ++exp; 149 } 150 } 151 return exp; 152 } 153 154 public Duration roundUp( Duration durationValue, int decimalShift ) { 155 long value = durationValue.longValue(); 156 if (value == 0) return new Duration(0l); 157 if (decimalShift >= 0) return durationValue; 158 long shiftedValueP5 = Math.abs(value); 159 for (int i = 0; i != (-decimalShift - 1); ++i) 160 shiftedValueP5 /= 10l; 161 shiftedValueP5 += 5l; 162 long shiftedValue = shiftedValueP5 / 10l; 163 if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue; 164 shiftedValue *= Long.signum(value); 165 for (int i = 0; i != -decimalShift; ++i) 166 shiftedValue *= 10l; 167 return new Duration(shiftedValue); 168 } 169 170 public Duration roundDown( Duration durationValue, int decimalShift ) { 171 long value = durationValue.longValue(); 172 if (value == 0) return new Duration(0l); 173 if (decimalShift >= 0) return durationValue; 174 long shiftedValue = Math.abs(value); 175 for (int i = 0; i != -decimalShift; ++i) 176 shiftedValue /= 10l; 177 shiftedValue *= Long.signum(value); 178 for (int i = 0; i != -decimalShift; ++i) 179 shiftedValue *= 10l; 180 return new Duration(shiftedValue); 181 } 182 183 public Duration keepSignificantFigures( Duration value, int numSigFigs ) { 184 if (numSigFigs < 0) return value; 185 if (numSigFigs == 0) return new Duration(0l); 186 int currentExp = getExponentInScientificNotation(value); 187 int decimalShift = -currentExp + numSigFigs - 1; 188 return roundUp(value, decimalShift); 189 } 190 }