1use arrow_buffer::{i256, ArrowNativeType, IntervalDayTime, IntervalMonthDayNano};
19use arrow_schema::ArrowError;
20use half::f16;
21use num::complex::ComplexFloat;
22use std::cmp::Ordering;
23
24pub trait ArrowNativeTypeOp: ArrowNativeType {
42 const ZERO: Self;
44
45 const ONE: Self;
47
48 const MIN_TOTAL_ORDER: Self;
52
53 const MAX_TOTAL_ORDER: Self;
57
58 fn add_checked(self, rhs: Self) -> Result<Self, ArrowError>;
60
61 fn add_wrapping(self, rhs: Self) -> Self;
63
64 fn sub_checked(self, rhs: Self) -> Result<Self, ArrowError>;
66
67 fn sub_wrapping(self, rhs: Self) -> Self;
69
70 fn mul_checked(self, rhs: Self) -> Result<Self, ArrowError>;
72
73 fn mul_wrapping(self, rhs: Self) -> Self;
75
76 fn div_checked(self, rhs: Self) -> Result<Self, ArrowError>;
78
79 fn div_wrapping(self, rhs: Self) -> Self;
81
82 fn mod_checked(self, rhs: Self) -> Result<Self, ArrowError>;
84
85 fn mod_wrapping(self, rhs: Self) -> Self;
87
88 fn neg_checked(self) -> Result<Self, ArrowError>;
90
91 fn neg_wrapping(self) -> Self;
93
94 fn pow_checked(self, exp: u32) -> Result<Self, ArrowError>;
96
97 fn pow_wrapping(self, exp: u32) -> Self;
99
100 fn is_zero(self) -> bool;
102
103 fn compare(self, rhs: Self) -> Ordering;
105
106 fn is_eq(self, rhs: Self) -> bool;
108
109 #[inline]
111 fn is_ne(self, rhs: Self) -> bool {
112 !self.is_eq(rhs)
113 }
114
115 #[inline]
117 fn is_lt(self, rhs: Self) -> bool {
118 self.compare(rhs).is_lt()
119 }
120
121 #[inline]
123 fn is_le(self, rhs: Self) -> bool {
124 self.compare(rhs).is_le()
125 }
126
127 #[inline]
129 fn is_gt(self, rhs: Self) -> bool {
130 self.compare(rhs).is_gt()
131 }
132
133 #[inline]
135 fn is_ge(self, rhs: Self) -> bool {
136 self.compare(rhs).is_ge()
137 }
138}
139
140macro_rules! native_type_op {
141 ($t:tt) => {
142 native_type_op!($t, 0, 1);
143 };
144 ($t:tt, $zero:expr, $one: expr) => {
145 native_type_op!($t, $zero, $one, $t::MIN, $t::MAX);
146 };
147 ($t:tt, $zero:expr, $one: expr, $min: expr, $max: expr) => {
148 impl ArrowNativeTypeOp for $t {
149 const ZERO: Self = $zero;
150 const ONE: Self = $one;
151 const MIN_TOTAL_ORDER: Self = $min;
152 const MAX_TOTAL_ORDER: Self = $max;
153
154 #[inline]
155 fn add_checked(self, rhs: Self) -> Result<Self, ArrowError> {
156 self.checked_add(rhs).ok_or_else(|| {
157 ArrowError::ArithmeticOverflow(format!(
158 "Overflow happened on: {:?} + {:?}",
159 self, rhs
160 ))
161 })
162 }
163
164 #[inline]
165 fn add_wrapping(self, rhs: Self) -> Self {
166 self.wrapping_add(rhs)
167 }
168
169 #[inline]
170 fn sub_checked(self, rhs: Self) -> Result<Self, ArrowError> {
171 self.checked_sub(rhs).ok_or_else(|| {
172 ArrowError::ArithmeticOverflow(format!(
173 "Overflow happened on: {:?} - {:?}",
174 self, rhs
175 ))
176 })
177 }
178
179 #[inline]
180 fn sub_wrapping(self, rhs: Self) -> Self {
181 self.wrapping_sub(rhs)
182 }
183
184 #[inline]
185 fn mul_checked(self, rhs: Self) -> Result<Self, ArrowError> {
186 self.checked_mul(rhs).ok_or_else(|| {
187 ArrowError::ArithmeticOverflow(format!(
188 "Overflow happened on: {:?} * {:?}",
189 self, rhs
190 ))
191 })
192 }
193
194 #[inline]
195 fn mul_wrapping(self, rhs: Self) -> Self {
196 self.wrapping_mul(rhs)
197 }
198
199 #[inline]
200 fn div_checked(self, rhs: Self) -> Result<Self, ArrowError> {
201 if rhs.is_zero() {
202 Err(ArrowError::DivideByZero)
203 } else {
204 self.checked_div(rhs).ok_or_else(|| {
205 ArrowError::ArithmeticOverflow(format!(
206 "Overflow happened on: {:?} / {:?}",
207 self, rhs
208 ))
209 })
210 }
211 }
212
213 #[inline]
214 fn div_wrapping(self, rhs: Self) -> Self {
215 self.wrapping_div(rhs)
216 }
217
218 #[inline]
219 fn mod_checked(self, rhs: Self) -> Result<Self, ArrowError> {
220 if rhs.is_zero() {
221 Err(ArrowError::DivideByZero)
222 } else {
223 self.checked_rem(rhs).ok_or_else(|| {
224 ArrowError::ArithmeticOverflow(format!(
225 "Overflow happened on: {:?} % {:?}",
226 self, rhs
227 ))
228 })
229 }
230 }
231
232 #[inline]
233 fn mod_wrapping(self, rhs: Self) -> Self {
234 self.wrapping_rem(rhs)
235 }
236
237 #[inline]
238 fn neg_checked(self) -> Result<Self, ArrowError> {
239 self.checked_neg().ok_or_else(|| {
240 ArrowError::ArithmeticOverflow(format!("Overflow happened on: - {:?}", self))
241 })
242 }
243
244 #[inline]
245 fn pow_checked(self, exp: u32) -> Result<Self, ArrowError> {
246 self.checked_pow(exp).ok_or_else(|| {
247 ArrowError::ArithmeticOverflow(format!(
248 "Overflow happened on: {:?} ^ {exp:?}",
249 self
250 ))
251 })
252 }
253
254 #[inline]
255 fn pow_wrapping(self, exp: u32) -> Self {
256 self.wrapping_pow(exp)
257 }
258
259 #[inline]
260 fn neg_wrapping(self) -> Self {
261 self.wrapping_neg()
262 }
263
264 #[inline]
265 fn is_zero(self) -> bool {
266 self == Self::ZERO
267 }
268
269 #[inline]
270 fn compare(self, rhs: Self) -> Ordering {
271 self.cmp(&rhs)
272 }
273
274 #[inline]
275 fn is_eq(self, rhs: Self) -> bool {
276 self == rhs
277 }
278 }
279 };
280}
281
282native_type_op!(i8);
283native_type_op!(i16);
284native_type_op!(i32);
285native_type_op!(i64);
286native_type_op!(i128);
287native_type_op!(u8);
288native_type_op!(u16);
289native_type_op!(u32);
290native_type_op!(u64);
291native_type_op!(i256, i256::ZERO, i256::ONE, i256::MIN, i256::MAX);
292
293native_type_op!(IntervalDayTime, IntervalDayTime::ZERO, IntervalDayTime::ONE);
294native_type_op!(
295 IntervalMonthDayNano,
296 IntervalMonthDayNano::ZERO,
297 IntervalMonthDayNano::ONE
298);
299
300macro_rules! native_type_float_op {
301 ($t:tt, $zero:expr, $one:expr, $min:expr, $max:expr) => {
302 impl ArrowNativeTypeOp for $t {
303 const ZERO: Self = $zero;
304 const ONE: Self = $one;
305 const MIN_TOTAL_ORDER: Self = $min;
306 const MAX_TOTAL_ORDER: Self = $max;
307
308 #[inline]
309 fn add_checked(self, rhs: Self) -> Result<Self, ArrowError> {
310 Ok(self + rhs)
311 }
312
313 #[inline]
314 fn add_wrapping(self, rhs: Self) -> Self {
315 self + rhs
316 }
317
318 #[inline]
319 fn sub_checked(self, rhs: Self) -> Result<Self, ArrowError> {
320 Ok(self - rhs)
321 }
322
323 #[inline]
324 fn sub_wrapping(self, rhs: Self) -> Self {
325 self - rhs
326 }
327
328 #[inline]
329 fn mul_checked(self, rhs: Self) -> Result<Self, ArrowError> {
330 Ok(self * rhs)
331 }
332
333 #[inline]
334 fn mul_wrapping(self, rhs: Self) -> Self {
335 self * rhs
336 }
337
338 #[inline]
339 fn div_checked(self, rhs: Self) -> Result<Self, ArrowError> {
340 if rhs.is_zero() {
341 Err(ArrowError::DivideByZero)
342 } else {
343 Ok(self / rhs)
344 }
345 }
346
347 #[inline]
348 fn div_wrapping(self, rhs: Self) -> Self {
349 self / rhs
350 }
351
352 #[inline]
353 fn mod_checked(self, rhs: Self) -> Result<Self, ArrowError> {
354 if rhs.is_zero() {
355 Err(ArrowError::DivideByZero)
356 } else {
357 Ok(self % rhs)
358 }
359 }
360
361 #[inline]
362 fn mod_wrapping(self, rhs: Self) -> Self {
363 self % rhs
364 }
365
366 #[inline]
367 fn neg_checked(self) -> Result<Self, ArrowError> {
368 Ok(-self)
369 }
370
371 #[inline]
372 fn neg_wrapping(self) -> Self {
373 -self
374 }
375
376 #[inline]
377 fn pow_checked(self, exp: u32) -> Result<Self, ArrowError> {
378 Ok(self.powi(exp as i32))
379 }
380
381 #[inline]
382 fn pow_wrapping(self, exp: u32) -> Self {
383 self.powi(exp as i32)
384 }
385
386 #[inline]
387 fn is_zero(self) -> bool {
388 self == $zero
389 }
390
391 #[inline]
392 fn compare(self, rhs: Self) -> Ordering {
393 <$t>::total_cmp(&self, &rhs)
394 }
395
396 #[inline]
397 fn is_eq(self, rhs: Self) -> bool {
398 self.to_bits() == rhs.to_bits()
402 }
403 }
404 };
405}
406
407native_type_float_op!(
410 f16,
411 f16::ZERO,
412 f16::ONE,
413 f16::from_bits(-1 as _),
414 f16::from_bits(i16::MAX as _)
415);
416native_type_float_op!(
418 f32,
419 0.,
420 1.,
421 unsafe {
422 #[allow(unnecessary_transmutes)]
425 std::mem::transmute(-1_i32)
426 },
427 unsafe {
428 #[allow(unnecessary_transmutes)]
431 std::mem::transmute(i32::MAX)
432 }
433);
434native_type_float_op!(
435 f64,
436 0.,
437 1.,
438 unsafe {
439 #[allow(unnecessary_transmutes)]
442 std::mem::transmute(-1_i64)
443 },
444 unsafe {
445 #[allow(unnecessary_transmutes)]
448 std::mem::transmute(i64::MAX)
449 }
450);
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455
456 macro_rules! assert_approx_eq {
457 ( $x: expr, $y: expr ) => {{
458 assert_approx_eq!($x, $y, 1.0e-4)
459 }};
460 ( $x: expr, $y: expr, $tol: expr ) => {{
461 let x_val = $x;
462 let y_val = $y;
463 let diff = f64::from((x_val - y_val).abs());
464 assert!(
465 diff <= $tol,
466 "{} != {} (with tolerance = {})",
467 x_val,
468 y_val,
469 $tol
470 );
471 }};
472 }
473
474 #[test]
475 fn test_native_type_is_zero() {
476 assert!(0_i8.is_zero());
477 assert!(0_i16.is_zero());
478 assert!(0_i32.is_zero());
479 assert!(0_i64.is_zero());
480 assert!(0_i128.is_zero());
481 assert!(i256::ZERO.is_zero());
482 assert!(0_u8.is_zero());
483 assert!(0_u16.is_zero());
484 assert!(0_u32.is_zero());
485 assert!(0_u64.is_zero());
486 assert!(f16::ZERO.is_zero());
487 assert!(0.0_f32.is_zero());
488 assert!(0.0_f64.is_zero());
489 }
490
491 #[test]
492 fn test_native_type_comparison() {
493 assert!(8_i8.is_eq(8_i8));
495 assert!(8_i16.is_eq(8_i16));
496 assert!(8_i32.is_eq(8_i32));
497 assert!(8_i64.is_eq(8_i64));
498 assert!(8_i128.is_eq(8_i128));
499 assert!(i256::from_parts(8, 0).is_eq(i256::from_parts(8, 0)));
500 assert!(8_u8.is_eq(8_u8));
501 assert!(8_u16.is_eq(8_u16));
502 assert!(8_u32.is_eq(8_u32));
503 assert!(8_u64.is_eq(8_u64));
504 assert!(f16::from_f32(8.0).is_eq(f16::from_f32(8.0)));
505 assert!(8.0_f32.is_eq(8.0_f32));
506 assert!(8.0_f64.is_eq(8.0_f64));
507
508 assert!(8_i8.is_ne(1_i8));
510 assert!(8_i16.is_ne(1_i16));
511 assert!(8_i32.is_ne(1_i32));
512 assert!(8_i64.is_ne(1_i64));
513 assert!(8_i128.is_ne(1_i128));
514 assert!(i256::from_parts(8, 0).is_ne(i256::from_parts(1, 0)));
515 assert!(8_u8.is_ne(1_u8));
516 assert!(8_u16.is_ne(1_u16));
517 assert!(8_u32.is_ne(1_u32));
518 assert!(8_u64.is_ne(1_u64));
519 assert!(f16::from_f32(8.0).is_ne(f16::from_f32(1.0)));
520 assert!(8.0_f32.is_ne(1.0_f32));
521 assert!(8.0_f64.is_ne(1.0_f64));
522
523 assert!(8_i8.is_lt(10_i8));
525 assert!(8_i16.is_lt(10_i16));
526 assert!(8_i32.is_lt(10_i32));
527 assert!(8_i64.is_lt(10_i64));
528 assert!(8_i128.is_lt(10_i128));
529 assert!(i256::from_parts(8, 0).is_lt(i256::from_parts(10, 0)));
530 assert!(8_u8.is_lt(10_u8));
531 assert!(8_u16.is_lt(10_u16));
532 assert!(8_u32.is_lt(10_u32));
533 assert!(8_u64.is_lt(10_u64));
534 assert!(f16::from_f32(8.0).is_lt(f16::from_f32(10.0)));
535 assert!(8.0_f32.is_lt(10.0_f32));
536 assert!(8.0_f64.is_lt(10.0_f64));
537
538 assert!(8_i8.is_gt(1_i8));
540 assert!(8_i16.is_gt(1_i16));
541 assert!(8_i32.is_gt(1_i32));
542 assert!(8_i64.is_gt(1_i64));
543 assert!(8_i128.is_gt(1_i128));
544 assert!(i256::from_parts(8, 0).is_gt(i256::from_parts(1, 0)));
545 assert!(8_u8.is_gt(1_u8));
546 assert!(8_u16.is_gt(1_u16));
547 assert!(8_u32.is_gt(1_u32));
548 assert!(8_u64.is_gt(1_u64));
549 assert!(f16::from_f32(8.0).is_gt(f16::from_f32(1.0)));
550 assert!(8.0_f32.is_gt(1.0_f32));
551 assert!(8.0_f64.is_gt(1.0_f64));
552 }
553
554 #[test]
555 fn test_native_type_add() {
556 assert_eq!(8_i8.add_wrapping(2_i8), 10_i8);
558 assert_eq!(8_i16.add_wrapping(2_i16), 10_i16);
559 assert_eq!(8_i32.add_wrapping(2_i32), 10_i32);
560 assert_eq!(8_i64.add_wrapping(2_i64), 10_i64);
561 assert_eq!(8_i128.add_wrapping(2_i128), 10_i128);
562 assert_eq!(
563 i256::from_parts(8, 0).add_wrapping(i256::from_parts(2, 0)),
564 i256::from_parts(10, 0)
565 );
566 assert_eq!(8_u8.add_wrapping(2_u8), 10_u8);
567 assert_eq!(8_u16.add_wrapping(2_u16), 10_u16);
568 assert_eq!(8_u32.add_wrapping(2_u32), 10_u32);
569 assert_eq!(8_u64.add_wrapping(2_u64), 10_u64);
570 assert_eq!(
571 f16::from_f32(8.0).add_wrapping(f16::from_f32(2.0)),
572 f16::from_f32(10.0)
573 );
574 assert_eq!(8.0_f32.add_wrapping(2.0_f32), 10_f32);
575 assert_eq!(8.0_f64.add_wrapping(2.0_f64), 10_f64);
576
577 assert_eq!(8_i8.add_checked(2_i8).unwrap(), 10_i8);
579 assert_eq!(8_i16.add_checked(2_i16).unwrap(), 10_i16);
580 assert_eq!(8_i32.add_checked(2_i32).unwrap(), 10_i32);
581 assert_eq!(8_i64.add_checked(2_i64).unwrap(), 10_i64);
582 assert_eq!(8_i128.add_checked(2_i128).unwrap(), 10_i128);
583 assert_eq!(
584 i256::from_parts(8, 0)
585 .add_checked(i256::from_parts(2, 0))
586 .unwrap(),
587 i256::from_parts(10, 0)
588 );
589 assert_eq!(8_u8.add_checked(2_u8).unwrap(), 10_u8);
590 assert_eq!(8_u16.add_checked(2_u16).unwrap(), 10_u16);
591 assert_eq!(8_u32.add_checked(2_u32).unwrap(), 10_u32);
592 assert_eq!(8_u64.add_checked(2_u64).unwrap(), 10_u64);
593 assert_eq!(
594 f16::from_f32(8.0).add_checked(f16::from_f32(2.0)).unwrap(),
595 f16::from_f32(10.0)
596 );
597 assert_eq!(8.0_f32.add_checked(2.0_f32).unwrap(), 10_f32);
598 assert_eq!(8.0_f64.add_checked(2.0_f64).unwrap(), 10_f64);
599 }
600
601 #[test]
602 fn test_native_type_sub() {
603 assert_eq!(8_i8.sub_wrapping(2_i8), 6_i8);
605 assert_eq!(8_i16.sub_wrapping(2_i16), 6_i16);
606 assert_eq!(8_i32.sub_wrapping(2_i32), 6_i32);
607 assert_eq!(8_i64.sub_wrapping(2_i64), 6_i64);
608 assert_eq!(8_i128.sub_wrapping(2_i128), 6_i128);
609 assert_eq!(
610 i256::from_parts(8, 0).sub_wrapping(i256::from_parts(2, 0)),
611 i256::from_parts(6, 0)
612 );
613 assert_eq!(8_u8.sub_wrapping(2_u8), 6_u8);
614 assert_eq!(8_u16.sub_wrapping(2_u16), 6_u16);
615 assert_eq!(8_u32.sub_wrapping(2_u32), 6_u32);
616 assert_eq!(8_u64.sub_wrapping(2_u64), 6_u64);
617 assert_eq!(
618 f16::from_f32(8.0).sub_wrapping(f16::from_f32(2.0)),
619 f16::from_f32(6.0)
620 );
621 assert_eq!(8.0_f32.sub_wrapping(2.0_f32), 6_f32);
622 assert_eq!(8.0_f64.sub_wrapping(2.0_f64), 6_f64);
623
624 assert_eq!(8_i8.sub_checked(2_i8).unwrap(), 6_i8);
626 assert_eq!(8_i16.sub_checked(2_i16).unwrap(), 6_i16);
627 assert_eq!(8_i32.sub_checked(2_i32).unwrap(), 6_i32);
628 assert_eq!(8_i64.sub_checked(2_i64).unwrap(), 6_i64);
629 assert_eq!(8_i128.sub_checked(2_i128).unwrap(), 6_i128);
630 assert_eq!(
631 i256::from_parts(8, 0)
632 .sub_checked(i256::from_parts(2, 0))
633 .unwrap(),
634 i256::from_parts(6, 0)
635 );
636 assert_eq!(8_u8.sub_checked(2_u8).unwrap(), 6_u8);
637 assert_eq!(8_u16.sub_checked(2_u16).unwrap(), 6_u16);
638 assert_eq!(8_u32.sub_checked(2_u32).unwrap(), 6_u32);
639 assert_eq!(8_u64.sub_checked(2_u64).unwrap(), 6_u64);
640 assert_eq!(
641 f16::from_f32(8.0).sub_checked(f16::from_f32(2.0)).unwrap(),
642 f16::from_f32(6.0)
643 );
644 assert_eq!(8.0_f32.sub_checked(2.0_f32).unwrap(), 6_f32);
645 assert_eq!(8.0_f64.sub_checked(2.0_f64).unwrap(), 6_f64);
646 }
647
648 #[test]
649 fn test_native_type_mul() {
650 assert_eq!(8_i8.mul_wrapping(2_i8), 16_i8);
652 assert_eq!(8_i16.mul_wrapping(2_i16), 16_i16);
653 assert_eq!(8_i32.mul_wrapping(2_i32), 16_i32);
654 assert_eq!(8_i64.mul_wrapping(2_i64), 16_i64);
655 assert_eq!(8_i128.mul_wrapping(2_i128), 16_i128);
656 assert_eq!(
657 i256::from_parts(8, 0).mul_wrapping(i256::from_parts(2, 0)),
658 i256::from_parts(16, 0)
659 );
660 assert_eq!(8_u8.mul_wrapping(2_u8), 16_u8);
661 assert_eq!(8_u16.mul_wrapping(2_u16), 16_u16);
662 assert_eq!(8_u32.mul_wrapping(2_u32), 16_u32);
663 assert_eq!(8_u64.mul_wrapping(2_u64), 16_u64);
664 assert_eq!(
665 f16::from_f32(8.0).mul_wrapping(f16::from_f32(2.0)),
666 f16::from_f32(16.0)
667 );
668 assert_eq!(8.0_f32.mul_wrapping(2.0_f32), 16_f32);
669 assert_eq!(8.0_f64.mul_wrapping(2.0_f64), 16_f64);
670
671 assert_eq!(8_i8.mul_checked(2_i8).unwrap(), 16_i8);
673 assert_eq!(8_i16.mul_checked(2_i16).unwrap(), 16_i16);
674 assert_eq!(8_i32.mul_checked(2_i32).unwrap(), 16_i32);
675 assert_eq!(8_i64.mul_checked(2_i64).unwrap(), 16_i64);
676 assert_eq!(8_i128.mul_checked(2_i128).unwrap(), 16_i128);
677 assert_eq!(
678 i256::from_parts(8, 0)
679 .mul_checked(i256::from_parts(2, 0))
680 .unwrap(),
681 i256::from_parts(16, 0)
682 );
683 assert_eq!(8_u8.mul_checked(2_u8).unwrap(), 16_u8);
684 assert_eq!(8_u16.mul_checked(2_u16).unwrap(), 16_u16);
685 assert_eq!(8_u32.mul_checked(2_u32).unwrap(), 16_u32);
686 assert_eq!(8_u64.mul_checked(2_u64).unwrap(), 16_u64);
687 assert_eq!(
688 f16::from_f32(8.0).mul_checked(f16::from_f32(2.0)).unwrap(),
689 f16::from_f32(16.0)
690 );
691 assert_eq!(8.0_f32.mul_checked(2.0_f32).unwrap(), 16_f32);
692 assert_eq!(8.0_f64.mul_checked(2.0_f64).unwrap(), 16_f64);
693 }
694
695 #[test]
696 fn test_native_type_div() {
697 assert_eq!(8_i8.div_wrapping(2_i8), 4_i8);
699 assert_eq!(8_i16.div_wrapping(2_i16), 4_i16);
700 assert_eq!(8_i32.div_wrapping(2_i32), 4_i32);
701 assert_eq!(8_i64.div_wrapping(2_i64), 4_i64);
702 assert_eq!(8_i128.div_wrapping(2_i128), 4_i128);
703 assert_eq!(
704 i256::from_parts(8, 0).div_wrapping(i256::from_parts(2, 0)),
705 i256::from_parts(4, 0)
706 );
707 assert_eq!(8_u8.div_wrapping(2_u8), 4_u8);
708 assert_eq!(8_u16.div_wrapping(2_u16), 4_u16);
709 assert_eq!(8_u32.div_wrapping(2_u32), 4_u32);
710 assert_eq!(8_u64.div_wrapping(2_u64), 4_u64);
711 assert_eq!(
712 f16::from_f32(8.0).div_wrapping(f16::from_f32(2.0)),
713 f16::from_f32(4.0)
714 );
715 assert_eq!(8.0_f32.div_wrapping(2.0_f32), 4_f32);
716 assert_eq!(8.0_f64.div_wrapping(2.0_f64), 4_f64);
717
718 assert_eq!(8_i8.div_checked(2_i8).unwrap(), 4_i8);
720 assert_eq!(8_i16.div_checked(2_i16).unwrap(), 4_i16);
721 assert_eq!(8_i32.div_checked(2_i32).unwrap(), 4_i32);
722 assert_eq!(8_i64.div_checked(2_i64).unwrap(), 4_i64);
723 assert_eq!(8_i128.div_checked(2_i128).unwrap(), 4_i128);
724 assert_eq!(
725 i256::from_parts(8, 0)
726 .div_checked(i256::from_parts(2, 0))
727 .unwrap(),
728 i256::from_parts(4, 0)
729 );
730 assert_eq!(8_u8.div_checked(2_u8).unwrap(), 4_u8);
731 assert_eq!(8_u16.div_checked(2_u16).unwrap(), 4_u16);
732 assert_eq!(8_u32.div_checked(2_u32).unwrap(), 4_u32);
733 assert_eq!(8_u64.div_checked(2_u64).unwrap(), 4_u64);
734 assert_eq!(
735 f16::from_f32(8.0).div_checked(f16::from_f32(2.0)).unwrap(),
736 f16::from_f32(4.0)
737 );
738 assert_eq!(8.0_f32.div_checked(2.0_f32).unwrap(), 4_f32);
739 assert_eq!(8.0_f64.div_checked(2.0_f64).unwrap(), 4_f64);
740 }
741
742 #[test]
743 fn test_native_type_mod() {
744 assert_eq!(9_i8.mod_wrapping(2_i8), 1_i8);
746 assert_eq!(9_i16.mod_wrapping(2_i16), 1_i16);
747 assert_eq!(9_i32.mod_wrapping(2_i32), 1_i32);
748 assert_eq!(9_i64.mod_wrapping(2_i64), 1_i64);
749 assert_eq!(9_i128.mod_wrapping(2_i128), 1_i128);
750 assert_eq!(
751 i256::from_parts(9, 0).mod_wrapping(i256::from_parts(2, 0)),
752 i256::from_parts(1, 0)
753 );
754 assert_eq!(9_u8.mod_wrapping(2_u8), 1_u8);
755 assert_eq!(9_u16.mod_wrapping(2_u16), 1_u16);
756 assert_eq!(9_u32.mod_wrapping(2_u32), 1_u32);
757 assert_eq!(9_u64.mod_wrapping(2_u64), 1_u64);
758 assert_eq!(
759 f16::from_f32(9.0).mod_wrapping(f16::from_f32(2.0)),
760 f16::from_f32(1.0)
761 );
762 assert_eq!(9.0_f32.mod_wrapping(2.0_f32), 1_f32);
763 assert_eq!(9.0_f64.mod_wrapping(2.0_f64), 1_f64);
764
765 assert_eq!(9_i8.mod_checked(2_i8).unwrap(), 1_i8);
767 assert_eq!(9_i16.mod_checked(2_i16).unwrap(), 1_i16);
768 assert_eq!(9_i32.mod_checked(2_i32).unwrap(), 1_i32);
769 assert_eq!(9_i64.mod_checked(2_i64).unwrap(), 1_i64);
770 assert_eq!(9_i128.mod_checked(2_i128).unwrap(), 1_i128);
771 assert_eq!(
772 i256::from_parts(9, 0)
773 .mod_checked(i256::from_parts(2, 0))
774 .unwrap(),
775 i256::from_parts(1, 0)
776 );
777 assert_eq!(9_u8.mod_checked(2_u8).unwrap(), 1_u8);
778 assert_eq!(9_u16.mod_checked(2_u16).unwrap(), 1_u16);
779 assert_eq!(9_u32.mod_checked(2_u32).unwrap(), 1_u32);
780 assert_eq!(9_u64.mod_checked(2_u64).unwrap(), 1_u64);
781 assert_eq!(
782 f16::from_f32(9.0).mod_checked(f16::from_f32(2.0)).unwrap(),
783 f16::from_f32(1.0)
784 );
785 assert_eq!(9.0_f32.mod_checked(2.0_f32).unwrap(), 1_f32);
786 assert_eq!(9.0_f64.mod_checked(2.0_f64).unwrap(), 1_f64);
787 }
788
789 #[test]
790 fn test_native_type_neg() {
791 assert_eq!(8_i8.neg_wrapping(), -8_i8);
793 assert_eq!(8_i16.neg_wrapping(), -8_i16);
794 assert_eq!(8_i32.neg_wrapping(), -8_i32);
795 assert_eq!(8_i64.neg_wrapping(), -8_i64);
796 assert_eq!(8_i128.neg_wrapping(), -8_i128);
797 assert_eq!(i256::from_parts(8, 0).neg_wrapping(), i256::from_i128(-8));
798 assert_eq!(8_u8.neg_wrapping(), u8::MAX - 7_u8);
799 assert_eq!(8_u16.neg_wrapping(), u16::MAX - 7_u16);
800 assert_eq!(8_u32.neg_wrapping(), u32::MAX - 7_u32);
801 assert_eq!(8_u64.neg_wrapping(), u64::MAX - 7_u64);
802 assert_eq!(f16::from_f32(8.0).neg_wrapping(), f16::from_f32(-8.0));
803 assert_eq!(8.0_f32.neg_wrapping(), -8_f32);
804 assert_eq!(8.0_f64.neg_wrapping(), -8_f64);
805
806 assert_eq!(8_i8.neg_checked().unwrap(), -8_i8);
808 assert_eq!(8_i16.neg_checked().unwrap(), -8_i16);
809 assert_eq!(8_i32.neg_checked().unwrap(), -8_i32);
810 assert_eq!(8_i64.neg_checked().unwrap(), -8_i64);
811 assert_eq!(8_i128.neg_checked().unwrap(), -8_i128);
812 assert_eq!(
813 i256::from_parts(8, 0).neg_checked().unwrap(),
814 i256::from_i128(-8)
815 );
816 assert!(8_u8.neg_checked().is_err());
817 assert!(8_u16.neg_checked().is_err());
818 assert!(8_u32.neg_checked().is_err());
819 assert!(8_u64.neg_checked().is_err());
820 assert_eq!(
821 f16::from_f32(8.0).neg_checked().unwrap(),
822 f16::from_f32(-8.0)
823 );
824 assert_eq!(8.0_f32.neg_checked().unwrap(), -8_f32);
825 assert_eq!(8.0_f64.neg_checked().unwrap(), -8_f64);
826 }
827
828 #[test]
829 fn test_native_type_pow() {
830 assert_eq!(8_i8.pow_wrapping(2_u32), 64_i8);
832 assert_eq!(8_i16.pow_wrapping(2_u32), 64_i16);
833 assert_eq!(8_i32.pow_wrapping(2_u32), 64_i32);
834 assert_eq!(8_i64.pow_wrapping(2_u32), 64_i64);
835 assert_eq!(8_i128.pow_wrapping(2_u32), 64_i128);
836 assert_eq!(
837 i256::from_parts(8, 0).pow_wrapping(2_u32),
838 i256::from_parts(64, 0)
839 );
840 assert_eq!(8_u8.pow_wrapping(2_u32), 64_u8);
841 assert_eq!(8_u16.pow_wrapping(2_u32), 64_u16);
842 assert_eq!(8_u32.pow_wrapping(2_u32), 64_u32);
843 assert_eq!(8_u64.pow_wrapping(2_u32), 64_u64);
844 assert_approx_eq!(f16::from_f32(8.0).pow_wrapping(2_u32), f16::from_f32(64.0));
845 assert_approx_eq!(8.0_f32.pow_wrapping(2_u32), 64_f32);
846 assert_approx_eq!(8.0_f64.pow_wrapping(2_u32), 64_f64);
847
848 assert_eq!(8_i8.pow_checked(2_u32).unwrap(), 64_i8);
850 assert_eq!(8_i16.pow_checked(2_u32).unwrap(), 64_i16);
851 assert_eq!(8_i32.pow_checked(2_u32).unwrap(), 64_i32);
852 assert_eq!(8_i64.pow_checked(2_u32).unwrap(), 64_i64);
853 assert_eq!(8_i128.pow_checked(2_u32).unwrap(), 64_i128);
854 assert_eq!(
855 i256::from_parts(8, 0).pow_checked(2_u32).unwrap(),
856 i256::from_parts(64, 0)
857 );
858 assert_eq!(8_u8.pow_checked(2_u32).unwrap(), 64_u8);
859 assert_eq!(8_u16.pow_checked(2_u32).unwrap(), 64_u16);
860 assert_eq!(8_u32.pow_checked(2_u32).unwrap(), 64_u32);
861 assert_eq!(8_u64.pow_checked(2_u32).unwrap(), 64_u64);
862 assert_approx_eq!(
863 f16::from_f32(8.0).pow_checked(2_u32).unwrap(),
864 f16::from_f32(64.0)
865 );
866 assert_approx_eq!(8.0_f32.pow_checked(2_u32).unwrap(), 64_f32);
867 assert_approx_eq!(8.0_f64.pow_checked(2_u32).unwrap(), 64_f64);
868 }
869
870 #[test]
871 fn test_float_total_order_min_max() {
872 assert!(<f64 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(f64::NEG_INFINITY));
873 assert!(<f64 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f64::INFINITY));
874
875 assert!(<f64 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_nan());
876 assert!(<f64 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_sign_negative());
877 assert!(<f64 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(-f64::NAN));
878
879 assert!(<f64 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_nan());
880 assert!(<f64 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_sign_positive());
881 assert!(<f64 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f64::NAN));
882
883 assert!(<f32 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(f32::NEG_INFINITY));
884 assert!(<f32 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f32::INFINITY));
885
886 assert!(<f32 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_nan());
887 assert!(<f32 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_sign_negative());
888 assert!(<f32 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(-f32::NAN));
889
890 assert!(<f32 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_nan());
891 assert!(<f32 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_sign_positive());
892 assert!(<f32 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f32::NAN));
893
894 assert!(<f16 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(f16::NEG_INFINITY));
895 assert!(<f16 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f16::INFINITY));
896
897 assert!(<f16 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_nan());
898 assert!(<f16 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_sign_negative());
899 assert!(<f16 as ArrowNativeTypeOp>::MIN_TOTAL_ORDER.is_lt(-f16::NAN));
900
901 assert!(<f16 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_nan());
902 assert!(<f16 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_sign_positive());
903 assert!(<f16 as ArrowNativeTypeOp>::MAX_TOTAL_ORDER.is_gt(f16::NAN));
904 }
905}