⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutablenumeric.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		int newScale = Math.max(scale+5, num.scale +4);
		BigDecimal big = toBigDecimal().divide(num.toBigDecimal(), newScale, BigDecimal.ROUND_HALF_EVEN);
		setValue( big.unscaledValue().toByteArray() );
		scale = big.scale();
		signum = big.signum();
    }
	

	final void div(int quotient){
		//increment the scale with 5
		mul(100000);
		scale += 5;
		
		divImpl(quotient);
	}
	
	
	final private void divImpl(int quotient){	
		if(quotient == 1) return;
		if(quotient < 0){
			quotient = - quotient;
			signum = -signum;
		}
		int valueLength = value.length;
		long carryover = 0;
		for(int i = 0; i<valueLength; i++){
			long v = (value[i] & 0xFFFFFFFFL) + carryover;
			value[i] = (int)(v / quotient);
			carryover = ((v % quotient) << 32);
		}
		carryover /= quotient;
		if(carryover > 2147483648L || //2147483648L == Integer.MAX_VALUE+1
		  (carryover == 2147483648L && (value[valueLength-1] % 2 == 1))){
			int i = valueLength-1;
			boolean isCarryOver = true;
			while(i >= 0 && isCarryOver)
				isCarryOver = (value[i--] += 1) == 0;
		}
		if(valueLength>1 && value[0] == 0){
			int[] temp = new int[valueLength-1];
			System.arraycopy(value, 1, temp, 0, valueLength-1);
			value = temp;
		}
			
	}
	
	
    void mod(MutableNumeric num){
    	//TODO performance
		num = new MutableNumeric( doubleValue() % num.doubleValue() );
		value = num.value;
		scale = num.scale;
		signum = num.signum;
    }


	int getScale(){
	    return scale;
    }
    
    
	void setScale(int newScale){
		if(newScale == scale) return;
		int factor = 1;
		if(newScale > scale){
			for(;newScale>scale; scale++){
				factor *=10;
				if(factor == 1000000000){
					mul(factor);
					factor = 1;
				}
			}
			mul(factor);
		}else{
			for(;newScale<scale; scale--){
				factor *=10;
				if(factor == 1000000000){
					divImpl(factor);
					factor = 1;
				}
			}
			divImpl(factor);		
		}
	}
	
	
	

    /**
     * @return Returns the signum.
     */
    int getSignum() {
        return signum;
    }
    
    
    void setSignum(int signum){
        this.signum = signum;
    }
    

    void floor(){
		//TODO performance
		int oldScale = scale;
		setScale(0);
		setScale(oldScale);
	}
	

    private void negate(byte[] complement){
        int last = complement.length-1;
        for(int i=0; i<=last; i++){
            complement[i] = (byte)( (i == last) ? -complement[i] : ~complement[i]);
        }
        while(complement[last] == 0){
            last--;
            complement[last]++;
        }
    }

    
    /**
     * Convert this number in a 2 complement that can be used from BigInteger.
     * The length is ever a multiple of 4
     * @return the 2 complement of this object
     */
    byte[] toByteArray(){
        if(signum == 0) return EMPTY_BYTES;
        byte[] complement;
        int offset;

        int v = 0;
        while(v < value.length && value[v] == 0) v++;
        if (v == value.length) return EMPTY_BYTES;

        if(value[v] < 0){
            // If the highest bit is set then it must resize
            // because this bit is needed for the signum
            complement = new byte[(value.length-v)*4 + 4];
            if(signum < 0)
                complement[0] = complement[1] = complement[2] = complement[3] = -1;
            offset = 4;
        }else{
            complement = new byte[(value.length-v)*4];
            offset = 0;
        }
        int last = value.length-1;
        for(; v <= last; v++){
            int val = (signum>0) ? value[v] : (v == last) ? -value[v] : ~value[v];
            complement[offset++] = (byte)(val >> 24);
            complement[offset++] = (byte)(val >> 16);
            complement[offset++] = (byte)(val >> 8);
            complement[offset++] = (byte)(val);
        }
        return complement;
    }

    public int intValue(){
        return Utils.long2int(longValue());
    }
    

    public long longValue(){
        if(value.length == 0 || signum == 0){
            return 0;
        }else{
            if (value.length == 1 && (value[0] > 0)){
                // simple Integer Value
                return Utils.double2long(value[0] / scaleDoubleFactor[scale] * signum);
            }else
            if (value.length == 1){
                // overflow Integer Value
                long temp = value[0] & 0xFFFFFFFFL;
                return Utils.double2long(temp / scaleDoubleFactor[scale] * signum);
            }else
            if (value.length == 2 && (value[0] > 0)){
                // simple Long Value
                long temp = (((long)value[0]) << 32) | (value[1] & 0xFFFFFFFFL);
                return Utils.double2long(temp / scaleDoubleFactor[scale] * signum);
            }else{
           		if(scale != 0){
           			MutableNumeric numeric = new MutableNumeric(this);
           			numeric.setScale(0);
           			return numeric.longValue();
           		}           			
            	return (signum > 0) ? Long.MAX_VALUE : Long.MIN_VALUE;
            }
        }
    }
    

    public float floatValue(){
        if(value.length == 0 || signum == 0){
            return 0;
        }else{
            if (value.length == 1 && (value[0] > 0)){
                // simple Integer Value
                return value[0] / scaleFloatFactor[scale] * signum;
            }else
            if (value.length == 1){
                // overflow Integer Value
                long temp = value[0] & 0xFFFFFFFFL;
                return temp / scaleFloatFactor[scale] * signum;
            }else
            if (value.length == 2 && (value[0] > 0)){
                // simple Long Value
                long temp = (((long)value[0]) << 32) | (value[1] & 0xFFFFFFFFL);
                return temp / scaleFloatFactor[scale] * signum;
            }else{
                return new BigDecimal( new BigInteger( toByteArray() ), scale ).floatValue();
            }
        }
    }

    public double doubleValue(){
        if(value.length == 0 || signum == 0){
            return 0;
        }else{
            if (value.length == 1 && (value[0] > 0)){
                // simple Integer Value
                return value[0] / scaleDoubleFactor[scale] * signum;
            }else
            if (value.length == 1){
                // overflow Integer Value
                long temp = value[0] & 0xFFFFFFFFL;
                return temp / scaleDoubleFactor[scale] * signum;
            }else
            if (value.length == 2 && (value[0] > 0)){
                // simple Long Value
                long temp = (((long)value[0]) << 32) | (value[1] & 0xFFFFFFFFL);
                return temp / scaleDoubleFactor[scale] * signum;
            }else{
                return new BigDecimal( new BigInteger( toByteArray() ), scale ).doubleValue();
            }
        }
    }

    public String toString(){
        StringBuffer buf = new StringBuffer();
        if(value.length == 0 || signum == 0){
            buf.append( '0' );
        }else{
            if (value.length == 1 && (value[0] > 0)){
                // simple Integer Value
                buf.append( Integer.toString(value[0]) );
            }else
            if (value.length == 1){
                // overflow Integer Value
                long temp = value[0] & 0xFFFFFFFFL;
                buf.append( Long.toString( temp ) );
            }else
            if (value.length == 2 && (value[0] > 0)){
                // simple Long Value
                long temp = (((long)value[0]) << 32) | (value[1] & 0xFFFFFFFFL);
                buf.append( Long.toString( temp ) );
            }else{
                return new BigDecimal( new BigInteger( toByteArray() ), scale ).toString();
            }
        }
        if(scale > 0){
            while(buf.length() <= scale) buf.insert( 0, '0' );
            buf.insert( buf.length() - scale, '.' );
        }
        if (signum < 0) buf.insert( 0, '-');
        return buf.toString();
    }
    
    public int compareTo(MutableNumeric numeric){
    	//TODO performance
		return toBigDecimal().compareTo(numeric.toBigDecimal());
    }           

	public boolean equals(Object obj){
		if(!(obj instanceof MutableNumeric)) return false;
		return compareTo((MutableNumeric)obj) == 0;
	}
	
    public BigDecimal toBigDecimal(){
		if(signum == 0) return new BigDecimal( BigInteger.ZERO, scale);
        return new BigDecimal( new BigInteger( toByteArray() ), scale );
    }

    public BigDecimal toBigDecimal(int newScale){
        if(newScale == this.scale) return toBigDecimal();
        return toBigDecimal().setScale( newScale, BigDecimal.ROUND_HALF_EVEN);
    }

	public Object getImmutableObject(){
		return toBigDecimal();
	}
	

    private static final byte[] EMPTY_BYTES = new byte[0];
    private static final int [] EMPTY_INTS  = new int [0];
    private static final double[] scaleDoubleFactor = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
    private static final float[]  scaleFloatFactor =  { 1, 10, 100, 1000, 10000, 100000, 1000000 };
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -