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