14 math.ops - Mathematical Opcodes
20 Parrot's library of mathematical ops.
22 To use this library of ops, add this directive to your PIR:
34 ########################################
36 =item B<cmod>(out INT, in INT, in INT)
38 =item B<cmod>(invar PMC, invar PMC, in INT)
40 =item B<cmod>(invar PMC, invar PMC, invar PMC)
42 NOTE: This "uncorrected mod" algorithm uses the C language's built-in
43 mod operator (x % y), which is
45 ... the remainder when x is divided by y, and thus is zero
46 when y divides x exactly.
48 The direction of truncation for / and the sign of the result
49 for % are machine-dependent for negative operands, as is the
50 action taken on overflow or underflow.
55 ... if the second operand is 0, the result is undefined.
56 Otherwise, it is always true that (a/b)*b + a%b is equal to z. If
57 both operands are non-negative, then the remainder is non-
58 negative and smaller than the divisor; if not, it is guaranteed
59 only that the absolute value of the remainder is smaller than
60 the absolute value of the divisor.
63 This op is provided for those who need it (such as speed-sensitive
64 applications with heavy use of mod, but using it only with positive
65 arguments), but a more mathematically useful mod based on ** floor(x/y)
66 and defined with y == 0 is provided by the mod op.
68 [1] Brian W. Kernighan and Dennis M. Ritchie, *The C Programming
69 Language*, Second Edition. Prentice Hall, 1988.
71 If the denominator is zero, a 'Divide by zero' exception is thrown.
75 inline op cmod(out INT, in INT, in INT) :base_core {
78 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
79 EXCEPTION_DIV_BY_ZERO,
81 goto ADDRESS(handler);
86 inline op cmod(invar PMC, invar PMC, in INT) :base_core {
90 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
91 EXCEPTION_DIV_BY_ZERO,
93 goto ADDRESS(handler);
96 result = VTABLE_get_integer(interp, $2) % $3;
98 $1 = Parrot_pmc_new_init_int(interp, VTABLE_type(interp, $2), result);
101 inline op cmod(invar PMC, invar PMC, invar PMC) :base_core {
103 INTVAL value = VTABLE_get_integer(interp, $3);
106 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
107 EXCEPTION_DIV_BY_ZERO,
109 goto ADDRESS(handler);
112 result = VTABLE_get_integer(interp, $2) % value;
114 $1 = Parrot_pmc_new_init_int(interp, VTABLE_type(interp, $2), result);
117 ########################################
119 =item B<cmod>(out NUM, in NUM, in NUM)
121 =item B<cmod>(invar PMC, invar PMC, in NUM)
123 NOTE: This "uncorrected mod" algorithm uses the built-in C math library's
124 fmod() function, which computes
126 ... the remainder of dividing x by y. The return value is
127 x - n * y, where n is the quotient of x / y, rounded towards
129 -- fmod() manpage on RedHat Linux 7.0
131 In addition, fmod() returns
133 the remainder, unless y is zero, when the function fails and
136 According to page 251 of [1], the result when y is zero is implementation-
139 This op is provided for those who need it, but a more mathematically
140 useful numeric mod based on floor(x/y) instead of truncate(x/y) and
141 defined with y == 0 is provided by the mod op.
143 [1] Brian W. Kernighan and Dennis M. Ritchie, *The C Programming
144 Language*, Second Edition. Prentice Hall, 1988.
146 If the denominator is zero, a 'Divide by zero' exception is thrown.
150 inline op cmod(out NUM, in NUM, in NUM) :base_core {
152 if (FLOAT_IS_ZERO($3)) {
153 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
154 EXCEPTION_DIV_BY_ZERO,
156 goto ADDRESS(handler);
161 inline op cmod(invar PMC, invar PMC, in NUM) :base_core {
165 if (FLOAT_IS_ZERO(value)) {
166 opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
167 EXCEPTION_DIV_BY_ZERO,
169 goto ADDRESS(handler);
172 result = fmod(VTABLE_get_integer(interp, $2), value);
174 $1 = Parrot_pmc_new_init_int(interp,
175 VTABLE_type(interp, $2), (INTVAL)result);
182 ###############################################################################
184 =head2 Pseudorandom number operations
186 These operations perform various pseudorandom number operations.
190 =item B<rand>(out NUM)
192 Set $1 to a random floating point number between 0 and 1, inclusive.
196 inline op rand(out NUM) {
197 $1 = Parrot_float_rand(0);
200 =item B<rand>(out INT)
202 Set $1 to a random integer between C<[-2^31, 2^31)> .
206 inline op rand(out INT) {
207 $1 = Parrot_int_rand(0);
210 =item B<rand>(out NUM, in NUM)
212 Set $1 to a random floating point number between 0 and and $2, inclusive.
216 inline op rand(out NUM, in NUM) {
217 $1 = $2 * Parrot_float_rand(0);
220 =item B<rand>(out INT, in INT)
222 Set $1 to a integer between 0 and and $2, inclusive.
226 inline op rand(out INT, in INT) {
227 $1 = Parrot_range_rand(0, $2, 0);
230 =item B<rand>(out NUM, in NUM, in NUM)
232 Set $1 to a random floating point number between $2 and and $3, inclusive.
236 inline op rand(out NUM, in NUM, in NUM) {
237 $1 = $2 + ($3 - $2) * Parrot_float_rand(0);
240 =item B<srand>(in NUM)
242 Set the random number seed to $1. $1 is casted to an INTVAL.
246 inline op srand(in NUM) {
247 Parrot_srand((INTVAL)$1);
250 =item B<srand>(in INT)
252 Set the random number seed to $1.
256 inline op srand(in INT) {
257 Parrot_srand((INTVAL)$1);
260 =item B<rand>(out INT, in INT, in INT)
262 Set $1 to a integer between $2 and and $3, inclusive.
266 inline op rand(out INT, in INT, in INT) {
267 $1 = Parrot_range_rand($2, $3, 0);
276 Copyright (C) 2001-2009, Parrot Foundation.
280 This program is free software. It is subject to the same license
281 as the Parrot interpreter itself.
288 * c-file-style: "parrot"
290 * vim: expandtab shiftwidth=4: