1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.evaluation.value;
22
23/**
24 * This DoubleValue represents a particular double value.
25 *
26 * @author Eric Lafortune
27 */
28final class ParticularDoubleValue extends SpecificDoubleValue
29{
30    private final double value;
31
32
33    /**
34     * Creates a new particular double value.
35     */
36    public ParticularDoubleValue(double value)
37    {
38        this.value = value;
39    }
40
41
42    // Implementations for DoubleValue.
43
44    public double value()
45    {
46        return value;
47    }
48
49
50    // Implementations of unary methods of DoubleValue.
51
52    public DoubleValue negate()
53    {
54        return new ParticularDoubleValue(-value);
55    }
56
57    public IntegerValue convertToInteger()
58    {
59        return new ParticularIntegerValue((int)value);
60    }
61
62    public LongValue convertToLong()
63    {
64        return new ParticularLongValue((long)value);
65    }
66
67    public FloatValue convertToFloat()
68    {
69        return new ParticularFloatValue((float)value);
70    }
71
72
73    // Implementations of binary methods of DoubleValue.
74
75    public DoubleValue generalize(DoubleValue other)
76    {
77        return other.generalize(this);
78    }
79
80    public DoubleValue add(DoubleValue other)
81    {
82        // Careful: -0.0 + 0.0 == 0.0
83        //return value == 0.0 ? other : other.add(this);
84        return other.add(this);
85    }
86
87    public DoubleValue subtract(DoubleValue other)
88    {
89        // Careful: -0.0 + 0.0 == 0.0
90        //return value == 0.0 ? other.negate() : other.subtractFrom(this);
91        return other.subtractFrom(this);
92    }
93
94    public DoubleValue subtractFrom(DoubleValue other)
95    {
96        // Careful: -0.0 + 0.0 == 0.0
97        //return value == 0.0 ? other : other.subtract(this);
98        return other.subtract(this);
99    }
100
101    public DoubleValue multiply(DoubleValue other)
102    {
103        return other.multiply(this);
104    }
105
106    public DoubleValue divide(DoubleValue other)
107    {
108        return other.divideOf(this);
109    }
110
111    public DoubleValue divideOf(DoubleValue other)
112    {
113        return other.divide(this);
114    }
115
116    public DoubleValue remainder(DoubleValue other)
117    {
118        return other.remainderOf(this);
119    }
120
121    public DoubleValue remainderOf(DoubleValue other)
122    {
123        return other.remainder(this);
124    }
125
126    public IntegerValue compare(DoubleValue other)
127    {
128        return other.compareReverse(this);
129    }
130
131
132    // Implementations of binary DoubleValue methods with ParticularDoubleValue
133    // arguments.
134
135    public DoubleValue generalize(ParticularDoubleValue other)
136    {
137        // Also handle NaN and Infinity.
138        return Double.doubleToRawLongBits(this.value) ==
139               Double.doubleToRawLongBits(other.value) ?
140                   this : ValueFactory.DOUBLE_VALUE;
141    }
142
143    public DoubleValue add(ParticularDoubleValue other)
144    {
145        return new ParticularDoubleValue(this.value + other.value);
146    }
147
148    public DoubleValue subtract(ParticularDoubleValue other)
149    {
150        return new ParticularDoubleValue(this.value - other.value);
151    }
152
153    public DoubleValue subtractFrom(ParticularDoubleValue other)
154    {
155        return new ParticularDoubleValue(other.value - this.value);
156    }
157
158    public DoubleValue multiply(ParticularDoubleValue other)
159    {
160        return new ParticularDoubleValue(this.value * other.value);
161    }
162
163    public DoubleValue divide(ParticularDoubleValue other)
164    {
165        return new ParticularDoubleValue(this.value / other.value);
166    }
167
168    public DoubleValue divideOf(ParticularDoubleValue other)
169    {
170        return new ParticularDoubleValue(other.value / this.value);
171    }
172
173    public DoubleValue remainder(ParticularDoubleValue other)
174    {
175        return new ParticularDoubleValue(this.value % other.value);
176    }
177
178    public DoubleValue remainderOf(ParticularDoubleValue other)
179    {
180        return new ParticularDoubleValue(other.value % this.value);
181    }
182
183    public IntegerValue compare(ParticularDoubleValue other)
184    {
185        return this.value <  other.value ? SpecificValueFactory.INTEGER_VALUE_M1 :
186               this.value == other.value ? SpecificValueFactory.INTEGER_VALUE_0  :
187                                           SpecificValueFactory.INTEGER_VALUE_1;
188    }
189
190
191    // Implementations for Value.
192
193    public boolean isParticular()
194    {
195        return true;
196    }
197
198
199    // Implementations for Object.
200
201    public boolean equals(Object object)
202    {
203       // Also handle NaN and Infinity.
204       return super.equals(object) &&
205              Double.doubleToLongBits(this.value) ==
206              Double.doubleToLongBits(((ParticularDoubleValue)object).value);
207    }
208
209
210    public int hashCode()
211    {
212        return super.hashCode() ^
213               (int)Double.doubleToLongBits(value);
214    }
215
216
217    public String toString()
218    {
219        return value+"d";
220    }
221}