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.
Files changed (247) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +568 -0
  3. data/README.md +6 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +220 -0
  7. data/ext/ca_axis_group.c +201 -123
  8. data/ext/ca_binop_dispatch.c +46 -52
  9. data/ext/ca_binop_dispatch.h +1 -1
  10. data/ext/ca_categorical_iterator.c +249 -183
  11. data/ext/ca_compare.c +7 -12
  12. data/ext/ca_for_buffer.h +21 -68
  13. data/ext/ca_group_iter.c +38 -23
  14. data/ext/ca_kernel_iterator.c +1765 -2076
  15. data/ext/ca_kernel_iterator.h +584 -566
  16. data/ext/ca_monop_dispatch.c +86 -63
  17. data/ext/ca_monop_dispatch.h +5 -0
  18. data/ext/ca_obj_array.c +223 -56
  19. data/ext/ca_obj_bincmp.c +172 -138
  20. data/ext/ca_obj_binop.c +116 -230
  21. data/ext/ca_obj_bitarray.c +40 -26
  22. data/ext/ca_obj_bitfield.c +100 -68
  23. data/ext/ca_obj_block.c +19 -9
  24. data/ext/ca_obj_byte_swap.c +45 -46
  25. data/ext/ca_obj_const_string.c +269 -44
  26. data/ext/ca_obj_face.c +612 -89
  27. data/ext/ca_obj_face.h +111 -47
  28. data/ext/ca_obj_fake.c +36 -79
  29. data/ext/ca_obj_farray.c +7 -3
  30. data/ext/ca_obj_field.c +33 -8
  31. data/ext/ca_obj_fixlen_string.c +23 -24
  32. data/ext/ca_obj_grid.c +541 -210
  33. data/ext/ca_obj_meld.c +331 -111
  34. data/ext/ca_obj_moncmp.c +80 -65
  35. data/ext/ca_obj_monop.c +177 -149
  36. data/ext/ca_obj_object.c +664 -248
  37. data/ext/ca_obj_record.c +63 -23
  38. data/ext/ca_obj_reduce.c +18 -16
  39. data/ext/ca_obj_refer.c +140 -58
  40. data/ext/ca_obj_remap.c +85 -24
  41. data/ext/ca_obj_repeat.c +24 -9
  42. data/ext/ca_obj_roll.c +121 -16
  43. data/ext/ca_obj_select.c +61 -58
  44. data/ext/ca_obj_select_axis.c +73 -107
  45. data/ext/ca_obj_shift.c +32 -102
  46. data/ext/ca_obj_stack.c +372 -122
  47. data/ext/ca_obj_stride.c +348 -140
  48. data/ext/ca_obj_string.c +88 -22
  49. data/ext/ca_obj_tile.c +38 -21
  50. data/ext/ca_obj_time.c +45 -31
  51. data/ext/ca_obj_timedelta.c +43 -29
  52. data/ext/ca_obj_transpose.c +17 -6
  53. data/ext/ca_obj_triop.c +125 -141
  54. data/ext/ca_obj_window.c +330 -44
  55. data/ext/ca_op_ipower.c +24 -11
  56. data/ext/ca_op_powi.h +57 -30
  57. data/ext/ca_pow5_table.h +656 -0
  58. data/ext/ca_sort_kernels.h +70 -0
  59. data/ext/ca_sweep_engine.c +104 -81
  60. data/ext/ca_sweep_engine.h +7 -20
  61. data/ext/ca_triop_dispatch.c +4 -1
  62. data/ext/ca_triop_dispatch.h +5 -2
  63. data/ext/caframe_csv_reader.c +542 -0
  64. data/ext/carray.h +241 -92
  65. data/ext/carray_access.c +608 -276
  66. data/ext/carray_address_basis.c +494 -97
  67. data/ext/carray_attribute.c +129 -4
  68. data/ext/carray_bincount.c +39 -7
  69. data/ext/carray_broadcast.c +56 -19
  70. data/ext/carray_build_flags.h +1 -1
  71. data/ext/carray_call_cfunc.c +108 -28
  72. data/ext/carray_cast.c +1576 -223
  73. data/ext/carray_cast_func.rb +77 -24
  74. data/ext/carray_class.c +4 -3
  75. data/ext/carray_conversion.c +208 -75
  76. data/ext/carray_copy.c +82 -24
  77. data/ext/carray_core.c +646 -162
  78. data/ext/carray_count.c +171 -88
  79. data/ext/carray_element.c +94 -60
  80. data/ext/carray_factorize.c +670 -324
  81. data/ext/carray_generate.c +260 -83
  82. data/ext/carray_histogram.c +209 -106
  83. data/ext/carray_hold.c +14 -16
  84. data/ext/carray_index_classifier.c +422 -243
  85. data/ext/carray_internal.h +692 -3
  86. data/ext/carray_kernels_bincmp.c +7 -0
  87. data/ext/carray_kernels_binop.c +487 -120
  88. data/ext/carray_kernels_init.c +653 -50
  89. data/ext/carray_kernels_moncmp.c +15 -8
  90. data/ext/carray_kernels_monop.c +99 -43
  91. data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
  92. data/ext/carray_kernels_reduce_boolean.c +112 -36
  93. data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
  94. data/ext/carray_kernels_reduce_extreme.c +3032 -2892
  95. data/ext/carray_kernels_reduce_variance.c +439 -500
  96. data/ext/carray_kernels_scan.c +1097 -488
  97. data/ext/carray_kernels_search.c +3787 -2176
  98. data/ext/carray_kernels_sort.c +1200 -920
  99. data/ext/carray_kernels_triop.c +479 -7
  100. data/ext/carray_key_windows.c +216 -0
  101. data/ext/carray_lazy.c +967 -153
  102. data/ext/carray_loop.c +81 -65
  103. data/ext/carray_mask.c +910 -324
  104. data/ext/carray_math_kernel.h +1 -0
  105. data/ext/carray_median_percentile.c +299 -100
  106. data/ext/carray_memory_view.c +872 -758
  107. data/ext/carray_operator.c +1171 -364
  108. data/ext/carray_order.c +505 -133
  109. data/ext/carray_partition.c +112 -65
  110. data/ext/carray_random.c +327 -239
  111. data/ext/carray_round.c +273 -0
  112. data/ext/carray_scatter.c +346 -78
  113. data/ext/carray_segment.c +257 -0
  114. data/ext/carray_slab.c +249 -86
  115. data/ext/carray_sort.c +224 -227
  116. data/ext/carray_sort_kernel.c +8 -1
  117. data/ext/carray_struct.c +118 -39
  118. data/ext/carray_test.c +193 -69
  119. data/ext/carray_time_text.c +1182 -0
  120. data/ext/carray_undef.c +4 -0
  121. data/ext/carray_utils.c +579 -113
  122. data/ext/extconf.rb +27 -2
  123. data/ext/mk_call_cfunc.rb +19 -4
  124. data/ext/mk_pow5_table.rb +35 -0
  125. data/ext/mkkernel.rb +1202 -1014
  126. data/ext/ruby_carray.c +17 -5
  127. data/ext/version.h +4 -4
  128. data/ext/version.rb +4 -2
  129. data/lib/carray/attribute.rb +160 -17
  130. data/lib/carray/autoload_carray.rb +23 -27
  131. data/lib/carray/autoload_method_extension.rb +20 -5
  132. data/lib/carray/axis_group.rb +360 -63
  133. data/lib/carray/basics.rb +162 -28
  134. data/lib/carray/bincount_nd.rb +18 -2
  135. data/lib/carray/block_iterator.rb +231 -58
  136. data/lib/carray/boolean_reduce.rb +34 -42
  137. data/lib/carray/categorical.rb +242 -52
  138. data/lib/carray/categorical_iterator.rb +437 -827
  139. data/lib/carray/complex.rb +41 -34
  140. data/lib/carray/conditional.rb +150 -14
  141. data/lib/carray/const_string.rb +59 -4
  142. data/lib/carray/construct.rb +15 -11
  143. data/lib/carray/data_type_extension.rb +1 -0
  144. data/lib/carray/distance_limit.rb +77 -0
  145. data/lib/carray/fixlen_string.rb +7 -1
  146. data/lib/carray/frame/column_verbs.rb +70 -0
  147. data/lib/carray/frame/concat.rb +157 -6
  148. data/lib/carray/frame/convert.rb +82 -7
  149. data/lib/carray/frame/csv_parser.rb +688 -87
  150. data/lib/carray/frame/describe.rb +80 -0
  151. data/lib/carray/frame/frame.rb +369 -45
  152. data/lib/carray/frame/group.rb +631 -90
  153. data/lib/carray/frame/io.rb +506 -79
  154. data/lib/carray/frame/join.rb +411 -62
  155. data/lib/carray/frame/records.rb +116 -19
  156. data/lib/carray/frame/reshape.rb +455 -0
  157. data/lib/carray/frame/sort.rb +30 -18
  158. data/lib/carray/frame/verbs.rb +868 -61
  159. data/lib/carray/frame/windows.rb +117 -0
  160. data/lib/carray/frame.rb +4 -0
  161. data/lib/carray/fuse_source.rb +118 -2
  162. data/lib/carray/fusion.rb +257 -42
  163. data/lib/carray/histogram.rb +6 -1
  164. data/lib/carray/inspect.rb +54 -13
  165. data/lib/carray/iterator.rb +99 -9
  166. data/lib/carray/key_windows.rb +620 -0
  167. data/lib/carray/lazy.rb +216 -193
  168. data/lib/carray/mask_gap_fill.rb +112 -92
  169. data/lib/carray/math.rb +32 -19
  170. data/lib/carray/meld_reduce.rb +52 -21
  171. data/lib/carray/methods/align_addr.rb +8 -4
  172. data/lib/carray/methods/bin.rb +26 -18
  173. data/lib/carray/methods/bincount.rb +18 -2
  174. data/lib/carray/methods/bit_string.rb +15 -4
  175. data/lib/carray/methods/choose.rb +16 -3
  176. data/lib/carray/methods/composition.rb +18 -10
  177. data/lib/carray/methods/factorize.rb +2 -2
  178. data/lib/carray/methods/gather_nd.rb +25 -5
  179. data/lib/carray/methods/insert_block.rb +9 -14
  180. data/lib/carray/methods/is_between.rb +59 -0
  181. data/lib/carray/methods/is_in.rb +140 -10
  182. data/lib/carray/methods/join.rb +2 -7
  183. data/lib/carray/methods/lag.rb +49 -0
  184. data/lib/carray/methods/locate_addr.rb +182 -45
  185. data/lib/carray/methods/mode.rb +18 -1
  186. data/lib/carray/methods/nunique.rb +11 -6
  187. data/lib/carray/methods/repeat.rb +1 -20
  188. data/lib/carray/methods/resize.rb +21 -23
  189. data/lib/carray/methods/snap.rb +34 -12
  190. data/lib/carray/methods/unique.rb +11 -2
  191. data/lib/carray/methods/value_counts.rb +4 -11
  192. data/lib/carray/record_order.rb +208 -0
  193. data/lib/carray/rng.rb +3 -0
  194. data/lib/carray/runtime.rb +65 -17
  195. data/lib/carray/segment_iterator.rb +1221 -0
  196. data/lib/carray/serialize.rb +214 -30
  197. data/lib/carray/slab_iterator.rb +101 -27
  198. data/lib/carray/stack.rb +10 -4
  199. data/lib/carray/string.rb +105 -5
  200. data/lib/carray/string_operation_extension.rb +12 -4
  201. data/lib/carray/struct.rb +137 -58
  202. data/lib/carray/struct_builder.rb +124 -17
  203. data/lib/carray/time.rb +1222 -186
  204. data/lib/carray/window_iterator.rb +242 -81
  205. data/lib/carray.rb +9 -2
  206. data/yard-stubs/ca_obj_array.rb +4 -4
  207. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  208. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  209. data/yard-stubs/ca_obj_fake.rb +1 -1
  210. data/yard-stubs/ca_obj_field.rb +5 -1
  211. data/yard-stubs/ca_obj_grid.rb +21 -10
  212. data/yard-stubs/ca_obj_refer.rb +5 -4
  213. data/yard-stubs/ca_obj_roll.rb +2 -3
  214. data/yard-stubs/ca_obj_shift.rb +5 -1
  215. data/yard-stubs/ca_obj_stride.rb +10 -7
  216. data/yard-stubs/ca_obj_tile.rb +1 -1
  217. data/yard-stubs/ca_obj_transpose.rb +1 -1
  218. data/yard-stubs/ca_obj_window.rb +9 -5
  219. data/yard-stubs/carray_access.rb +11 -5
  220. data/yard-stubs/carray_attribute.rb +0 -5
  221. data/yard-stubs/carray_broadcast.rb +1 -1
  222. data/yard-stubs/carray_cast.rb +88 -43
  223. data/yard-stubs/carray_conversion.rb +15 -2
  224. data/yard-stubs/carray_copy.rb +12 -5
  225. data/yard-stubs/carray_core.rb +3 -3
  226. data/yard-stubs/carray_count.rb +9 -0
  227. data/yard-stubs/carray_element.rb +10 -4
  228. data/yard-stubs/carray_generate.rb +21 -1
  229. data/yard-stubs/carray_lazy.rb +5 -1
  230. data/yard-stubs/carray_loop.rb +4 -1
  231. data/yard-stubs/carray_mask.rb +60 -12
  232. data/yard-stubs/carray_math.rb +52 -14
  233. data/yard-stubs/carray_median_percentile.rb +15 -8
  234. data/yard-stubs/carray_memory_view.rb +40 -23
  235. data/yard-stubs/carray_order.rb +61 -29
  236. data/yard-stubs/carray_random.rb +13 -4
  237. data/yard-stubs/carray_scatter.rb +21 -9
  238. data/yard-stubs/carray_segment.rb +72 -0
  239. data/yard-stubs/carray_slab.rb +10 -2
  240. data/yard-stubs/carray_sort.rb +49 -8
  241. data/yard-stubs/carray_test.rb +15 -3
  242. data/yard-stubs/carray_utils.rb +0 -26
  243. metadata +19 -5
  244. data/ext/ca_for_each_element.h +0 -239
  245. data/ext/carray_kernels_map.c +0 -3467
  246. data/lib/carray/arrow_tensor.rb +0 -401
  247. data/lib/carray/table.rb +0 -108
@@ -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
+ }