📄 binarydecimal.java
字号:
throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "SMALLINT"); } /* ** DECIMAL arithmetic methods. */ /** * This method implements the + operator for DECIMAL. * * @param addend1 One of the addends * @param addend2 The other addend * @param result The result of a previous call to this method, null * if not called yet * * @return A SQLDecimal containing the result of the addition * * @exception StandardException Thrown on error */ public final NumberDataValue plus(NumberDataValue addend1, NumberDataValue addend2, NumberDataValue result) throws StandardException { if (result == null) { result = (NumberDataValue) getNewNull(); } if (addend1.isNull() || addend2.isNull()) { result.setToNull(); return result; } return plusNN(addend1, addend2, result); } /* (non-Javadoc) * @see org.apache.derby.iapi.types.NumberDataValue#times(org.apache.derby.iapi.types.NumberDataValue, org.apache.derby.iapi.types.NumberDataValue, org.apache.derby.iapi.types.NumberDataValue) */ public final NumberDataValue times(NumberDataValue left, NumberDataValue right, NumberDataValue result) throws StandardException { if (result == null) { result = (NumberDataValue) getNewNull(); } if (left.isNull() || right.isNull()) { result.setToNull(); return result; } return timesNN(left, right, result); } public NumberDataValue divide(NumberDataValue dividend, NumberDataValue divisor, NumberDataValue result)throws StandardException{return divide(dividend, divisor, result, -1);} /** * This method implements the / operator for BigDecimal/BigDecimal * * @param dividend The numerator * @param divisor The denominator * @param result The result of a previous call to this method, null * if not called yet * @param scale The result scale, if < 0, calculate the scale according * to the actual values' sizes * * @return A SQLDecimal containing the result of the division * * @exception StandardException Thrown on error */ public final NumberDataValue divide(NumberDataValue dividend, NumberDataValue divisor, NumberDataValue result, int scale) throws StandardException { if (result == null) { result = (NumberDataValue) getNewNull(); } if (dividend.isNull() || divisor.isNull()) { result.setToNull(); return result; } return divideNN(dividend, divisor, result, scale); } public final NumberDataValue minus(NumberDataValue left, NumberDataValue right, NumberDataValue result) throws StandardException { if (result == null) { result = (NumberDataValue) getNewNull(); } if (left.isNull() || right.isNull()) { result.setToNull(); return result; } return minusNN(left, right, result); } /** * Implement subtraction using addition and negation of the right value. */ public NumberDataValue minusNN(NumberDataValue left, NumberDataValue right, NumberDataValue result) throws StandardException { // Requires plusNN() correctly handles that its right argument and // result can be references to the same object. return plusNN(left, right.minus(result), result); } /* ** Abstract methods for handling non-null arithmetic. ** Eventually move these methods into NumberDataType ** and directly compile to them when arguments cannot ** be null. A performance optimization. */ /** * Multiple two non-nullable values using DECIMAL arithmetic. */ public abstract NumberDataValue timesNN(NumberDataValue left, NumberDataValue right, NumberDataValue result) throws StandardException; /** * Add two non-nullable values using DECIMAL arithmetic. * For subclasses of BinaryDecimal, any implementation * must handle the result and addend2 (right) being references * to the same object. */ public abstract NumberDataValue plusNN(NumberDataValue addend1, NumberDataValue addend2, NumberDataValue result) throws StandardException; /** * Divide two non-nullable values using DECIMAL arithmetic. */ public abstract NumberDataValue divideNN(NumberDataValue dividend, NumberDataValue divisor, NumberDataValue result, int scale) throws StandardException; /* ** Methods that act directly on twos complement byte arrays. */ /** * Compress the passed in byte array so that leading * 0x00 and 0xff are removed when possible. * E.g. * 0x00000453 ->>> 0x0453 * 0xfffffff2 ->>> 0xf2 * 0xff192312 ->>> 0xff192312 (unchanged) * 0xffff8039 ->>> 0x8039 * data2c is set to the compressed value. * @param dataLength Valid length of data in data2c. */ private static byte[] reduceBytes2c(byte[] rd, int offset, int dataLength) { // look for leading zeros, if the value // is dataLength bytes long then look // at up to the first (dataLength - 1) bytes // to see if leading 0x00 can be removed. int leading; for (leading = 0; leading < (dataLength - 1); leading++) { if (rd[offset + leading] != (byte) 0) break; // if the hi bit of the next byte is set // then we cannot strip this 0x00 otherwise // the number will turn negative. if ((rd[offset + leading + 1] & 0x80) != 0) break; } if (leading == 0) { // now a similar trick with 0xff, but a slight // complication. for (; leading < (dataLength - 1); leading++) { // Need to check the highest byte of the // would-be remaining significant byte is // set to indicate this is still a negative number if ((rd[offset + leading] == (byte) 0xff) && ((rd[offset + leading+1] & (byte) 0x80) != 0)) continue; break; } } if ((leading != 0) || (rd.length != dataLength)) { byte[] reduced = new byte[dataLength - leading]; System.arraycopy(rd, offset + leading, reduced, 0, reduced.length); return reduced; } return rd; } /** * Return the SQL scale of this value, number of digits after the * decimal point, or zero for a whole number. */ public int getDecimalValueScale() { if (isNull()) return 0; return sqlScale; } /* ** I/O handling */ /** * Distill the Decimal to a byte array and * Write out: <UL> * <LI> scale (unsigned byte) </LI> * <LI> length of byte array </LI> * <LI> the byte array </LI> </UL> * */ public void writeExternal(ObjectOutput out) throws IOException { // never called when value is null if (SanityManager.DEBUG) SanityManager.ASSERT(! isNull()); out.writeByte(sqlScale); out.writeByte(data2c.length); out.write(data2c); } /** * Note the use of data2c: we reuse the array if the * incoming array is the same length or smaller than * the array length. * * @see java.io.Externalizable#readExternal */ public void readExternal(ObjectInput in) throws IOException { sqlScale = in.readUnsignedByte(); int size = in.readUnsignedByte(); /* ** Allocate a new array if the data to read ** is larger than the existing array, or if ** we don't have an array yet. Need to use readFully below and NOT just read because read does not guarantee getting size bytes back, whereas readFully does (unless EOF). */ if ((data2c == null) || size != data2c.length) { data2c = new byte[size]; } in.readFully(data2c); } public void readExternalFromArray(ArrayInputStream in) throws IOException { sqlScale = in.readUnsignedByte(); int size = in.readUnsignedByte(); /* ** Allocate a new array if the data to read ** is larger than the existing array, or if ** we don't have an array yet. Need to use readFully below and NOT just read because read does not guarantee getting size bytes back, whereas readFully does (unless EOF). */ if ((data2c == null) || size != data2c.length) { data2c = new byte[size]; } in.readFully(data2c); } public final int getLength() { return getDecimalValuePrecision(); } /* (non-Javadoc) * @see org.apache.derby.iapi.types.DataValueDescriptor#getClone() */ public DataValueDescriptor getClone() { BinaryDecimal dvd = (BinaryDecimal) getNewNull(); if (this.data2c != null) { dvd.data2c = new byte[data2c.length]; System.arraycopy(data2c, 0, dvd.data2c, 0, data2c.length); dvd.sqlScale = sqlScale; } return dvd; } /* (non-Javadoc) * @see org.apache.derby.iapi.types.DataValueDescriptor#setValueFromResultSet(java.sql.ResultSet, int, boolean) */ public void setValueFromResultSet(ResultSet resultSet, int colNumber, boolean isNullable) throws StandardException, SQLException { // TODO Auto-generated method stub throw StandardException.newException(SQLState.NOT_IMPLEMENTED); } /* (non-Javadoc) * @see org.apache.derby.iapi.types.DataValueDescriptor#estimateMemoryUsage() */ public int estimateMemoryUsage() { // TODO Auto-generated method stub return 0; } public int hashCode() { if (isNull()) return 0; try { return (int) getLong(); } catch (StandardException se) { return 0; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -