]>
Commit | Line | Data |
---|---|---|
3b2f2976 | 1 | use rustc_apfloat::ppc::DoubleDouble; |
dfeec247 | 2 | use rustc_apfloat::{Category, Float, Round}; |
3b2f2976 XL |
3 | |
4 | use std::cmp::Ordering; | |
5 | ||
6 | #[test] | |
7 | fn ppc_double_double() { | |
8 | let test = DoubleDouble::ZERO; | |
9 | let expected = "0x0p+0".parse::<DoubleDouble>().unwrap(); | |
10 | assert!(test.is_zero()); | |
11 | assert!(!test.is_negative()); | |
12 | assert!(test.bitwise_eq(expected)); | |
13 | assert_eq!(0, test.to_bits()); | |
14 | ||
15 | let test = -DoubleDouble::ZERO; | |
16 | let expected = "-0x0p+0".parse::<DoubleDouble>().unwrap(); | |
17 | assert!(test.is_zero()); | |
18 | assert!(test.is_negative()); | |
19 | assert!(test.bitwise_eq(expected)); | |
20 | assert_eq!(0x8000000000000000, test.to_bits()); | |
21 | ||
22 | let test = "1.0".parse::<DoubleDouble>().unwrap(); | |
23 | assert_eq!(0x3ff0000000000000, test.to_bits()); | |
24 | ||
25 | // LDBL_MAX | |
dfeec247 | 26 | let test = "1.79769313486231580793728971405301e+308".parse::<DoubleDouble>().unwrap(); |
3b2f2976 XL |
27 | assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, test.to_bits()); |
28 | ||
29 | // LDBL_MIN | |
dfeec247 | 30 | let test = "2.00416836000897277799610805135016e-292".parse::<DoubleDouble>().unwrap(); |
3b2f2976 XL |
31 | assert_eq!(0x0000000000000000_0360000000000000, test.to_bits()); |
32 | } | |
33 | ||
34 | #[test] | |
35 | fn ppc_double_double_add_special() { | |
36 | let data = [ | |
37 | // (1 + 0) + (-1 + 0) = Category::Zero | |
dfeec247 | 38 | (0x3ff0000000000000, 0xbff0000000000000, Category::Zero, Round::NearestTiesToEven), |
3b2f2976 XL |
39 | // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = Category::Infinity |
40 | ( | |
41 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
42 | 0x7948000000000000, | |
43 | Category::Infinity, | |
44 | Round::NearestTiesToEven, | |
45 | ), | |
46 | // FIXME: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when | |
47 | // DoubleDouble's fallback is gone. | |
48 | // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 - | |
49 | // 160))) = Category::Normal | |
50 | ( | |
51 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
52 | 0x75effffffffffffe_7947ffffffffffff, | |
53 | Category::Normal, | |
54 | Round::NearestTiesToEven, | |
55 | ), | |
56 | // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = Category::Infinity | |
57 | ( | |
58 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
59 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
60 | Category::Infinity, | |
61 | Round::NearestTiesToEven, | |
62 | ), | |
63 | // NaN + (1 + 0) = Category::NaN | |
dfeec247 | 64 | (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 XL |
65 | ]; |
66 | ||
136023e0 | 67 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
68 | { |
69 | let mut a1 = DoubleDouble::from_bits(op1); | |
70 | let a2 = DoubleDouble::from_bits(op2); | |
71 | a1 = a1.add_r(a2, round).value; | |
72 | ||
73 | assert_eq!(expected, a1.category(), "{:#x} + {:#x}", op1, op2); | |
74 | } | |
75 | { | |
76 | let a1 = DoubleDouble::from_bits(op1); | |
77 | let mut a2 = DoubleDouble::from_bits(op2); | |
78 | a2 = a2.add_r(a1, round).value; | |
79 | ||
80 | assert_eq!(expected, a2.category(), "{:#x} + {:#x}", op2, op1); | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | #[test] | |
86 | fn ppc_double_double_add() { | |
87 | let data = [ | |
88 | // (1 + 0) + (1e-105 + 0) = (1 + 1e-105) | |
89 | ( | |
90 | 0x3ff0000000000000, | |
91 | 0x3960000000000000, | |
92 | 0x3960000000000000_3ff0000000000000, | |
93 | Round::NearestTiesToEven, | |
94 | ), | |
95 | // (1 + 0) + (1e-106 + 0) = (1 + 1e-106) | |
96 | ( | |
97 | 0x3ff0000000000000, | |
98 | 0x3950000000000000, | |
99 | 0x3950000000000000_3ff0000000000000, | |
100 | Round::NearestTiesToEven, | |
101 | ), | |
102 | // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105) | |
103 | ( | |
104 | 0x3950000000000000_3ff0000000000000, | |
105 | 0x3950000000000000, | |
106 | 0x3960000000000000_3ff0000000000000, | |
107 | Round::NearestTiesToEven, | |
108 | ), | |
109 | // (1 + 0) + (epsilon + 0) = (1 + epsilon) | |
110 | ( | |
111 | 0x3ff0000000000000, | |
112 | 0x0000000000000001, | |
113 | 0x0000000000000001_3ff0000000000000, | |
114 | Round::NearestTiesToEven, | |
115 | ), | |
116 | // FIXME: change 0xf950000000000000 to 0xf940000000000000, when | |
117 | // DoubleDouble's fallback is gone. | |
118 | // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX + | |
119 | // 1.11111... << (1023 - 52) | |
120 | ( | |
121 | 0xf950000000000000_7fefffffffffffff, | |
122 | 0x7c90000000000000, | |
123 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
124 | Round::NearestTiesToEven, | |
125 | ), | |
126 | // FIXME: change 0xf950000000000000 to 0xf940000000000000, when | |
127 | // DoubleDouble's fallback is gone. | |
128 | // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX + | |
129 | // 1.11111... << (1023 - 52) | |
130 | ( | |
131 | 0x7c90000000000000, | |
132 | 0xf950000000000000_7fefffffffffffff, | |
133 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
134 | Round::NearestTiesToEven, | |
135 | ), | |
136 | ]; | |
137 | ||
136023e0 | 138 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
139 | { |
140 | let mut a1 = DoubleDouble::from_bits(op1); | |
141 | let a2 = DoubleDouble::from_bits(op2); | |
142 | a1 = a1.add_r(a2, round).value; | |
143 | ||
144 | assert_eq!(expected, a1.to_bits(), "{:#x} + {:#x}", op1, op2); | |
145 | } | |
146 | { | |
147 | let a1 = DoubleDouble::from_bits(op1); | |
148 | let mut a2 = DoubleDouble::from_bits(op2); | |
149 | a2 = a2.add_r(a1, round).value; | |
150 | ||
151 | assert_eq!(expected, a2.to_bits(), "{:#x} + {:#x}", op2, op1); | |
152 | } | |
153 | } | |
154 | } | |
155 | ||
156 | #[test] | |
157 | fn ppc_double_double_subtract() { | |
158 | let data = [ | |
159 | // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105) | |
160 | ( | |
161 | 0x3ff0000000000000, | |
162 | 0xb960000000000000, | |
163 | 0x3960000000000000_3ff0000000000000, | |
164 | Round::NearestTiesToEven, | |
165 | ), | |
166 | // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106) | |
167 | ( | |
168 | 0x3ff0000000000000, | |
169 | 0xb950000000000000, | |
170 | 0x3950000000000000_3ff0000000000000, | |
171 | Round::NearestTiesToEven, | |
172 | ), | |
173 | ]; | |
174 | ||
136023e0 | 175 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
176 | let mut a1 = DoubleDouble::from_bits(op1); |
177 | let a2 = DoubleDouble::from_bits(op2); | |
178 | a1 = a1.sub_r(a2, round).value; | |
179 | ||
180 | assert_eq!(expected, a1.to_bits(), "{:#x} - {:#x}", op1, op2); | |
181 | } | |
182 | } | |
183 | ||
184 | #[test] | |
185 | fn ppc_double_double_multiply_special() { | |
186 | let data = [ | |
187 | // Category::NaN * Category::NaN = Category::NaN | |
dfeec247 | 188 | (0x7ff8000000000000, 0x7ff8000000000000, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 | 189 | // Category::NaN * Category::Zero = Category::NaN |
dfeec247 | 190 | (0x7ff8000000000000, 0, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 | 191 | // Category::NaN * Category::Infinity = Category::NaN |
dfeec247 | 192 | (0x7ff8000000000000, 0x7ff0000000000000, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 | 193 | // Category::NaN * Category::Normal = Category::NaN |
dfeec247 | 194 | (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 | 195 | // Category::Infinity * Category::Infinity = Category::Infinity |
dfeec247 | 196 | (0x7ff0000000000000, 0x7ff0000000000000, Category::Infinity, Round::NearestTiesToEven), |
3b2f2976 | 197 | // Category::Infinity * Category::Zero = Category::NaN |
dfeec247 | 198 | (0x7ff0000000000000, 0, Category::NaN, Round::NearestTiesToEven), |
3b2f2976 | 199 | // Category::Infinity * Category::Normal = Category::Infinity |
dfeec247 | 200 | (0x7ff0000000000000, 0x3ff0000000000000, Category::Infinity, Round::NearestTiesToEven), |
3b2f2976 XL |
201 | // Category::Zero * Category::Zero = Category::Zero |
202 | (0, 0, Category::Zero, Round::NearestTiesToEven), | |
203 | // Category::Zero * Category::Normal = Category::Zero | |
dfeec247 | 204 | (0, 0x3ff0000000000000, Category::Zero, Round::NearestTiesToEven), |
3b2f2976 XL |
205 | ]; |
206 | ||
136023e0 | 207 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
208 | { |
209 | let mut a1 = DoubleDouble::from_bits(op1); | |
210 | let a2 = DoubleDouble::from_bits(op2); | |
211 | a1 = a1.mul_r(a2, round).value; | |
212 | ||
213 | assert_eq!(expected, a1.category(), "{:#x} * {:#x}", op1, op2); | |
214 | } | |
215 | { | |
216 | let a1 = DoubleDouble::from_bits(op1); | |
217 | let mut a2 = DoubleDouble::from_bits(op2); | |
218 | a2 = a2.mul_r(a1, round).value; | |
219 | ||
220 | assert_eq!(expected, a2.category(), "{:#x} * {:#x}", op2, op1); | |
221 | } | |
222 | } | |
223 | } | |
224 | ||
225 | #[test] | |
226 | fn ppc_double_double_multiply() { | |
227 | let data = [ | |
228 | // 1/3 * 3 = 1.0 | |
229 | ( | |
230 | 0x3c75555555555556_3fd5555555555555, | |
231 | 0x4008000000000000, | |
232 | 0x3ff0000000000000, | |
233 | Round::NearestTiesToEven, | |
234 | ), | |
235 | // (1 + epsilon) * (1 + 0) = Category::Zero | |
236 | ( | |
237 | 0x0000000000000001_3ff0000000000000, | |
238 | 0x3ff0000000000000, | |
239 | 0x0000000000000001_3ff0000000000000, | |
240 | Round::NearestTiesToEven, | |
241 | ), | |
242 | // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon | |
243 | ( | |
244 | 0x0000000000000001_3ff0000000000000, | |
245 | 0x0000000000000001_3ff0000000000000, | |
246 | 0x0000000000000002_3ff0000000000000, | |
247 | Round::NearestTiesToEven, | |
248 | ), | |
249 | // -(1 + epsilon) * (1 + epsilon) = -1 | |
250 | ( | |
251 | 0x0000000000000001_bff0000000000000, | |
252 | 0x0000000000000001_3ff0000000000000, | |
253 | 0xbff0000000000000, | |
254 | Round::NearestTiesToEven, | |
255 | ), | |
256 | // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon | |
257 | ( | |
258 | 0x3fe0000000000000, | |
259 | 0x0000000000000002_3ff0000000000000, | |
260 | 0x0000000000000001_3fe0000000000000, | |
261 | Round::NearestTiesToEven, | |
262 | ), | |
263 | // (0.5 + 0) * (1 + epsilon) = 0.5 | |
264 | ( | |
265 | 0x3fe0000000000000, | |
266 | 0x0000000000000001_3ff0000000000000, | |
267 | 0x3fe0000000000000, | |
268 | Round::NearestTiesToEven, | |
269 | ), | |
270 | // __LDBL_MAX__ * (1 + 1 << 106) = inf | |
271 | ( | |
272 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
273 | 0x3950000000000000_3ff0000000000000, | |
274 | 0x7ff0000000000000, | |
275 | Round::NearestTiesToEven, | |
276 | ), | |
277 | // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=||| | |
278 | ( | |
279 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
280 | 0x3940000000000000_3ff0000000000000, | |
281 | 0x7c8fffffffffffff_7fefffffffffffff, | |
282 | Round::NearestTiesToEven, | |
283 | ), | |
284 | // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__ | |
285 | ( | |
286 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
287 | 0x3930000000000000_3ff0000000000000, | |
288 | 0x7c8ffffffffffffe_7fefffffffffffff, | |
289 | Round::NearestTiesToEven, | |
290 | ), | |
291 | ]; | |
292 | ||
136023e0 | 293 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
294 | { |
295 | let mut a1 = DoubleDouble::from_bits(op1); | |
296 | let a2 = DoubleDouble::from_bits(op2); | |
297 | a1 = a1.mul_r(a2, round).value; | |
298 | ||
299 | assert_eq!(expected, a1.to_bits(), "{:#x} * {:#x}", op1, op2); | |
300 | } | |
301 | { | |
302 | let a1 = DoubleDouble::from_bits(op1); | |
303 | let mut a2 = DoubleDouble::from_bits(op2); | |
304 | a2 = a2.mul_r(a1, round).value; | |
305 | ||
306 | assert_eq!(expected, a2.to_bits(), "{:#x} * {:#x}", op2, op1); | |
307 | } | |
308 | } | |
309 | } | |
310 | ||
311 | #[test] | |
312 | fn ppc_double_double_divide() { | |
313 | // FIXME: Only a sanity check for now. Add more edge cases when the | |
314 | // double-double algorithm is implemented. | |
315 | let data = [ | |
316 | // 1 / 3 = 1/3 | |
317 | ( | |
318 | 0x3ff0000000000000, | |
319 | 0x4008000000000000, | |
320 | 0x3c75555555555556_3fd5555555555555, | |
321 | Round::NearestTiesToEven, | |
322 | ), | |
323 | ]; | |
324 | ||
136023e0 | 325 | for (op1, op2, expected, round) in data { |
3b2f2976 XL |
326 | let mut a1 = DoubleDouble::from_bits(op1); |
327 | let a2 = DoubleDouble::from_bits(op2); | |
328 | a1 = a1.div_r(a2, round).value; | |
329 | ||
330 | assert_eq!(expected, a1.to_bits(), "{:#x} / {:#x}", op1, op2); | |
331 | } | |
332 | } | |
333 | ||
334 | #[test] | |
335 | fn ppc_double_double_remainder() { | |
336 | let data = [ | |
337 | // ieee_rem(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53) | |
338 | ( | |
339 | 0x3cb8000000000000_4008000000000000, | |
340 | 0x3ca4000000000000_3ff4000000000000, | |
341 | 0x3c90000000000000_3fe0000000000000, | |
342 | ), | |
343 | // ieee_rem(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53) | |
344 | ( | |
345 | 0x3cb8000000000000_4008000000000000, | |
346 | 0x3cac000000000000_3ffc000000000000, | |
347 | 0xbc90000000000000_bfe0000000000000, | |
348 | ), | |
349 | ]; | |
350 | ||
136023e0 | 351 | for (op1, op2, expected) in data { |
3b2f2976 XL |
352 | let a1 = DoubleDouble::from_bits(op1); |
353 | let a2 = DoubleDouble::from_bits(op2); | |
354 | let result = a1.ieee_rem(a2).value; | |
355 | ||
dfeec247 | 356 | assert_eq!(expected, result.to_bits(), "ieee_rem({:#x}, {:#x})", op1, op2); |
3b2f2976 XL |
357 | } |
358 | } | |
359 | ||
360 | #[test] | |
361 | fn ppc_double_double_mod() { | |
362 | let data = [ | |
363 | // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53) | |
364 | ( | |
365 | 0x3cb8000000000000_4008000000000000, | |
366 | 0x3ca4000000000000_3ff4000000000000, | |
367 | 0x3c90000000000000_3fe0000000000000, | |
368 | ), | |
369 | // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53) | |
370 | // 0xbc98000000000000 doesn't seem right, but it's what we currently have. | |
371 | // FIXME: investigate | |
372 | ( | |
373 | 0x3cb8000000000000_4008000000000000, | |
374 | 0x3cac000000000000_3ffc000000000000, | |
375 | 0xbc98000000000000_3ff4000000000001, | |
376 | ), | |
377 | ]; | |
378 | ||
136023e0 | 379 | for (op1, op2, expected) in data { |
3b2f2976 XL |
380 | let a1 = DoubleDouble::from_bits(op1); |
381 | let a2 = DoubleDouble::from_bits(op2); | |
382 | let r = (a1 % a2).value; | |
383 | ||
384 | assert_eq!(expected, r.to_bits(), "fmod({:#x}, {:#x})", op1, op2); | |
385 | } | |
386 | } | |
387 | ||
388 | #[test] | |
389 | fn ppc_double_double_fma() { | |
390 | // Sanity check for now. | |
391 | let mut a = "2".parse::<DoubleDouble>().unwrap(); | |
dfeec247 XL |
392 | a = a.mul_add("3".parse::<DoubleDouble>().unwrap(), "4".parse::<DoubleDouble>().unwrap()).value; |
393 | assert_eq!(Some(Ordering::Equal), "10".parse::<DoubleDouble>().unwrap().partial_cmp(&a)); | |
3b2f2976 XL |
394 | } |
395 | ||
396 | #[test] | |
397 | fn ppc_double_double_round_to_integral() { | |
398 | { | |
399 | let a = "1.5".parse::<DoubleDouble>().unwrap(); | |
400 | let a = a.round_to_integral(Round::NearestTiesToEven).value; | |
dfeec247 | 401 | assert_eq!(Some(Ordering::Equal), "2".parse::<DoubleDouble>().unwrap().partial_cmp(&a)); |
3b2f2976 XL |
402 | } |
403 | { | |
404 | let a = "2.5".parse::<DoubleDouble>().unwrap(); | |
405 | let a = a.round_to_integral(Round::NearestTiesToEven).value; | |
dfeec247 | 406 | assert_eq!(Some(Ordering::Equal), "2".parse::<DoubleDouble>().unwrap().partial_cmp(&a)); |
3b2f2976 XL |
407 | } |
408 | } | |
409 | ||
410 | #[test] | |
411 | fn ppc_double_double_compare() { | |
412 | let data = [ | |
413 | // (1 + 0) = (1 + 0) | |
dfeec247 | 414 | (0x3ff0000000000000, 0x3ff0000000000000, Some(Ordering::Equal)), |
3b2f2976 XL |
415 | // (1 + 0) < (1.00...1 + 0) |
416 | (0x3ff0000000000000, 0x3ff0000000000001, Some(Ordering::Less)), | |
417 | // (1.00...1 + 0) > (1 + 0) | |
dfeec247 | 418 | (0x3ff0000000000001, 0x3ff0000000000000, Some(Ordering::Greater)), |
3b2f2976 | 419 | // (1 + 0) < (1 + epsilon) |
dfeec247 | 420 | (0x3ff0000000000000, 0x0000000000000001_3ff0000000000001, Some(Ordering::Less)), |
3b2f2976 XL |
421 | // NaN != NaN |
422 | (0x7ff8000000000000, 0x7ff8000000000000, None), | |
423 | // (1 + 0) != NaN | |
424 | (0x3ff0000000000000, 0x7ff8000000000000, None), | |
425 | // Inf = Inf | |
dfeec247 | 426 | (0x7ff0000000000000, 0x7ff0000000000000, Some(Ordering::Equal)), |
3b2f2976 XL |
427 | ]; |
428 | ||
136023e0 | 429 | for (op1, op2, expected) in data { |
3b2f2976 XL |
430 | let a1 = DoubleDouble::from_bits(op1); |
431 | let a2 = DoubleDouble::from_bits(op2); | |
dfeec247 | 432 | assert_eq!(expected, a1.partial_cmp(&a2), "compare({:#x}, {:#x})", op1, op2,); |
3b2f2976 XL |
433 | } |
434 | } | |
435 | ||
436 | #[test] | |
437 | fn ppc_double_double_bitwise_eq() { | |
438 | let data = [ | |
439 | // (1 + 0) = (1 + 0) | |
440 | (0x3ff0000000000000, 0x3ff0000000000000, true), | |
441 | // (1 + 0) != (1.00...1 + 0) | |
442 | (0x3ff0000000000000, 0x3ff0000000000001, false), | |
443 | // NaN = NaN | |
444 | (0x7ff8000000000000, 0x7ff8000000000000, true), | |
445 | // NaN != NaN with a different bit pattern | |
dfeec247 | 446 | (0x7ff8000000000000, 0x3ff0000000000000_7ff8000000000000, false), |
3b2f2976 XL |
447 | // Inf = Inf |
448 | (0x7ff0000000000000, 0x7ff0000000000000, true), | |
449 | ]; | |
450 | ||
136023e0 | 451 | for (op1, op2, expected) in data { |
3b2f2976 XL |
452 | let a1 = DoubleDouble::from_bits(op1); |
453 | let a2 = DoubleDouble::from_bits(op2); | |
454 | assert_eq!(expected, a1.bitwise_eq(a2), "{:#x} = {:#x}", op1, op2); | |
455 | } | |
456 | } | |
457 | ||
458 | #[test] | |
459 | fn ppc_double_double_change_sign() { | |
460 | let float = DoubleDouble::from_bits(0xbcb0000000000000_400f000000000000); | |
461 | { | |
462 | let actual = float.copy_sign("1".parse::<DoubleDouble>().unwrap()); | |
463 | assert_eq!(0xbcb0000000000000_400f000000000000, actual.to_bits()); | |
464 | } | |
465 | { | |
466 | let actual = float.copy_sign("-1".parse::<DoubleDouble>().unwrap()); | |
467 | assert_eq!(0x3cb0000000000000_c00f000000000000, actual.to_bits()); | |
468 | } | |
469 | } | |
470 | ||
471 | #[test] | |
472 | fn ppc_double_double_factories() { | |
473 | assert_eq!(0, DoubleDouble::ZERO.to_bits()); | |
dfeec247 | 474 | assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, DoubleDouble::largest().to_bits()); |
3b2f2976 | 475 | assert_eq!(0x0000000000000001, DoubleDouble::SMALLEST.to_bits()); |
dfeec247 XL |
476 | assert_eq!(0x0360000000000000, DoubleDouble::smallest_normalized().to_bits()); |
477 | assert_eq!(0x0000000000000000_8000000000000000, (-DoubleDouble::ZERO).to_bits()); | |
478 | assert_eq!(0xfc8ffffffffffffe_ffefffffffffffff, (-DoubleDouble::largest()).to_bits()); | |
479 | assert_eq!(0x0000000000000000_8000000000000001, (-DoubleDouble::SMALLEST).to_bits()); | |
3b2f2976 XL |
480 | assert_eq!( |
481 | 0x0000000000000000_8360000000000000, | |
482 | (-DoubleDouble::smallest_normalized()).to_bits() | |
483 | ); | |
484 | assert!(DoubleDouble::SMALLEST.is_smallest()); | |
485 | assert!(DoubleDouble::largest().is_largest()); | |
486 | } | |
487 | ||
488 | #[test] | |
489 | fn ppc_double_double_is_denormal() { | |
490 | assert!(DoubleDouble::SMALLEST.is_denormal()); | |
491 | assert!(!DoubleDouble::largest().is_denormal()); | |
492 | assert!(!DoubleDouble::smallest_normalized().is_denormal()); | |
493 | { | |
494 | // (4 + 3) is not normalized | |
495 | let data = 0x4008000000000000_4010000000000000; | |
496 | assert!(DoubleDouble::from_bits(data).is_denormal()); | |
497 | } | |
498 | } | |
499 | ||
500 | #[test] | |
501 | fn ppc_double_double_exact_inverse() { | |
502 | assert!( | |
503 | "2.0" | |
504 | .parse::<DoubleDouble>() | |
505 | .unwrap() | |
506 | .get_exact_inverse() | |
507 | .unwrap() | |
508 | .bitwise_eq("0.5".parse::<DoubleDouble>().unwrap()) | |
509 | ); | |
510 | } | |
511 | ||
512 | #[test] | |
513 | fn ppc_double_double_scalbn() { | |
514 | // 3.0 + 3.0 << 53 | |
515 | let input = 0x3cb8000000000000_4008000000000000; | |
516 | let result = DoubleDouble::from_bits(input).scalbn(1); | |
517 | // 6.0 + 6.0 << 53 | |
518 | assert_eq!(0x3cc8000000000000_4018000000000000, result.to_bits()); | |
519 | } | |
520 | ||
521 | #[test] | |
522 | fn ppc_double_double_frexp() { | |
523 | // 3.0 + 3.0 << 53 | |
524 | let input = 0x3cb8000000000000_4008000000000000; | |
525 | let mut exp = 0; | |
526 | // 0.75 + 0.75 << 53 | |
527 | let result = DoubleDouble::from_bits(input).frexp(&mut exp); | |
528 | assert_eq!(2, exp); | |
529 | assert_eq!(0x3c98000000000000_3fe8000000000000, result.to_bits()); | |
530 | } |