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