main.c (1719B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include <stdint.h> 20 #include "stdlib/ndarray/base/wrap_index.h" 21 22 /** 23 * Wraps an index on the interval `[0,max]`. 24 * 25 * @param idx index 26 * @param max maximum index (should be nonnegative) 27 * @return index 28 * 29 * @example 30 * #include "stdlib/ndarray/base/wrap_index.h" 31 * 32 * int64_t idx = stdlib_ndarray_wrap_index( 13, 10 ); 33 * // returns 2 34 */ 35 int64_t stdlib_ndarray_wrap_index( int64_t idx, int64_t max ) { 36 int64_t mp1 = max + 1; // WARNING: possibility of overflow (although, in practice, `max` should never be that large) 37 if ( idx < 0 ) { 38 idx += mp1; // slight optimization to avoid modulo arithmetic when |idx| <= max+1 39 if ( idx < 0 ) { 40 idx -= mp1*( (int64_t)( idx/mp1 ) ); // this is equivalent to `idx mod mp1`, where the result has same sign as dividend (i.e., `idx`); cannot use `%` as the sign of the result is implementation defined in C 41 if ( idx != 0 ) { 42 idx += mp1; 43 } 44 } 45 return idx; 46 } 47 if ( idx > max ) { 48 idx -= mp1; // slight optimization to avoid modulo arithmetic when max+1 < idx <= 2*(max+1) 49 if ( idx > max ) { 50 idx %= mp1; 51 } 52 return idx; 53 } 54 return idx; 55 }