tagged release 0.7.1
[parrot.git] / src / pmc / float.pmc
blobd315627d8a878bbbe2aae0c82f0f539e9cecd8ff
1 /*
2 Copyright (C) 2003-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/float.pmc - Floating-point number
9 =head1 DESCRIPTION
11 C<Float> extends C<scalar> to provide floating-point number operations.
13 =head2 Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
23 pmclass Float extends scalar provides float provides scalar {
27 =item C<void init()>
29 Initializes the number to zero.
31 =cut
35     VTABLE void init() {
36         PMC_num_val(SELF) = 0.0;
37     }
41 =item C<PMC *new_from_string(STRING *rep, INTVAL flags)>
43 Class method to construct an Integer from the string representation C<rep>.
45 =cut
48     VTABLE PMC *new_from_string(STRING *rep, INTVAL flags) {
49         const INTVAL type = SELF->vtable->base_type;
50         PMC * const res =
51             (flags & PObj_constant_FLAG)
52                 ? constant_pmc_new(INTERP, type)
53                 : pmc_new(INTERP, type);
55         PMC_num_val(res) = string_to_num(INTERP, rep);
56         return res;
57     }
61 =item C<FLOATVAL get_number()>
63 Returns the value of the number.
65 =cut
69     VTABLE FLOATVAL get_number() {
70         return PMC_num_val(SELF);
71     }
75 =item C<INTVAL get_integer()>
77 Returns an integer representation of the number (by casting).
79 =cut
83     VTABLE INTVAL get_integer() {
84         /* two steps avoid casting warnings */
85         FLOATVAL n = SELF.get_number();
86         return (INTVAL) n;
87     }
91 =item C<INTVAL get_bool()>
93 Evaluates the number as a boolean, i.e. it's true if it's not zero.
95 =cut
99     VTABLE INTVAL get_bool() {
100         const FLOATVAL f = SELF.get_number();
101         return !FLOAT_IS_ZERO(f);
102     }
106 =item C<STRING *get_string()>
108 Returns a Parrot string representation of the number.
110 =item C<STRING *get_repr()>
112 =cut
116     VTABLE STRING *get_string() {
117         return string_from_num(INTERP, SELF.get_number());
118     }
120     VTABLE STRING *get_repr() {
121         const FLOATVAL val      = SELF.get_number();
122         const double d          = fabs((double)val);
123         const char * const sign = signbit(val) ? "-" : "";
124         return Parrot_sprintf_c(INTERP, "%s" FLOATVAL_FMT, sign, d);
125     }
129 =item C<void set_integer_native(INTVAL value)>
131 =item C<void set_bool(INTVAL value)>
133 =cut
137     VTABLE void set_integer_native(INTVAL value) {
138         SELF.morph(enum_class_Integer);
139         SELF.set_integer_native(value);
140     }
142     VTABLE void set_bool(INTVAL value) {
143         SELF.morph(enum_class_Boolean);
144         SELF.set_bool(value);
145     }
149 =item C<void set_number_native(FLOATVAL value)>
151 Sets the value of the number to C<value>.
153 =cut
157     VTABLE void set_number_native(FLOATVAL value) {
158         PMC_num_val(SELF) = value;
159     }
163 =item C<void set_number_same(PMC *value)>
165 Sets the value of the number to the value of C<*value>.
167 =cut
171     VTABLE void set_number_same(PMC *value) {
172         PMC_num_val(SELF) = PMC_num_val(value);
173     }
177 =item C<void set_string_native(STRING *value)>
179 Sets the value of the number to the value of C<*value>.
181 Note that this method morphs the number into a C<String>.
183 =cut
187     VTABLE void set_string_native(STRING *value) {
188         SELF.morph(enum_class_String);
189         SELF.set_string_native(value);
190     }
194 =item C<void set_pmc(PMC *value)>
196 Sets the value of the number to the value in C<*value>.
198 =cut
202     VTABLE void set_pmc(PMC *value) {
203         PMC_num_val(SELF) = VTABLE_get_number(INTERP, value);
204     }
209 =item C<PMC *neg(PMC *dest)>
211 =item C<void i_neg()>
213 Set C<dest> to the negated value of C<SELF>.
215 =cut
219     VTABLE PMC *neg(PMC *dest) {
220         const FLOATVAL a = -SELF.get_number();
222         if (!dest)
223             dest = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
225         VTABLE_set_number_native(INTERP, dest, a);
226         return dest;
227     }
229     VTABLE void i_neg() {
230         const FLOATVAL a = -SELF.get_number();
231         VTABLE_set_number_native(INTERP, SELF, a);
232     }
236 =item C<INTVAL is_equal(PMC *value)>
238 The C<==> operation.
240 =cut
244     VTABLE INTVAL is_equal(PMC *value) {
245 MMD_Float: {
246         return (INTVAL)(SELF.get_number() == VTABLE_get_number(INTERP, value));
247         }
248 MMD_DEFAULT: {
249         return (INTVAL)(SELF.get_number() == VTABLE_get_number(INTERP, value));
250         }
251     }
253     VTABLE INTVAL is_equal_num(PMC *value) {
254 MMD_Float: {
255         return (INTVAL)(SELF.get_number() == VTABLE_get_number(INTERP, value));
256         }
257 MMD_DEFAULT: {
258         return (INTVAL)(SELF.get_number() == VTABLE_get_number(INTERP, value));
259         }
260     }
264 =item C<INTVAL cmp(PMC *value)>
266 The C<cmp> operation.
268 =cut
272     VTABLE INTVAL cmp(PMC *value) {
273 MMD_Float: {
274             const FLOATVAL diff = SELF.get_number() - VTABLE_get_number(INTERP, value);
275             return diff > 0 ? 1 : diff < 0 ? -1 : 0;
276         }
277 MMD_DEFAULT: {
278             const FLOATVAL diff =
279                 SELF.get_number() - VTABLE_get_number(INTERP, value);
280             return diff > 0 ? 1 : diff < 0 ? -1 : 0;
281         }
282     }
286 =item C<INTVAL cmp_num(PMC *value)>
288 Returns the result of comparing the number with C<*value>.
290 =cut
294     VTABLE INTVAL cmp_num(PMC *value) {
295 MMD_Float: {
296             const FLOATVAL diff = SELF.get_number() - VTABLE_get_number(INTERP, value);
297             return diff > 0 ? 1 : diff < 0 ? -1 : 0;
298         }
299 MMD_DEFAULT: {
300             const FLOATVAL diff =
301                 SELF.get_number() - VTABLE_get_number(INTERP, value);
302             return diff > 0 ? 1 : diff < 0 ? -1 : 0;
303         }
304     }
308 =item C<void increment()>
310 Increments the number.
312 =cut
316     VTABLE void increment() {
317         PMC_num_val(SELF)++;
318     }
322 =item C<void decrement()>
324 Decrements the number.
326 =cut
330     VTABLE void decrement() {
331         PMC_num_val(SELF)--;
332     }
335 =item C<PMC *absolute(PMC *dest)>
337 =item C<void i_absolute()>
339 Sets C<dest> to the absolute value of SELF.
341 =cut
345     VTABLE PMC *absolute(PMC *dest) {
346         const FLOATVAL a = fabs(SELF.get_number());
348         if (!dest)
349             dest = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
351         VTABLE_set_number_native(INTERP, dest, a);
352         return dest;
353     }
355     VTABLE void i_absolute() {
356         const FLOATVAL a = fabs(SELF.get_number());
357         VTABLE_set_number_native(INTERP, SELF, a);
358     }
362 =item C<void freeze(visit_info *info)>
364 Used to archive the number.
366 =cut
369     VTABLE void freeze(visit_info *info) {
370         IMAGE_IO * const io = info->image_io;
371         SUPER(info);
372         VTABLE_push_float(INTERP, io, SELF.get_number());
373     }
377 =item C<void thaw(visit_info *info)>
379 Used to unarchive the number.
381 =cut
384     VTABLE void thaw(visit_info *info) {
385         IMAGE_IO * const io = info->image_io;
386         SUPER(info);
387         if (info->extra_flags == EXTRA_IS_NULL)
388             PMC_num_val(SELF) = VTABLE_shift_float(INTERP, io);
389     }
392 =back
394 =head2 Methods
396 =over 4
398 =item C<METHOD PMC *acos()>
400 =item C<METHOD PMC *asec()>
402 =item C<METHOD PMC *asin()>
404 =item C<METHOD PMC *cos()>
406 =item C<METHOD PMC *cosh()>
408 =item C<METHOD PMC *exp()>
410 =item C<METHOD PMC *ln()>
412 =item C<METHOD PMC *log10()>
414 =item C<METHOD PMC *log2()>
416 =item C<METHOD PMC *sec()>
418 =item C<METHOD PMC *sech()>
420 =item C<METHOD PMC *sin()>
422 =item C<METHOD PMC *sinh()>
424 =item C<METHOD PMC *tan()>
426 =item C<METHOD PMC *tanh()>
428 =item C<METHOD PMC *sqrt()>
430 Return a new PMC of the type of C<SELF> with I<FUNC>(value) of SELF.
432 =cut
436     METHOD acos() {
437         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
438         PMC_num_val(d) = acos(SELF.get_number());
439         RETURN(PMC *d);
440     }
442     METHOD cos() {
443         PMC * const d  = pmc_new(INTERP,
444                 Parrot_get_ctx_HLL_type(INTERP, enum_class_Float));
445         PMC_num_val(d) = cos(SELF.get_number());
446         RETURN(PMC *d);
447     }
449     METHOD asec() {
450         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
451         PMC_num_val(d) = acos(1.0 / SELF.get_number());
452         RETURN(PMC *d);
453     }
455     METHOD asin() {
456         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
457         PMC_num_val(d) = asin(SELF.get_number());
458         RETURN(PMC *d);
459     }
461     METHOD atan() {
462         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
463         PMC_num_val(d) = atan(SELF.get_number());
464         RETURN(PMC *d);
465     }
467     METHOD atan2(PMC *val) {
468         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
469         PMC_num_val(d) = atan2(SELF.get_number(), PMC_num_val(val));
470         RETURN(PMC *d);
471     }
473     METHOD cosh() {
474         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
475         PMC_num_val(d) = cosh(SELF.get_number());
476         RETURN(PMC *d);
477     }
479     METHOD exp() {
480         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
481         PMC_num_val(d) = exp(SELF.get_number());
482         RETURN(PMC *d);
483     }
485     METHOD ln() {
486         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
487         PMC_num_val(d) = log(SELF.get_number());
488         RETURN(PMC *d);
489     }
491     METHOD log10() {
492         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
493         PMC_num_val(d) = log10(SELF.get_number());
494         RETURN(PMC *d);
495     }
497     METHOD log2() {
498         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
499         PMC_num_val(d) = log(SELF.get_number()) / log(2.0);
500         RETURN(PMC *d);
501     }
503     METHOD sec() {
504         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
505         PMC_num_val(d) = 1.0 / cos(SELF.get_number());
506         RETURN(PMC *d);
507     }
509     METHOD sech() {
510         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
511         PMC_num_val(d) = 1.0 / cosh(SELF.get_number());
512         RETURN(PMC *d);
513     }
515     METHOD sin() {
516         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
517         PMC_num_val(d) = sin(SELF.get_number());
518         RETURN(PMC *d);
519     }
521     METHOD sinh() {
522         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
523         PMC_num_val(d) = sinh(SELF.get_number());
524         RETURN(PMC *d);
525     }
527     METHOD tan() {
528         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
529         PMC_num_val(d) = tan(SELF.get_number());
530         RETURN(PMC *d);
531     }
533     METHOD tanh() {
534         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
535         PMC_num_val(d) = tanh(SELF.get_number());
536         RETURN(PMC *d);
537     }
539     METHOD sqrt() {
540         PMC * const d  = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
541         PMC_num_val(d) = sqrt(SELF.get_number());
542         RETURN(PMC *d);
543     }
548 =back
550 =cut
555  * Local variables:
556  *   c-file-style: "parrot"
557  * End:
558  * vim: expandtab shiftwidth=4:
559  */