File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\value\ValueLong.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.value;
8
9 import java.math.BigDecimal;
10 import java.math.BigInteger;
11 import java.sql.PreparedStatement;
12 import java.sql.SQLException;
13 import org.h2.constant.ErrorCode;
14 import org.h2.message.DbException;
15 import org.h2.util.MathUtils;
16
17 /**
18 * Implementation of the BIGINT data type.
19 */
20 public class ValueLong extends Value {
21
22 /**
23 * The largest Long value, as a BigInteger.
24 */
25 public static final BigInteger MAX = BigInteger.valueOf(Long.MAX_VALUE);
26
27 /**
28 * The smallest Long value, as a BigDecimal.
29 */
30 public static final BigDecimal MIN_BD = BigDecimal.valueOf(Long.MIN_VALUE);
31
32 /**
33 * The precision in digits.
34 */
35 public static final int PRECISION = 19;
36
37 /**
38 * The maximum display size of a long.
39 * Example: 9223372036854775808
40 */
41 public static final int DISPLAY_SIZE = 20;
42
43 private static final BigInteger MIN = BigInteger.valueOf(Long.MIN_VALUE);
44 private static final int STATIC_SIZE = 100;
45 private static final ValueLong[] STATIC_CACHE;
46
47 private final long value;
48
49 static {
50 STATIC_CACHE = new ValueLong[STATIC_SIZE];
51 for (int i = 0; i < STATIC_SIZE; i++) {
52 STATIC_CACHE[i] = new ValueLong(i);
53 }
54 }
55
56 private ValueLong(long value) {
57 this.value = value;
58 }
59
60 public Value add(Value v) {
61 ValueLong other = (ValueLong) v;
62 long result = value + other.value;
63 int sv = Long.signum(value);
64 int so = Long.signum(other.value);
65 int sr = Long.signum(result);
66 // if the operands have different signs overflow can not occur
67 // if the operands have the same sign,
68 // and the result has a different sign, then it is an overflow
69 // it can not be an overflow when one of the operands is 0
70 if (sv != so || sr == so || sv == 0 || so == 0) {
71 return ValueLong.get(result);
72 }
73 throw getOverflow();
74 }
75
76 public int getSignum() {
77 return Long.signum(value);
78 }
79
80 public Value negate() {
81 if (value == Long.MIN_VALUE) {
82 throw getOverflow();
83 }
84 return ValueLong.get(-value);
85 }
86
87 private DbException getOverflow() {
88 return DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Long.toString(value));
89 }
90
91 public Value subtract(Value v) {
92 ValueLong other = (ValueLong) v;
93 int sv = Long.signum(value);
94 int so = Long.signum(other.value);
95 // if the operands have the same sign, then overflow can not occur
96 // if the second operand is 0, then overflow can not occur
97 if (sv == so || so == 0) {
98 return ValueLong.get(value - other.value);
99 }
100 // now, if the other value is Long.MIN_VALUE, it must be an overflow
101 // x - Long.MIN_VALUE overflows for x>=0
102 return add(other.negate());
103 }
104
105 private static boolean isInteger(long a) {
106 return a >= Integer.MIN_VALUE && a <= Integer.MAX_VALUE;
107 }
108
109 public Value multiply(Value v) {
110 ValueLong other = (ValueLong) v;
111 long result = value * other.value;
112 if (value == 0 || value == 1 || other.value == 0 || other.value == 1) {
113 return ValueLong.get(result);
114 }
115 if (isInteger(value) && isInteger(other.value)) {
116 return ValueLong.get(result);
117 }
118 // just checking one case is not enough: Long.MIN_VALUE * -1
119 // probably this is correct but I'm not sure
120 // if(result / value == other.value && result / other.value == value) {
121 // return ValueLong.get(result);
122 //}
123 BigInteger bv = BigInteger.valueOf(value);
124 BigInteger bo = BigInteger.valueOf(other.value);
125 BigInteger br = bv.multiply(bo);
126 if (br.compareTo(MIN) < 0 || br.compareTo(MAX) > 0) {
127 throw getOverflow();
128 }
129 return ValueLong.get(br.longValue());
130 }
131
132 public Value divide(Value v) {
133 ValueLong other = (ValueLong) v;
134 if (other.value == 0) {
135 throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
136 }
137 return ValueLong.get(value / other.value);
138 }
139
140 public Value modulus(Value v) {
141 ValueLong other = (ValueLong) v;
142 if (other.value == 0) {
143 throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
144 }
145 return ValueLong.get(this.value % other.value);
146 }
147
148 public String getSQL() {
149 return getString();
150 }
151
152 public int getType() {
153 return Value.LONG;
154 }
155
156 public long getLong() {
157 return value;
158 }
159
160 protected int compareSecure(Value o, CompareMode mode) {
161 ValueLong v = (ValueLong) o;
162 return MathUtils.compareLong(value, v.value);
163 }
164
165 public String getString() {
166 return String.valueOf(value);
167 }
168
169 public long getPrecision() {
170 return PRECISION;
171 }
172
173 public int hashCode() {
174 return (int) (value ^ (value >> 32));
175 }
176
177 public Object getObject() {
178 return value;
179 }
180
181 public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
182 prep.setLong(parameterIndex, value);
183 }
184
185 /**
186 * Get or create a long value for the given long.
187 *
188 * @param i the long
189 * @return the value
190 */
191 public static ValueLong get(long i) {
192 if (i >= 0 && i < STATIC_SIZE) {
193 return STATIC_CACHE[(int) i];
194 }
195 return (ValueLong) Value.cache(new ValueLong(i));
196 }
197
198 public int getDisplaySize() {
199 return DISPLAY_SIZE;
200 }
201
202 public boolean equals(Object other) {
203 return other instanceof ValueLong && value == ((ValueLong) other).value;
204 }
205
206 }
207