aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/math/floor.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/math/floor.v')
-rw-r--r--v_windows/v/vlib/math/floor.v105
1 files changed, 105 insertions, 0 deletions
diff --git a/v_windows/v/vlib/math/floor.v b/v_windows/v/vlib/math/floor.v
new file mode 100644
index 0000000..a2c3208
--- /dev/null
+++ b/v_windows/v/vlib/math/floor.v
@@ -0,0 +1,105 @@
+module math
+
+// floor returns the greatest integer value less than or equal to x.
+//
+// special cases are:
+// floor(±0) = ±0
+// floor(±inf) = ±inf
+// floor(nan) = nan
+pub fn floor(x f64) f64 {
+ if x == 0 || is_nan(x) || is_inf(x, 0) {
+ return x
+ }
+ if x < 0 {
+ mut d, fract := modf(-x)
+ if fract != 0.0 {
+ d = d + 1
+ }
+ return -d
+ }
+ d, _ := modf(x)
+ return d
+}
+
+// ceil returns the least integer value greater than or equal to x.
+//
+// special cases are:
+// ceil(±0) = ±0
+// ceil(±inf) = ±inf
+// ceil(nan) = nan
+pub fn ceil(x f64) f64 {
+ return -floor(-x)
+}
+
+// trunc returns the integer value of x.
+//
+// special cases are:
+// trunc(±0) = ±0
+// trunc(±inf) = ±inf
+// trunc(nan) = nan
+pub fn trunc(x f64) f64 {
+ if x == 0 || is_nan(x) || is_inf(x, 0) {
+ return x
+ }
+ d, _ := modf(x)
+ return d
+}
+
+// round returns the nearest integer, rounding half away from zero.
+//
+// special cases are:
+// round(±0) = ±0
+// round(±inf) = ±inf
+// round(nan) = nan
+pub fn round(x f64) f64 {
+ if x == 0 || is_nan(x) || is_inf(x, 0) {
+ return x
+ }
+ // Largest integer <= x
+ mut y := floor(x) // Fractional part
+ mut r := x - y // Round up to nearest.
+ if r > 0.5 {
+ unsafe {
+ goto rndup
+ }
+ }
+ // Round to even
+ if r == 0.5 {
+ r = y - 2.0 * floor(0.5 * y)
+ if r == 1.0 {
+ rndup:
+ y += 1.0
+ }
+ }
+ // Else round down.
+ return y
+}
+
+// round_to_even returns the nearest integer, rounding ties to even.
+//
+// special cases are:
+// round_to_even(±0) = ±0
+// round_to_even(±inf) = ±inf
+// round_to_even(nan) = nan
+pub fn round_to_even(x f64) f64 {
+ mut bits := f64_bits(x)
+ mut e_ := (bits >> shift) & mask
+ if e_ >= bias {
+ // round abs(x) >= 1.
+ // - Large numbers without fractional components, infinity, and nan are unchanged.
+ // - Add 0.499.. or 0.5 before truncating depending on whether the truncated
+ // number is even or odd (respectively).
+ half_minus_ulp := u64(u64(1) << (shift - 1)) - 1
+ e_ -= u64(bias)
+ bits += (half_minus_ulp + (bits >> (shift - e_)) & 1) >> e_
+ bits &= frac_mask >> e_
+ bits ^= frac_mask >> e_
+ } else if e_ == bias - 1 && bits & frac_mask != 0 {
+ // round 0.5 < abs(x) < 1.
+ bits = bits & sign_mask | uvone // +-1
+ } else {
+ // round abs(x) <= 0.5 including denormals.
+ bits &= sign_mask // +-0
+ }
+ return f64_from_bits(bits)
+}