ParticularFloatValue.java revision 8a6199f0c36a778f22394364347a301b0b28e94b
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 FloatValue represents a particular float value.
25 *
26 * @author Eric Lafortune
27 */
28final class ParticularFloatValue extends SpecificFloatValue
29{
30    private final float value;
31
32
33    /**
34     * Creates a new particular float value.
35     */
36    public ParticularFloatValue(float value)
37    {
38        this.value = value;
39    }
40
41
42    // Implementations for FloatValue.
43
44    public float value()
45    {
46        return value;
47    }
48
49
50    // Implementations of unary methods of FloatValue.
51
52    public FloatValue negate()
53    {
54        return new ParticularFloatValue(-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 DoubleValue convertToDouble()
68    {
69        return new ParticularDoubleValue((float)value);
70    }
71
72
73    // Implementations of binary methods of FloatValue.
74
75    public FloatValue generalize(FloatValue other)
76    {
77        return other.generalize(this);
78    }
79
80    public FloatValue add(FloatValue 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 FloatValue subtract(FloatValue 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 FloatValue subtractFrom(FloatValue 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 FloatValue multiply(FloatValue other)
102    {
103        return other.multiply(this);
104    }
105
106    public FloatValue divide(FloatValue other)
107    {
108        return other.divideOf(this);
109    }
110
111    public FloatValue divideOf(FloatValue other)
112    {
113        return other.divide(this);
114    }
115
116    public FloatValue remainder(FloatValue other)
117    {
118        return other.remainderOf(this);
119    }
120
121    public FloatValue remainderOf(FloatValue other)
122    {
123        return other.remainder(this);
124    }
125
126    public IntegerValue compare(FloatValue other)
127    {
128        return other.compareReverse(this);
129    }
130
131
132    // Implementations of binary FloatValue methods with ParticularFloatValue
133    // arguments.
134
135    public FloatValue generalize(ParticularFloatValue other)
136    {
137        // Also handle NaN and Infinity.
138        return Float.floatToRawIntBits(this.value) ==
139               Float.floatToRawIntBits(other.value) ?
140                   this : ValueFactory.FLOAT_VALUE;
141    }
142
143    public FloatValue add(ParticularFloatValue other)
144    {
145        return new ParticularFloatValue(this.value + other.value);
146    }
147
148    public FloatValue subtract(ParticularFloatValue other)
149    {
150        return new ParticularFloatValue(this.value - other.value);
151    }
152
153    public FloatValue subtractFrom(ParticularFloatValue other)
154    {
155        return new ParticularFloatValue(other.value - this.value);
156    }
157
158    public FloatValue multiply(ParticularFloatValue other)
159    {
160        return new ParticularFloatValue(this.value * other.value);
161    }
162
163    public FloatValue divide(ParticularFloatValue other)
164    {
165        return new ParticularFloatValue(this.value / other.value);
166    }
167
168    public FloatValue divideOf(ParticularFloatValue other)
169    {
170        return new ParticularFloatValue(other.value / this.value);
171    }
172
173    public FloatValue remainder(ParticularFloatValue other)
174    {
175        return new ParticularFloatValue(this.value % other.value);
176    }
177
178    public FloatValue remainderOf(ParticularFloatValue other)
179    {
180        return new ParticularFloatValue(other.value % this.value);
181    }
182
183    public IntegerValue compare(ParticularFloatValue 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               Float.floatToIntBits(this.value) ==
206               Float.floatToIntBits(((ParticularFloatValue)object).value);
207    }
208
209
210    public int hashCode()
211    {
212        return super.hashCode() ^
213               Float.floatToIntBits(value);
214    }
215
216
217    public String toString()
218    {
219        return value+"f";
220    }
221}