Skip to content

Commit a3da509

Browse files
committed
Implemented a variety of generalized rounding functions.
1 parent 6cb279c commit a3da509

File tree

6 files changed

+124
-1
lines changed

6 files changed

+124
-1
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,19 @@ The following is a brief description of the included functions, divided into rou
2727
A variety of scripts dealing with sequences, functions, and sets, which may have some uses for managing data structures. For example, the various pairing and inverse pairing functions can be used to store pairs of numbers as single numbers in data structures (like stacks and queues) and then recovered.
2828

2929
* [`_base_to_decimal`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_base_to_decimal/_base_to_decimal.gml): Converts a number from an array of base-_b_ digits to decimal. The inverse of `_decimal_to_base`.
30+
* [`_ceil`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_ceil/_ceil.gml): Generalized ceiling function which accepts a step size argument.
3031
* [`_decimal_to_base`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_decimal_to_base/_decimal_to_base.gml): Converts a number from decimal to an array of base-_b_ digits. The inverse of `_base_to_decimal`.
3132
* [`_factorial`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_factorial/_factorial.gml): Calculates the factorial (_n!_) of a nonnegative integer.
33+
* [`_floor`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_floor/_floor.gml): Generalized floor function which accepts a step size argument.
34+
* [`_frac`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_frac/_frac.gml): Generalized fractional part function which accepts a step size argument.
3235
* [`_integer_pair_to_natural`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_integer_pair_to_natural/_integer_pair_to_natural.gml): Maps an ordered pair of integers to a unique natural number (by composing `_nautral_pair_to_natural` on `_integer_to_natural`). This is the inverse of `_natural_to_integer_pair`.
3336
* [`_integer_to_natural`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_integer_to_natural/_integer_to_natural.gml): Maps an integer to a unique natural number using the zig-zagging bijection from _(0, 1, -1, 2, -2, ...)_ to _(0, 1, 2, 3, 4, ...)_. This is the inverse of `_natural_to_integer`.
3437
* [`_k_tuples`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_k_tuples/_k_tuples.gml): Generates an array of all possible base-_b_ _k_-tuples, in ascending (or descending) order.
3538
* [`_natural_to_integer`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_natural_to_integer/_natural_to_integer.gml): Maps a natural number to a unique integer using the zig-zagging bijection from _(0, 1, 2, 3, 4, ...)_ to _(0, 1, -1, 2, -2, ...)_. This is the inverse of `_integer_to_natural`.
3639
* [`_natural_to_integer_pair`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_natural_to_integer_pair/_natural_to_integer_pair.gml): Maps a natural number to a unique ordered pair of integers (by composing `_nautral_to_integer` on `_natural_to_natural_pair`). This is the inverse of `_integer_pair_to_natural`.
3740
* [`_natural_to_natural_pair`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_natural_to_natural_pair/_natural_to_natural_pair.gml): Maps a natural number to a unique ordered pair of natural numbers using the [inverse Cantor pairing function](https://en.wikipedia.org/wiki/Pairing_function#Inverting_the_Cantor_pairing_function). This is the inverse of `_pair_to_natural`.
3841
* [`_natural_pair_to_natural`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_natural_pair_to_natural/_natural_pair_to_natural.gml): Maps an ordered pair of natural numbers to a unique natural number using the [Cantor pairing function](https://en.wikipedia.org/wiki/Pairing_function#Cantor_pairing_function). This is the inverse of `_natural_to_pair`.
42+
* [`_round`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_round/_round.gml): Generalized rounding function which accepts a step size argument.
3943

4044
## Array Functions
4145

@@ -84,8 +88,9 @@ Common linear algebra algorithms for dealing with matrices and vectors. In all f
8488

8589
Functions which involve randomization.
8690

87-
* [`_random_weighted_index`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_random_weighted_index/_random_weighted_index.gml): Chooses a random array index with probabilities defined by a given weight array.
91+
* [`_random_round`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_random_round/_random_round.gml): Rounds a number either up or down to an integer value with a probability based on its fractional part.
8892
* [`_random_sample`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_random_sample/_random_sample.gml): Draws a set of random samples from an array, either with or without replacement.
93+
* [`_random_weighted_index`](https://github.com/adam-rumpf/game-maker-scripts/blob/master/scripts/_random_weighted_index/_random_weighted_index.gml): Chooses a random array index with probabilities defined by a given weight array.
8994

9095
## Cellular Automata Functions
9196

scripts/_ceil/_ceil.gml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// @func _ceil(x[, step])
2+
/// @desc Rounds a number up to a multiple of a given step size. This generalizes the built-in ceil() function, which uses a step size of 1.
3+
/// @param {real} x - Number to round.
4+
/// @param {real} [step=1.0] - Step size to round to.
5+
/// @return {real} Least multiple of step which is greater than or equal to x.
6+
7+
function _ceil(xx)
8+
{
9+
// Get step size argument
10+
var step = (argument_count > 1 ? argument[1] : 1.0);
11+
12+
// Verify that step size is positive
13+
if (step <= 0)
14+
return undefined;
15+
16+
// Subtract generalized fractional part from x and add one step
17+
return xx - (xx mod step) + step;
18+
}

scripts/_floor/_floor.gml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// @func _floor(x[, step])
2+
/// @desc Rounds a number down to a multiple of a given step size. This generalizes the built-in floor() function, which uses a step size of 1.
3+
/// @param {real} x - Number to round.
4+
/// @param {real} [step=1.0] - Step size to round to.
5+
/// @return {real} Greatest multiple of step which is less than or equal to x.
6+
7+
function _floor(xx)
8+
{
9+
// Get step size argument
10+
var step = (argument_count > 1 ? argument[1] : 1.0);
11+
12+
// Verify that step size is positive
13+
if (step <= 0)
14+
return undefined;
15+
16+
// Subtract generalized fractional part from x
17+
return xx - (xx mod step);
18+
}

scripts/_frac/_frac.gml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// @func _frac(x[, step])
2+
/// @desc Finds the fractional part of a number above a multiple of a given step size. This generalizes the built-in frac() function, which uses a step size of 1.
3+
/// @param {real} x - Number to find the fractional part of.
4+
/// @param {real} [step=1.0] - Step size.
5+
/// @return {real} Amount by which x exceeds the greatest multiple of step that does not exceed x. Equivalent to x - _floor(x, step).
6+
7+
function _frac(xx)
8+
{
9+
// Get step size argument
10+
var step = (argument_count > 1 ? argument[1] : 1.0);
11+
12+
// Verify that step size is positive
13+
if (step <= 0)
14+
return undefined;
15+
16+
// Find the generalized fractional part
17+
return (xx mod step);
18+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/// @func _random_round(x[, step])
2+
/// @desc Randomly rounds a real up or down with a probability equal to the fractional part.
3+
/// @param {real} x - Number to be rounded.
4+
/// @param {real} [step=1.0] - Step size to round to.
5+
/// @return {int} Either ceil(x) or floor(x), with the probability of the ceiling being the fractional part of x.
6+
7+
function _random_round(xx)
8+
{
9+
// Get step size argument
10+
var step = (argument_count > 1 ? argument[1] : 1.0);
11+
12+
// Verify that step size is positive
13+
if (step <= 0)
14+
return undefined;
15+
16+
// Get generalized fractional part of x
17+
var fraction = (xx mod step);
18+
19+
// Decide random return value based on fractional part
20+
if (random_range(0.0, 1.0) < fraction)
21+
return xx - (xx mod step) + step; // round up with probability equal to fractional part
22+
else
23+
return xx - (xx mod step); // otherwise round down
24+
}

scripts/_round/_round.gml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/// @func _round(x[, step[, down]])
2+
/// @desc Rounds a number to the nearest multiple of a given step size. This generalizes the built-in round() function, which uses a step size of 1.
3+
/// @param {real} x - Number to round.
4+
/// @param {real} [step=1.0] - Step size to round to.
5+
/// @param {bool} [down=true] - Whether to round down in case of a tie. If false, rounds up instead.
6+
/// @return {real} Nearest multiple of step to x.
7+
8+
function _round(xx)
9+
{
10+
// Get step size and direction arguments
11+
var step = (argument_count > 1 ? argument[1] : 1.0);
12+
var down = (argument_count > 2 ? argument[2] : true);
13+
14+
// Verify that step size is positive
15+
if (step <= 0)
16+
return undefined;
17+
18+
// Get normalized distance between consecutive multiples of the step
19+
var dist = (xx mod step)/step;
20+
21+
// Use distance to decide rounding direction
22+
if (dist < 0.5)
23+
{
24+
// Round down if less than half
25+
return xx - (xx mod step);
26+
}
27+
else if (dist > 0.5)
28+
{
29+
// Round up if more than half
30+
return xx - (xx mod step) + step;
31+
}
32+
else
33+
{
34+
// Break ties based on direction argument
35+
if (down == true)
36+
return xx - (xx mod step);
37+
else
38+
return xx - (xx mod step) + step;
39+
}
40+
}

0 commit comments

Comments
 (0)