carray 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_round.c
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
CArray#round(ndigits) and #round!(ndigits): each element rounded as Ruby's
|
|
4
|
+
Float#round(ndigits) and Integer#round(ndigits) round it, half away from
|
|
5
|
+
zero. The argument-free forms are the generated monop kernels; this file
|
|
6
|
+
takes over the method and hands them the calls without an argument.
|
|
7
|
+
|
|
8
|
+
---------------------------------------------------------------------------- */
|
|
9
|
+
|
|
10
|
+
#include <math.h>
|
|
11
|
+
#include <float.h>
|
|
12
|
+
|
|
13
|
+
#include "carray.h"
|
|
14
|
+
#include "carray_internal.h"
|
|
15
|
+
#include "ca_obj_face.h"
|
|
16
|
+
|
|
17
|
+
VALUE rb_ca_round (VALUE self); /* generated: round without digits */
|
|
18
|
+
VALUE rb_ca_round_bang (VALUE self);
|
|
19
|
+
|
|
20
|
+
static ID id_round;
|
|
21
|
+
|
|
22
|
+
/* The rounding of Float#round for ndigits > 0 (numeric.c, round_half_up
|
|
23
|
+
with its check for a product that came out one short). */
|
|
24
|
+
static double
|
|
25
|
+
ca_round_half_up (double x, double s)
|
|
26
|
+
{
|
|
27
|
+
double f, xs = x * s;
|
|
28
|
+
|
|
29
|
+
f = round(xs);
|
|
30
|
+
if ( x > 0 ) {
|
|
31
|
+
if ( (double)((f + 0.5) / s) <= x ) f += 1;
|
|
32
|
+
x = f;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
if ( (double)((f - 0.5) / s) >= x ) f -= 1;
|
|
36
|
+
x = f;
|
|
37
|
+
}
|
|
38
|
+
return x;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* numeric.c: float_round_overflow / float_round_underflow. When the first
|
|
42
|
+
holds, number * 10**ndigits is already an integer and the number is its
|
|
43
|
+
own answer; when the second holds, the answer is 0. */
|
|
44
|
+
static int
|
|
45
|
+
ca_round_overflow (long ndigits, int binexp)
|
|
46
|
+
{
|
|
47
|
+
enum { float_dig = DBL_DIG + 2 };
|
|
48
|
+
return ndigits >= float_dig - (binexp > 0 ? binexp / 4 : binexp / 3 - 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static int
|
|
52
|
+
ca_round_underflow (long ndigits, int binexp)
|
|
53
|
+
{
|
|
54
|
+
return ndigits < - (binexp > 0 ? binexp / 3 + 1 : binexp / 4);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* An integer |x| rounded to a multiple of 10**k (k >= 1), half away from
|
|
58
|
+
zero, as Integer#round(-k). Returns 0 when the answer does not fit in
|
|
59
|
+
64 bits, and sets *overflow. */
|
|
60
|
+
static uint64_t
|
|
61
|
+
ca_round_uint64 (uint64_t ax, long k, int *overflow)
|
|
62
|
+
{
|
|
63
|
+
uint64_t y = 1, q, rem, r;
|
|
64
|
+
long i;
|
|
65
|
+
|
|
66
|
+
*overflow = 0;
|
|
67
|
+
if ( k > 19 ) { /* 10**20 / 2 exceeds every 64-bit value */
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
for (i = 0; i < k; i++) {
|
|
71
|
+
y *= 10;
|
|
72
|
+
}
|
|
73
|
+
q = ax / y;
|
|
74
|
+
rem = ax % y;
|
|
75
|
+
r = q * y;
|
|
76
|
+
if ( rem >= y - y / 2 ) { /* rem * 2 >= y, without overflow */
|
|
77
|
+
if ( r > UINT64_MAX - y ) {
|
|
78
|
+
*overflow = 1;
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
r += y;
|
|
82
|
+
}
|
|
83
|
+
return r;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* x rounded as Float#round(ndigits) rounds it, for ndigits != 0. NaN and
|
|
87
|
+
the infinities are their own answer (Float#round raises for them when
|
|
88
|
+
ndigits <= 0; an array of floats keeps them as values). */
|
|
89
|
+
static double
|
|
90
|
+
ca_round_double (double x, long ndigits)
|
|
91
|
+
{
|
|
92
|
+
int binexp;
|
|
93
|
+
|
|
94
|
+
if ( x == 0.0 || ! isfinite(x) ) {
|
|
95
|
+
return x;
|
|
96
|
+
}
|
|
97
|
+
if ( ndigits > 0 ) {
|
|
98
|
+
frexp(x, &binexp);
|
|
99
|
+
if ( ca_round_overflow(ndigits, binexp) ) {
|
|
100
|
+
return x;
|
|
101
|
+
}
|
|
102
|
+
if ( ca_round_underflow(ndigits, binexp) ) {
|
|
103
|
+
return 0.0;
|
|
104
|
+
}
|
|
105
|
+
if ( ndigits > 14 ) {
|
|
106
|
+
/* pow(10, ndigits) may not be exact; Ruby rounds through a Rational. */
|
|
107
|
+
return NUM2DBL(rb_funcall(DBL2NUM(x), id_round, 1, LONG2NUM(ndigits)));
|
|
108
|
+
}
|
|
109
|
+
{
|
|
110
|
+
double f = pow(10, (double) ndigits);
|
|
111
|
+
return ca_round_half_up(x, f) / f;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
/* Ruby truncates to an Integer, then rounds the Integer. */
|
|
116
|
+
double t = trunc(x);
|
|
117
|
+
if ( fabs(t) < 18446744073709551616.0 ) { /* 2**64 */
|
|
118
|
+
int overflow;
|
|
119
|
+
uint64_t r = ca_round_uint64((uint64_t) fabs(t), -ndigits, &overflow);
|
|
120
|
+
if ( ! overflow ) {
|
|
121
|
+
return ( t < 0 ) ? -(double) r : (double) r;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return NUM2DBL(rb_funcall(DBL2NUM(x), id_round, 1, LONG2NUM(ndigits)));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#define ROUND_INT_LOOP(type, lo, hi, is_signed) \
|
|
129
|
+
{ \
|
|
130
|
+
type *p = (type *) ca->ptr; \
|
|
131
|
+
for (i = 0; i < ca->elements; i++) { \
|
|
132
|
+
int neg, overflow; \
|
|
133
|
+
uint64_t ax, r; \
|
|
134
|
+
if ( m && m[i] ) continue; \
|
|
135
|
+
neg = ( is_signed ) && ( (int64_t) p[i] < 0 ); \
|
|
136
|
+
ax = neg ? (uint64_t) 0 - (uint64_t)(int64_t) p[i] : (uint64_t) p[i]; \
|
|
137
|
+
r = ca_round_uint64(ax, -ndigits, &overflow); \
|
|
138
|
+
if ( overflow || ( neg ? r > (uint64_t) 0 - (uint64_t)(int64_t)(lo) \
|
|
139
|
+
: r > (uint64_t)(hi) ) ) { \
|
|
140
|
+
rb_raise(rb_eRangeError, \
|
|
141
|
+
"round: a value rounded to %ld digits does not fit " \
|
|
142
|
+
"data_type %s", ndigits, ca_type_name[ca->data_type]); \
|
|
143
|
+
} \
|
|
144
|
+
p[i] = neg ? (type)((uint64_t) 0 - r) : (type) r; \
|
|
145
|
+
} \
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* Rounds the cells of the entity `ca` in place; masked cells are left. */
|
|
149
|
+
static void
|
|
150
|
+
ca_round_entity (CArray *ca, long ndigits)
|
|
151
|
+
{
|
|
152
|
+
boolean8_t *m = NULL;
|
|
153
|
+
ca_size_t i;
|
|
154
|
+
|
|
155
|
+
if ( ca->mask ) {
|
|
156
|
+
m = (boolean8_t *) ca->mask->ptr;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
switch ( ca->data_type ) {
|
|
160
|
+
case CA_INT8: ROUND_INT_LOOP(int8_t, INT8_MIN, INT8_MAX, 1); break;
|
|
161
|
+
case CA_UINT8: ROUND_INT_LOOP(uint8_t, 0, UINT8_MAX, 0); break;
|
|
162
|
+
case CA_INT16: ROUND_INT_LOOP(int16_t, INT16_MIN, INT16_MAX, 1); break;
|
|
163
|
+
case CA_UINT16: ROUND_INT_LOOP(uint16_t, 0, UINT16_MAX, 0); break;
|
|
164
|
+
case CA_INT32: ROUND_INT_LOOP(int32_t, INT32_MIN, INT32_MAX, 1); break;
|
|
165
|
+
case CA_UINT32: ROUND_INT_LOOP(uint32_t, 0, UINT32_MAX, 0); break;
|
|
166
|
+
case CA_INT64: ROUND_INT_LOOP(int64_t, INT64_MIN, INT64_MAX, 1); break;
|
|
167
|
+
case CA_UINT64: ROUND_INT_LOOP(uint64_t, 0, UINT64_MAX, 0); break;
|
|
168
|
+
case CA_FLOAT32: {
|
|
169
|
+
float32_t *p = (float32_t *) ca->ptr;
|
|
170
|
+
for (i = 0; i < ca->elements; i++) {
|
|
171
|
+
if ( m && m[i] ) continue;
|
|
172
|
+
p[i] = (float32_t) ca_round_double((double) p[i], ndigits);
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case CA_FLOAT64: {
|
|
177
|
+
float64_t *p = (float64_t *) ca->ptr;
|
|
178
|
+
for (i = 0; i < ca->elements; i++) {
|
|
179
|
+
if ( m && m[i] ) continue;
|
|
180
|
+
p[i] = ca_round_double(p[i], ndigits);
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case CA_OBJECT: {
|
|
185
|
+
VALUE *p = (VALUE *) ca->ptr;
|
|
186
|
+
volatile VALUE nd = LONG2NUM(ndigits);
|
|
187
|
+
for (i = 0; i < ca->elements; i++) {
|
|
188
|
+
if ( m && m[i] ) continue;
|
|
189
|
+
p[i] = rb_funcall(p[i], id_round, 1, nd);
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
default:
|
|
194
|
+
rb_raise(rb_eCADataTypeError, "round: not defined for data_type %s",
|
|
195
|
+
ca_type_name[ca->data_type]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* The array to round: a boolean is rounded as its 0/1 int64 values, as
|
|
200
|
+
round without digits does. */
|
|
201
|
+
static VALUE
|
|
202
|
+
ca_round_source (VALUE self, VALUE vdigits, long *ndigits)
|
|
203
|
+
{
|
|
204
|
+
CArray *ca;
|
|
205
|
+
*ndigits = ca_integer_arg(vdigits, "ndigits", "round");
|
|
206
|
+
ca_face_refuse_numeric(self, "round", rb_eCADataTypeError);
|
|
207
|
+
GetCArray(self, ca);
|
|
208
|
+
if ( ca->data_type == CA_BOOLEAN ) {
|
|
209
|
+
self = rb_ca_wrap_readonly(self, INT2NUM(CA_INT64));
|
|
210
|
+
}
|
|
211
|
+
return self;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* A copy of `src` rounded to `ndigits`. Rounding to 0 digits is what round
|
|
215
|
+
without digits does (except for objects, which are asked with the digits);
|
|
216
|
+
an integer has no digits below 10**0 to round. */
|
|
217
|
+
static VALUE
|
|
218
|
+
ca_round_copy (VALUE src, long ndigits)
|
|
219
|
+
{
|
|
220
|
+
volatile VALUE out;
|
|
221
|
+
CArray *ca, *co;
|
|
222
|
+
GetCArray(src, ca);
|
|
223
|
+
if ( ndigits == 0 && ca->data_type != CA_OBJECT ) {
|
|
224
|
+
return rb_ca_round(src);
|
|
225
|
+
}
|
|
226
|
+
out = rb_ca_copy(src);
|
|
227
|
+
GetCArray(out, co);
|
|
228
|
+
if ( ndigits > 0 && ca_is_integer_type(co) ) {
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
ca_round_entity(co, ndigits);
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
static VALUE
|
|
236
|
+
rb_ca_round_digits (int argc, VALUE *argv, VALUE self)
|
|
237
|
+
{
|
|
238
|
+
long ndigits;
|
|
239
|
+
rb_check_arity(argc, 0, 1);
|
|
240
|
+
if ( argc == 0 ) {
|
|
241
|
+
return rb_ca_round(self);
|
|
242
|
+
}
|
|
243
|
+
self = ca_round_source(self, argv[0], &ndigits);
|
|
244
|
+
return ca_round_copy(self, ndigits);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static VALUE
|
|
248
|
+
rb_ca_round_digits_bang (int argc, VALUE *argv, VALUE self)
|
|
249
|
+
{
|
|
250
|
+
long ndigits;
|
|
251
|
+
volatile VALUE src, out;
|
|
252
|
+
rb_check_arity(argc, 0, 1);
|
|
253
|
+
if ( argc == 0 ) {
|
|
254
|
+
return rb_ca_round_bang(self);
|
|
255
|
+
}
|
|
256
|
+
rb_ca_modify(self);
|
|
257
|
+
src = ca_round_source(self, argv[0], &ndigits);
|
|
258
|
+
if ( src != self ) {
|
|
259
|
+
rb_raise(rb_eCADataTypeError,
|
|
260
|
+
"round!: a boolean array can not hold the rounded int64 values");
|
|
261
|
+
}
|
|
262
|
+
out = ca_round_copy(self, ndigits);
|
|
263
|
+
rb_ca_store_all(self, out);
|
|
264
|
+
return self;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
void
|
|
268
|
+
Init_carray_round (void)
|
|
269
|
+
{
|
|
270
|
+
id_round = rb_intern("round");
|
|
271
|
+
rb_define_method(rb_cCArray, "round", rb_ca_round_digits, -1);
|
|
272
|
+
rb_define_method(rb_cCArray, "round!", rb_ca_round_digits_bang, -1);
|
|
273
|
+
}
|