root/misc/S29_round.xinming.pl

Revision 10022, 2.8 kB (checked in by yiyihu, 3 years ago)

Because aufrandk also implemented rounding suite... And It overrite mine...
So I renamed mine, and commit... :-)

Line 
1our Int multi Num::round_toward_nearest (Num $x, int $symmetrical? = 1) {
2# XXX -- Not implemented
3# How should I implement this? As in
4# http://www.pldesignline.com/howto/showArticle.jhtml?articleID=175801189
5# says, This may be considered as the superset of round_half_up and
6# round_half_down
7
8}
9
10our Int multi Num::round_half_up (Num $x, int $symmetrical? = 1) {
11        return int($x + 0.5)
12                if $x > 0;
13
14        $symmetrical ??
15                -(int(abs($x) + 0.5)) !!
16                -(int(abs($x) + 0.4))
17}
18
19our Int multi Num::round_half_down (Num $x, int $symmetrical? = 1) {
20        return int($x + 0.4)
21                if $x > 0;
22
23        $symmetrical ??
24                -(int(abs($x) + 0.4)) !!
25                -(int(abs($x) + 0.5))
26}
27
28# No symmetry flag
29our Int multi Num::round_half_even (Num $x) {
30        return int($x.is_even ?? $x + 0.4 !! $x + 0.5)
31                if $x > 0;
32
33        return 0 if $x == 0;
34
35        return -(&?ROUTINE(abs($x)));
36}
37
38our Int multi Num::round_half_odd (Num $x) {
39        return int($x.is_odd ?? $x + 0.4 !! $x + 0.5)
40                if $x > 0;
41
42        return 0 if $x == 0;
43
44        return -(&?ROUTINE(abs($x)));
45}
46
47our Int multi Num::round_alternate (Num $x) {
48# XXX I don't understand what round-alternate means.
49# But in my understanding, The implemention below might be right.
50        state $t;
51        if $t {
52                $t = 0;
53                return $x.round_half_even;
54        } else {
55                $t = 1;
56                return $x.round_half_odd;
57        }
58}
59
60our Int multi Num::round_random (Num $x) {
61        my @l = (
62                { $^a.round_half_up: symmetrical => $^b },
63                { $^a.round_half_down: symmetrical => $^b },
64                { $^a.round_half_even },
65                { $^a.round_half_odd },
66
67#               { $^a.round_half_alternate },
68#               { $^a.round_half_random },
69
70                { $^a.round_half_ceiling },
71                { $^a.round_toward_zero },
72                { $^a.round_away_from_zero },
73
74#               { $^a.round_up: symmetrical => $^b },
75#               { $^a.round_down: symmetrical => $^b },
76                );
77        my $sym_flag = (int(rand() * 10)) % 2;
78        my $selector = (int(rand() * 100)) % @l.elems;
79
80        @l[$selector]($x, $sym_flag);
81}
82
83our Int multi Num::round_ceiling (Num $x) {
84        my Int $t = int($x);
85        $x > 0 && $x != $t ??
86                $t + 1 !! $t
87}
88
89our Int multi Num::round_floor (Num $x) {
90        my Int $t = int($x);
91        $x > 0 || $x == $t ??
92                $t !! $t - 1
93}
94
95our Int multi Num::round_toward_zero (Num $x) {
96        return(int $x);
97}
98
99our Int multi Num::round_away_from_zero (Num $x) {
100        return 0 if $x == 0;
101
102        my Int $t = int($x);
103        return $x if $x == $t;
104        $x > 0 ?? $t + 1 !! $t - 1;
105}
106
107our Int multi Num::round_up (Num $x, int $symmetrical? = 1) {
108        $symmetrical ?? $x.round_away_from_zero
109                !! $x.round_ceiling
110}
111
112our Int multi Num::round_down (Num $x, int $symmetrical? = 1) {
113        $symmetrical ?? $x.round_toward_zero
114                !! $x.round_floor
115}
116
117our Int multi Num::truncation (Num $x) {
118        ...
119}
120
121# Other math functions.
122our bool multi Num::is_odd (Num $x) {
123        return ?(int($x) % 2);
124}
125
126our bool multi Num::is_even (Num $x) {
127        return !(int($x) % 2);
128}
129
130our Num multi Num::abs (Num $x) {
131        $x < 0 ?? -$x !! $x;
132}
133
134our int multi Num::sign (Num $x) {
135        return 0 if $x == 0;
136        $x > 0 ?? 1 !! -1;
137}
Note: See TracBrowser for help on using the browser.