1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // Note that $opt$ is a marker for the optimizing compiler to test
18 // it does compile the method.
19 public class DivTest {
20 
expectEquals(int expected, int result)21   public static void expectEquals(int expected, int result) {
22     if (expected != result) {
23       throw new Error("Expected: " + expected + ", found: " + result);
24     }
25   }
26 
expectEquals(long expected, long result)27   public static void expectEquals(long expected, long result) {
28     if (expected != result) {
29       throw new Error("Expected: " + expected + ", found: " + result);
30     }
31   }
32 
expectEquals(float expected, float result)33   public static void expectEquals(float expected, float result) {
34     if (expected != result) {
35       throw new Error("Expected: " + expected + ", found: " + result);
36     }
37   }
38 
expectEquals(double expected, double result)39   public static void expectEquals(double expected, double result) {
40     if (expected != result) {
41       throw new Error("Expected: " + expected + ", found: " + result);
42     }
43   }
44 
expectApproxEquals(float a, float b)45   public static void expectApproxEquals(float a, float b) {
46     float maxDelta = 0.00001F;
47     boolean aproxEquals = (a > b) ? ((a - b) < maxDelta) : ((b - a) < maxDelta);
48     if (!aproxEquals) {
49       throw new Error("Expected: " + a + ", found: " + b
50           + ", with delta: " + maxDelta + " " + (a - b));
51     }
52   }
53 
expectApproxEquals(double a, double b)54   public static void expectApproxEquals(double a, double b) {
55     double maxDelta = 0.00001D;
56     boolean aproxEquals = (a > b) ? ((a - b) < maxDelta) : ((b - a) < maxDelta);
57     if (!aproxEquals) {
58       throw new Error("Expected: " + a + ", found: "
59           + b + ", with delta: " + maxDelta + " " + (a - b));
60     }
61   }
62 
expectNaN(float a)63   public static void expectNaN(float a) {
64     if (a == a) {
65       throw new Error("Expected NaN: " + a);
66     }
67   }
68 
expectNaN(double a)69   public static void expectNaN(double a) {
70     if (a == a) {
71       throw new Error("Expected NaN: " + a);
72     }
73   }
74 
expectDivisionByZero(int value)75   public static void expectDivisionByZero(int value) {
76     try {
77       $opt$Div(value, 0);
78       throw new Error("Expected RuntimeException when dividing by 0");
79     } catch (java.lang.RuntimeException e) {
80     }
81     try {
82       $opt$DivZero(value);
83       throw new Error("Expected RuntimeException when dividing by 0");
84     } catch (java.lang.RuntimeException e) {
85     }
86   }
87 
expectDivisionByZero(long value)88   public static void expectDivisionByZero(long value) {
89     try {
90       $opt$Div(value, 0L);
91       throw new Error("Expected RuntimeException when dividing by 0");
92     } catch (java.lang.RuntimeException e) {
93     }
94     try {
95       $opt$DivZero(value);
96       throw new Error("Expected RuntimeException when dividing by 0");
97     } catch (java.lang.RuntimeException e) {
98     }
99   }
100 
main()101   public static void main() {
102     divInt();
103     divLong();
104     divFloat();
105     divDouble();
106   }
107 
divInt()108   private static void divInt() {
109     expectEquals(2, $opt$DivConst(6));
110     expectEquals(2, $opt$Div(6, 3));
111     expectEquals(6, $opt$Div(6, 1));
112     expectEquals(-2, $opt$Div(6, -3));
113     expectEquals(1, $opt$Div(4, 3));
114     expectEquals(-1, $opt$Div(4, -3));
115     expectEquals(5, $opt$Div(23, 4));
116     expectEquals(-5, $opt$Div(-23, 4));
117 
118     expectEquals(-Integer.MAX_VALUE, $opt$Div(Integer.MAX_VALUE, -1));
119     expectEquals(Integer.MIN_VALUE, $opt$Div(Integer.MIN_VALUE, -1)); // overflow
120     expectEquals(-1073741824, $opt$Div(Integer.MIN_VALUE, 2));
121 
122     expectEquals(0, $opt$Div(0, Integer.MAX_VALUE));
123     expectEquals(0, $opt$Div(0, Integer.MIN_VALUE));
124 
125     expectDivisionByZero(0);
126     expectDivisionByZero(1);
127     expectDivisionByZero(Integer.MAX_VALUE);
128     expectDivisionByZero(Integer.MIN_VALUE);
129   }
130 
divLong()131   private static void divLong() {
132     expectEquals(2L, $opt$DivConst(6L));
133     expectEquals(2L, $opt$Div(6L, 3L));
134     expectEquals(6L, $opt$Div(6L, 1L));
135     expectEquals(-2L, $opt$Div(6L, -3L));
136     expectEquals(1L, $opt$Div(4L, 3L));
137     expectEquals(-1L, $opt$Div(4L, -3L));
138     expectEquals(5L, $opt$Div(23L, 4L));
139     expectEquals(-5L, $opt$Div(-23L, 4L));
140 
141     expectEquals(-Integer.MAX_VALUE, $opt$Div(Integer.MAX_VALUE, -1L));
142     expectEquals(2147483648L, $opt$Div(Integer.MIN_VALUE, -1L));
143     expectEquals(-1073741824L, $opt$Div(Integer.MIN_VALUE, 2L));
144 
145     expectEquals(-Long.MAX_VALUE, $opt$Div(Long.MAX_VALUE, -1L));
146     expectEquals(Long.MIN_VALUE, $opt$Div(Long.MIN_VALUE, -1L)); // overflow
147 
148     expectEquals(11111111111111L, $opt$Div(33333333333333L, 3L));
149     expectEquals(3L, $opt$Div(33333333333333L, 11111111111111L));
150 
151     expectEquals(0L, $opt$Div(0L, Long.MAX_VALUE));
152     expectEquals(0L, $opt$Div(0L, Long.MIN_VALUE));
153 
154     expectDivisionByZero(0L);
155     expectDivisionByZero(1L);
156     expectDivisionByZero(Long.MAX_VALUE);
157     expectDivisionByZero(Long.MIN_VALUE);
158   }
159 
divFloat()160   private static void divFloat() {
161     expectApproxEquals(1.6666666F, $opt$Div(5F, 3F));
162     expectApproxEquals(0F, $opt$Div(0F, 3F));
163     expectApproxEquals(-0.3333333F, $opt$Div(1F, -3F));
164     expectApproxEquals(4F, $opt$Div(-12F, -3F));
165     expectApproxEquals(0.5, $opt$Div(0.1F, 0.2F));
166     expectApproxEquals(-2.5F, $opt$Div(-0.5F, 0.2F));
167 
168     expectEquals(0F, $opt$Div(0F, Float.POSITIVE_INFINITY));
169     expectEquals(0F, $opt$Div(11F, Float.POSITIVE_INFINITY));
170     expectEquals(0F, $opt$Div(0F, Float.NEGATIVE_INFINITY));
171     expectEquals(0F, $opt$Div(11F, Float.NEGATIVE_INFINITY));
172 
173     expectNaN($opt$Div(0F, 0F));
174     expectNaN($opt$Div(Float.NaN, 11F));
175     expectNaN($opt$Div(-11F, Float.NaN));
176     expectNaN($opt$Div(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
177     expectNaN($opt$Div(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY));
178     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY));
179     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
180     expectNaN($opt$Div(Float.NaN, Float.NEGATIVE_INFINITY));
181     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.NaN));
182 
183     expectEquals(Float.POSITIVE_INFINITY, $opt$Div(3F, 0F));
184     expectEquals(Float.NEGATIVE_INFINITY, $opt$Div(-3F, 0F));
185     expectEquals(Float.POSITIVE_INFINITY, $opt$Div(Float.MAX_VALUE, Float.MIN_VALUE));
186     expectEquals(Float.NEGATIVE_INFINITY, $opt$Div(-Float.MAX_VALUE, Float.MIN_VALUE));
187   }
188 
divDouble()189   private static void divDouble() {
190     expectApproxEquals(1.6666666D, $opt$Div(5D, 3D));
191     expectApproxEquals(0D, $opt$Div(0D, 3D));
192     expectApproxEquals(-0.3333333D, $opt$Div(1D, -3D));
193     expectApproxEquals(4D, $opt$Div(-12D, -3D));
194     expectApproxEquals(0.5, $opt$Div(0.1D, 0.2D));
195     expectApproxEquals(-2.5D, $opt$Div(-0.5D, 0.2D));
196 
197     expectEquals(0D, $opt$Div(0D, Float.POSITIVE_INFINITY));
198     expectEquals(0D, $opt$Div(11D, Float.POSITIVE_INFINITY));
199     expectEquals(0D, $opt$Div(0D, Float.NEGATIVE_INFINITY));
200     expectEquals(0D, $opt$Div(11D, Float.NEGATIVE_INFINITY));
201 
202     expectNaN($opt$Div(0D, 0D));
203     expectNaN($opt$Div(Float.NaN, 11D));
204     expectNaN($opt$Div(-11D, Float.NaN));
205     expectNaN($opt$Div(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
206     expectNaN($opt$Div(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY));
207     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY));
208     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
209     expectNaN($opt$Div(Float.NaN, Float.NEGATIVE_INFINITY));
210     expectNaN($opt$Div(Float.POSITIVE_INFINITY, Float.NaN));
211 
212     expectEquals(Float.POSITIVE_INFINITY, $opt$Div(3D, 0D));
213     expectEquals(Float.NEGATIVE_INFINITY, $opt$Div(-3D, 0D));
214     expectEquals(Float.POSITIVE_INFINITY, $opt$Div(Float.MAX_VALUE, Float.MIN_VALUE));
215     expectEquals(Float.NEGATIVE_INFINITY, $opt$Div(-Float.MAX_VALUE, Float.MIN_VALUE));
216   }
217 
$opt$Div(int a, int b)218   static int $opt$Div(int a, int b) {
219     return a / b;
220   }
221 
$opt$DivZero(int a)222   static int $opt$DivZero(int a) {
223     return a / 0;
224   }
225 
226   // Division by literals != 0 should not generate checks.
$opt$DivConst(int a)227   static int $opt$DivConst(int a) {
228     return a / 3;
229   }
230 
$opt$DivConst(long a)231   static long $opt$DivConst(long a) {
232     return a / 3L;
233   }
234 
$opt$Div(long a, long b)235   static long $opt$Div(long a, long b) {
236     return a / b;
237   }
238 
$opt$DivZero(long a)239   static long $opt$DivZero(long a) {
240     return a / 0L;
241   }
242 
$opt$Div(float a, float b)243   static float $opt$Div(float a, float b) {
244     return a / b;
245   }
246 
$opt$Div(double a, double b)247   static double $opt$Div(double a, double b) {
248     return a / b;
249   }
250 }
251