1 21 22 package org.apache.derby.iapi.types; 23 24 import org.apache.derby.iapi.error.StandardException; 25 import org.apache.derby.iapi.types.NumberDataValue; 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 import org.apache.derby.iapi.services.io.Storable; 28 import org.apache.derby.iapi.types.Orderable; 29 import org.apache.derby.iapi.types.DataValueDescriptor; 30 import org.apache.derby.iapi.types.TypeId; 31 import org.apache.derby.iapi.reference.SQLState; 32 import org.apache.derby.iapi.reference.Limits; 33 34 import org.apache.derby.iapi.types.*; 35 36 44 public abstract class NumberDataType extends DataType 45 implements NumberDataValue 46 { 47 50 static DataValueDescriptor ZERO_DECIMAL; 51 52 55 static Comparable MINLONG_MINUS_ONE; 56 59 static Comparable MAXLONG_PLUS_ONE; 60 61 67 public final NumberDataValue absolute(NumberDataValue result) 68 throws StandardException 69 { 70 if(isNegative()) 71 return minus(result); 72 73 if(result == null) 74 result = (NumberDataType)getNewNull(); 75 76 result.setValue(this); 77 return result; 78 } 79 80 88 89 public NumberDataValue sqrt(NumberDataValue result) 90 throws StandardException 91 { 92 if(result == null) 93 { 94 result = (NumberDataValue)getNewNull(); 95 } 96 97 if(this.isNull()) 98 { 99 result.setToNull(); 100 return result; 101 } 102 103 double doubleValue = getDouble(); 104 105 if( this.isNegative() ) 106 { 107 if( (new Double (doubleValue)).equals(new Double (-0.0d)) ) 108 { 109 doubleValue = 0.0d; 110 } 111 else 112 { 113 throw StandardException.newException( SQLState.LANG_SQRT_OF_NEG_NUMBER, this); 114 } 115 } 116 117 result.setValue( Math.sqrt(doubleValue) ); 118 return result; 119 } 120 121 133 134 public NumberDataValue plus(NumberDataValue addend1, 135 NumberDataValue addend2, 136 NumberDataValue result) 137 throws StandardException 138 { 139 if (result == null) 140 { 141 result = (NumberDataValue) getNewNull(); 142 } 143 144 if (addend1.isNull() || addend2.isNull()) 145 { 146 result.setToNull(); 147 return result; 148 } 149 int addend1Int = addend1.getInt(); 150 int addend2Int = addend2.getInt(); 151 152 int resultValue = addend1Int + addend2Int; 153 154 162 if ((addend1Int < 0) == (addend2Int < 0)) 163 { 164 168 if ((addend1Int < 0) != (resultValue < 0)) 169 { 170 throw outOfRange(); 171 } 172 } 173 174 result.setValue(resultValue); 175 176 return result; 177 } 178 190 191 public NumberDataValue minus(NumberDataValue left, 192 NumberDataValue right, 193 NumberDataValue result) 194 throws StandardException 195 { 196 if (result == null) 197 { 198 result = (NumberDataValue) getNewNull(); 199 } 200 201 if (left.isNull() || right.isNull()) 202 { 203 result.setToNull(); 204 return result; 205 } 206 207 int diff = left.getInt() - right.getInt(); 208 209 217 if ((left.getInt() < 0) != (right.getInt() < 0)) 218 { 219 223 if ((left.getInt() < 0) != (diff < 0)) 224 { 225 throw outOfRange(); 226 } 227 } 228 229 result.setValue(diff); 230 231 return result; 232 } 233 234 248 249 public NumberDataValue divide(NumberDataValue dividend, 250 NumberDataValue divisor, 251 NumberDataValue result) 252 throws StandardException 253 { 254 if (result == null) 255 { 256 result = (NumberDataValue) getNewNull(); 257 } 258 259 if (dividend.isNull() || divisor.isNull()) 260 { 261 result.setToNull(); 262 return result; 263 } 264 265 266 int intDivisor = divisor.getInt(); 267 if (intDivisor == 0) 268 { 269 throw StandardException.newException(SQLState.LANG_DIVIDE_BY_ZERO); 270 } 271 272 result.setValue(dividend.getInt() / intDivisor); 273 return result; 274 } 275 276 279 public NumberDataValue divide(NumberDataValue dividend, 280 NumberDataValue divisor, 281 NumberDataValue result, 282 int scale) 283 throws StandardException 284 { 285 return divide(dividend, divisor, result); 286 } 287 288 public NumberDataValue mod(NumberDataValue dividend, 289 NumberDataValue divisor, 290 NumberDataValue result) 291 throws StandardException { 292 if (SanityManager.DEBUG) 293 SanityManager.NOTREACHED(); 294 return null; 295 } 296 297 298 public final int compare(DataValueDescriptor arg) throws StandardException 299 { 300 303 if (typePrecedence() < arg.typePrecedence()) 304 { 305 return - (arg.compare(this)); 306 } 307 308 309 boolean thisNull, otherNull; 310 311 thisNull = this.isNull(); 312 otherNull = arg.isNull(); 313 314 320 if (thisNull || otherNull) 321 { 322 if (!thisNull) return -1; 324 if (!otherNull) return 1; 326 return 0; 327 } 328 329 return typeCompare(arg); 330 331 } 332 337 protected abstract int typeCompare(DataValueDescriptor arg) throws StandardException; 338 339 342 public final boolean compare(int op, 343 DataValueDescriptor other, 344 boolean orderedNulls, 345 boolean unknownRV) 346 throws StandardException 347 { 348 if (!orderedNulls) { 350 if (this.isNull() || other.isNull()) 351 return unknownRV; 352 } 353 354 355 return super.compare(op, other, orderedNulls, unknownRV); 356 } 357 358 365 protected abstract boolean isNegative(); 366 367 373 public void setValue(short theValue) 374 throws StandardException 375 { 376 setValue((int) theValue); 377 } 378 379 385 public void setValue(byte theValue) 386 throws StandardException 387 { 388 setValue((int) theValue); 389 } 390 397 public void setValue(Number theValue) throws StandardException 398 { 399 if (objectNull(theValue)) 400 return; 401 402 if (SanityManager.ASSERT) 403 { 404 if (!(theValue instanceof java.lang.Integer )) 405 SanityManager.THROWASSERT("NumberDataType.setValue(Number) passed a " + theValue.getClass()); 406 } 407 408 setValue(theValue.intValue()); 409 } 410 411 416 void setObject(Object theValue) throws StandardException 417 { 418 setValue(((Integer ) theValue).intValue()); 419 } 420 421 425 public void setBigDecimal(Number bigDecimal) throws StandardException 426 { 427 if (objectNull(bigDecimal)) 428 return; 429 430 Comparable bdc = (Comparable ) bigDecimal; 431 432 433 435 if ( (bdc.compareTo(NumberDataType.MINLONG_MINUS_ONE) == 1) 436 && (bdc.compareTo(NumberDataType.MAXLONG_PLUS_ONE) == -1)) { 437 438 setValue(bigDecimal.longValue()); 439 } else { 440 441 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, getTypeName()); 442 } 443 } 444 445 448 public int typeToBigDecimal() 449 { 450 return java.sql.Types.BIGINT; 451 } 452 457 public int getDecimalValuePrecision() 458 { 459 return -1; 460 } 461 462 467 public int getDecimalValueScale() 468 { 469 return -1; 470 } 471 472 protected final boolean objectNull(Object o) 473 { 474 if (o == null) 475 { 476 restoreToNull(); 477 return true; 478 } 479 return false; 480 } 481 482 487 public static float normalizeREAL(float v) throws StandardException 488 { 489 if ( (Float.isNaN(v) || Float.isInfinite(v)) || 490 ((v < Limits.DB2_SMALLEST_REAL) || (v > Limits.DB2_LARGEST_REAL)) || 491 ((v > 0) && (v < Limits.DB2_SMALLEST_POSITIVE_REAL)) || 492 ((v < 0) && (v > Limits.DB2_LARGEST_NEGATIVE_REAL)) ) 493 { 494 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, TypeId.REAL_NAME); 495 } 496 if (v == 0.0f) v = 0.0f; 498 499 return v; 500 } 501 502 512 public static float normalizeREAL(double v) throws StandardException 513 { 514 if ( (Double.isNaN(v) || Double.isInfinite(v)) || 516 ((v < Limits.DB2_SMALLEST_REAL) || (v > Limits.DB2_LARGEST_REAL)) || 517 ((v > 0) && (v < Limits.DB2_SMALLEST_POSITIVE_REAL)) || 518 ((v < 0) && (v > Limits.DB2_LARGEST_NEGATIVE_REAL)) ) 519 { 520 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, TypeId.REAL_NAME); 521 } 522 if (v == 0.0d) v = 0.0d; 524 525 return (float)v; 526 } 527 528 533 public static double normalizeDOUBLE(double v) throws StandardException 534 { 535 if ( (Double.isNaN(v) || Double.isInfinite(v)) || 536 ((v < Limits.DB2_SMALLEST_DOUBLE) || (v > Limits.DB2_LARGEST_DOUBLE)) || 537 ((v > 0) && (v < Limits.DB2_SMALLEST_POSITIVE_DOUBLE)) || 538 ((v < 0) && (v > Limits.DB2_LARGEST_NEGATIVE_DOUBLE)) ) 539 { 540 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, TypeId.DOUBLE_NAME); 541 } 542 if (v == 0.0d) v = 0.0d; 544 545 return v; 546 } 547 548 549 } 550 551 | Popular Tags |