root/misc/S29_round.pl

Revision 11295, 5.0 kB (checked in by Darren_Duncan, 3 years ago)

updated another 2-3 dozen files, mostly in misc/ and perl5/, to replace v6 with v6-alpha, and remove a few malformed shebang lines

Line 
1use v6-alpha;
2
3our Int multi Num::round_half_up_symmetric ( Num $x ) {
4    my $x_round;
5
6    # round .5 up above 0, down below 0
7    given abs($x) - floor( abs($x) ) {
8        when $_ <  .5 { $x_round = sign($x) * floor( abs($x) ) }
9        when $_ >= .5 { $x_round = sign($x) * ceil( abs($x) ) }
10    }
11    return $x_round;
12}
13
14our Int multi Num::round_half_up_asymmetric ( Num $x ) {
15    my $x_round;
16
17    # round .5 up above 0, up below 0
18    given abs($x) - floor( abs($x) ) {
19        when ($_ <  .5) && ($x >= 0) { $x_round = sign($x) * floor( abs($x) ) }
20        when ($_ >= .5) && ($x >= 0) { $x_round = sign($x) * ceil( abs($x) ) }
21        when ($_ <= .5) && ($x <  0) { $x_round = sign($x) * floor( abs($x) ) }
22        when ($_ >  .5) && ($x <  0) { $x_round = sign($x) * ceil( abs($x) ) }
23    }
24    return $x_round;
25}
26
27our Int multi Num::round_half_down_symmetric ( Num $x ) {
28    my $x_round;
29
30    # round .5 down above 0, down below 0
31    given abs($x) - floor( abs($x) ) {
32        when $_ <= .5 { $x_round = sign($x) * floor( abs($x) ) }
33        when $_ >  .5 { $x_round = sign($x) * ceil( abs($x) ) }
34    }
35    return $x_round;
36}
37
38our Int multi Num::round_half_down_asymmetric ( Num $x ) {
39    my $x_round;
40
41    # round .5 down above 0, up below 0
42    given abs($x) - floor( abs($x) ) {
43        when ($_ <= .5) && ($x >= 0) { $x_round = sign($x) * floor( abs($x) ) }
44        when ($_ >  .5) && ($x >= 0) { $x_round = sign($x) * ceil( abs($x) ) }
45        when ($_ <  .5) && ($x <  0) { $x_round = sign($x) * floor( abs($x) ) }
46        when ($_ >= .5) && ($x <  0) { $x_round = sign($x) * ceil( abs($x) ) }
47    }
48    return $x_round;
49}
50
51our Int multi Num::round_half_even ( Num $x ) {
52    my $x_round;
53
54    # round .5 to the nearest even number
55    given abs($x) - floor( abs($x) ) {
56        when $_ < .5 { $x_round = sign($x) * floor(abs($x)) }
57        when $_ > .5 { $x_round = sign($x) * ceil(abs($x)) }
58        when $_ == .5 {
59            given floor( abs($x) ) % 2 {
60                when $_ == 0 { $x_round = sign($x) * floor( abs($x) ) }
61                when $_ == 1 { $x_round = sign($x) * (floor( abs($x) ) + 1) }
62            }
63        }
64    }
65    return $x_round;
66}
67
68our Int multi Num::round_half_odd ( Num $x ) {
69    my $x_round;
70
71    # round .5 to the nearest odd number
72    given abs($x) - floor( abs($x) ) {
73        when $_ < .5 { $x_round = sign($x) * floor(abs($x)) }
74        when $_ > .5 { $x_round = sign($x) * ceil(abs($x)) }
75        when $_ == .5 {
76            given floor( abs($x) ) % 2 {
77                when $_ == 0 { $x_round = sign($x) * (floor( abs($x) ) + 1) }
78                when $_ == 1 { $x_round = sign($x) * floor( abs($x) ) }
79            }
80        }
81    }
82    return $x_round;
83}
84
85our Int multi Num::round_alternate ( Num $x ) {
86    my $x_round;
87    state $round_up = 1;
88
89    # alternate rounding .5 up and down
90    given abs($x) - floor( abs($x) ) {
91        when $_ < .5 { $x_round = sign($x) * floor(abs($x)) }
92        when $_ > .5 { $x_round = sign($x) * ceil(abs($x)) }
93        when $_ == .5 {
94            if $round_up {
95                $x_round = round_up_symmetric($x);
96                $round_up = 0;
97            }
98            else {
99                $x_round = round_down_symmetric($x);
100                $round_up = 1;
101            }
102        }
103    }
104
105    return $x_round;
106}
107
108our Int multi Num::round_random ( Num $x ) {
109    my $x_round;
110    state $rand_up = 1;
111
112    # randomly round .5 up or down
113    given abs($x) - floor( abs($x) ) {
114        when $_ <  .5 { $x_round = sign($x) * floor(abs($x)) }
115        when $_ >  .5 { $x_round = sign($x) * ceil(abs($x)) }
116        when $_ == .5 {
117            if $rand_up {
118                if rand < .5 {
119                    $x_round = round_up_symmetric($x);
120                }
121                else {
122                    $x_round = round_down_symmetric($x);
123                }
124                $rand_up = 0;
125            }
126            else {
127                if rand <= .5 {
128                    $x_round = round_up_symmetric($x);
129                }
130                else {
131                    $x_round = round_down_symmetric($x);
132                }
133                $rand_up = 1;
134            }
135        }
136    }
137
138    return $x_round;
139}
140
141our Int multi Num::round_ceiling ( Num $x ) {
142    my $x_round = ceil($x);
143
144    return $x_round;
145}
146
147our Int multi Num::round_floor ( Num $x ) {
148    my $x_round = floor($x);
149
150    return $x_round;
151}
152
153our Int multi Num::round_toward_zero ( Num $x ) {
154    my $x_round;
155
156    # round floor above 0, round ceiling below 0
157    if $x < 0 {
158        $x_round = round_floor($x);
159    }
160    elsif $x > 0 {
161        $x_round = round_ceiling($x);
162    }
163    else {
164        $x_round = 0;
165    }
166
167    return $x_round;
168}
169
170our Int multi Num::round_away_from_zero ( Num $x ) {
171    my $x_round;
172
173    # round ceiling above 0, round floor below 0
174    if $x < 0 {
175        $x_round = round_ceiling($x);
176    }
177    elsif $x > 0 {
178        $x_round = round_floor($x);
179    }
180    else {
181        $x_round = 0;
182    }
183
184    return $x_round;
185}
186
187our Int multi Num::sign (Num $x) {
188        return 0 if $x == 0;
189        $x > 0 ?? 1 !! -1;
190}
Note: See TracBrowser for help on using the browser.