cyb70289 commented on a change in pull request #9841:
URL: https://github.com/apache/arrow/pull/9841#discussion_r604553475



##########
File path: cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
##########
@@ -233,6 +235,282 @@ struct DivideChecked {
   }
 };
 
+struct Power {
+  template <typename T, typename Arg0, typename Arg1>
+  static enable_if_signed_integer<T> Call(KernelContext* ctx, Arg0 left, Arg1 
right) {
+    Arg0 result = 1;
+    if (left == 0) {
+      if (right < 0) {
+        ARROW_PREDICT_FALSE(MultiplyWithOverflow(2, 
std::numeric_limits<Arg0>::max(), &result));
+        ctx->SetStatus(Status::Invalid("divide by zero"));
+        return result;
+      } else if (right == 0) {
+        return 1;
+      }
+      return 0;
+    } else if (right == INFINITY && abs(left) > 1) {
+      ARROW_PREDICT_FALSE(MultiplyWithOverflow(2, 
std::numeric_limits<Arg0>::max(), &result));
+      return result;
+    } else if (right == -INFINITY && abs(left) > 1) {
+      return 0;
+    }

Review comment:
       I don't see why it's so complicated. This function is only for integer 
power, all args are supposed to be integers (see checked version). So there 
will be no things like `infinity`, which is only for floating points. I think 
just verify that the exponent is non-negtive should be enough.

##########
File path: cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
##########
@@ -233,6 +235,282 @@ struct DivideChecked {
   }
 };
 
+struct Power {
+  template <typename T, typename Arg0, typename Arg1>
+  static enable_if_signed_integer<T> Call(KernelContext* ctx, Arg0 left, Arg1 
right) {
+    Arg0 result = 1;
+    if (left == 0) {
+      if (right < 0) {
+        ARROW_PREDICT_FALSE(MultiplyWithOverflow(2, 
std::numeric_limits<Arg0>::max(), &result));
+        ctx->SetStatus(Status::Invalid("divide by zero"));
+        return result;
+      } else if (right == 0) {
+        return 1;
+      }
+      return 0;
+    } else if (right == INFINITY && abs(left) > 1) {
+      ARROW_PREDICT_FALSE(MultiplyWithOverflow(2, 
std::numeric_limits<Arg0>::max(), &result));
+      return result;
+    } else if (right == -INFINITY && abs(left) > 1) {
+      return 0;
+    }
+
+    if (right > 0) {
+      for (Arg1 i = 0; i < right; i++) {
+        if (ARROW_PREDICT_FALSE(MultiplyWithOverflow(result, left, &result))) {
+          ctx->SetStatus(Status::Invalid("overflow"));
+        }
+      }
+    } else {
+      for (Arg1 i = 0; i < -right; i++) {

Review comment:
       Again, negative exponent is illegal for integer power. This function is 
returning T, which is an integer.
   We'd better reference implementations from other software first, e.g., 
https://numpy.org/doc/stable/reference/generated/numpy.power.html




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to