diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-03-09 15:56:44 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-03-09 15:56:44 -0400 |
| commit | 29358b9cd0eea2ddf05d216d75d01dff5f0ea780 (patch) | |
| tree | 6a7776a9fbfaccc650b07dde125f5e8a31c8546e | |
| parent | 2ebe7893fe18c953967f602c73f6d3f32185eeb6 (diff) | |
Add some missing modulus and conversion methods for floats/ints
| -rw-r--r-- | environment.c | 4 | ||||
| -rw-r--r-- | stdlib/integers.h | 51 | ||||
| -rw-r--r-- | stdlib/nums.c | 8 | ||||
| -rw-r--r-- | stdlib/nums.h | 2 |
4 files changed, 63 insertions, 2 deletions
diff --git a/environment.c b/environment.c index 259cdd74..5c9bbe95 100644 --- a/environment.c +++ b/environment.c @@ -234,6 +234,8 @@ env_t *new_compilation_unit(CORD libname) {"scientific", "Num$scientific", "func(n:Num,precision=0 -> Text)"}, {"isinf", "Num$isinf", "func(n:Num -> Bool)"}, {"isfinite", "Num$isfinite", "func(n:Num -> Bool)"}, + {"modulo", "Num$mod", "func(x,y:Num -> Num)"}, + {"modulo1", "Num$mod1", "func(x,y:Num -> Num)"}, C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), {"INF", "(Num_t)(INFINITY)", "Num"}, @@ -270,6 +272,8 @@ env_t *new_compilation_unit(CORD libname) {"mix", "Num32$mix", "func(amount,x,y:Num32 -> Num32)"}, {"parse", "Num32$parse", "func(text:Text -> Num32?)"}, {"abs", "fabsf", "func(n:Num32 -> Num32)"}, + {"modulo", "Num32$mod", "func(x,y:Num32 -> Num32)"}, + {"modulo1", "Num32$mod1", "func(x,y:Num32 -> Num32)"}, F_opt(acos), F_opt(acosh), F_opt(asin), F(asinh), F(atan), F_opt(atanh), F(cbrt), F(ceil), F_opt(cos), F(cosh), F(erf), F(erfc), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F_opt(log), F_opt(log10), F_opt(log1p), diff --git a/stdlib/integers.h b/stdlib/integers.h index c78cabf0..f70ed29d 100644 --- a/stdlib/integers.h +++ b/stdlib/integers.h @@ -282,7 +282,6 @@ MACROLIKE PUREFUNC Int_t Int$from_num(double n, bool truncate) { fail("Could not convert to an integer without truncation: %g", n); return Int$from_mpz(result); } -#pragma GCC diagnostic pop MACROLIKE PUREFUNC Int_t Int$from_num32(float n, bool truncate) { return Int$from_num((double)n, truncate); } MACROLIKE Int_t Int$from_int64(int64_t i) { if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) @@ -298,6 +297,18 @@ MACROLIKE CONSTFUNC Int_t Int$from_byte(Byte_t b) { return I_small(b); } MACROLIKE CONSTFUNC Int_t Int$from_bool(Bool_t b) { return I_small(b); } // Int64 constructors +MACROLIKE PUREFUNC Int64_t Int64$from_num(Num_t n, bool truncate) { + int64_t i64 = (int64_t)n; + if unlikely ((Num_t)n != n && !truncate) + fail("Could not convert Num to Int64 without truncation: %g\n", n); + return i64; +} +MACROLIKE PUREFUNC Int64_t Int64$from_num32(Num32_t n, bool truncate) { + int64_t i64 = (int64_t)n; + if unlikely ((Num32_t)n != n && !truncate) + fail("Could not convert Num32 to Int64 without truncation: %g\n", (double)n); + return i64; +} MACROLIKE PUREFUNC Int64_t Int64$from_int(Int_t i, bool truncate) { if likely (i.small & 1) return (int64_t)(i.small >> 2); @@ -310,6 +321,18 @@ MACROLIKE CONSTFUNC Int64_t Int64$from_int16(Int16_t i) { return (Int64_t)i; } MACROLIKE CONSTFUNC Int64_t Int64$from_int8(Int8_t i) { return (Int64_t)i; } // Int32 constructors +MACROLIKE PUREFUNC Int32_t Int32$from_num(Num_t n, bool truncate) { + int32_t i32 = (int32_t)n; + if unlikely ((Num_t)n != n && !truncate) + fail("Could not convert Num to Int32 without truncation: %g\n", n); + return i32; +} +MACROLIKE PUREFUNC Int32_t Int32$from_num32(Num32_t n, bool truncate) { + int32_t i32 = (int32_t)n; + if unlikely ((Num32_t)n != n && !truncate) + fail("Could not convert Num32 to Int32 without truncation: %g\n", (double)n); + return i32; +} MACROLIKE PUREFUNC Int32_t Int32$from_int(Int_t i, bool truncate) { int64_t i64 = Int64$from_int(i, truncate); int32_t i32 = (int32_t)i64; @@ -326,6 +349,18 @@ MACROLIKE CONSTFUNC Int32_t Int32$from_int16(Int16_t i) { return (Int32_t)i; } MACROLIKE CONSTFUNC Int32_t Int32$from_int8(Int8_t i) { return (Int32_t)i; } // Int16 constructors +MACROLIKE PUREFUNC Int16_t Int16$from_num(Num_t n, bool truncate) { + int16_t i16 = (int16_t)n; + if unlikely ((Num_t)n != n && !truncate) + fail("Could not convert Num to Int16 without truncation: %g\n", n); + return i16; +} +MACROLIKE PUREFUNC Int16_t Int16$from_num32(Num32_t n, bool truncate) { + int16_t i16 = (int16_t)n; + if unlikely ((Num32_t)n != n && !truncate) + fail("Could not convert Num32 to Int16 without truncation: %g\n", (double)n); + return i16; +} MACROLIKE PUREFUNC Int16_t Int16$from_int(Int_t i, bool truncate) { int64_t i64 = Int64$from_int(i, truncate); int16_t i16 = (int16_t)i64; @@ -333,7 +368,6 @@ MACROLIKE PUREFUNC Int16_t Int16$from_int(Int_t i, bool truncate) { fail("Integer is too big to fit in a 16-bit integer!"); return i16; } - MACROLIKE PUREFUNC Int16_t Int16$from_int64(Int64_t i, bool truncate) { if (!truncate && unlikely(i != (Int64_t)(Int16_t)i)) fail("Integer is too big to fit in a 16-bit integer: %ld", i); @@ -347,6 +381,18 @@ MACROLIKE PUREFUNC Int16_t Int16$from_int32(Int32_t i, bool truncate) { MACROLIKE CONSTFUNC Int16_t Int16$from_int8(Int8_t i) { return (Int16_t)i; } // Int8 constructors +MACROLIKE PUREFUNC Int8_t Int8$from_num(Num_t n, bool truncate) { + int8_t i8 = (int8_t)n; + if unlikely ((Num_t)n != n && !truncate) + fail("Could not convert Num to Int8 without truncation: %g\n", n); + return i8; +} +MACROLIKE PUREFUNC Int8_t Int8$from_num32(Num32_t n, bool truncate) { + int8_t i8 = (int8_t)n; + if unlikely ((Num32_t)n != n && !truncate) + fail("Could not convert Num32 to Int8 without truncation: %g\n", (double)n); + return i8; +} MACROLIKE PUREFUNC Int8_t Int8$from_int(Int_t i, bool truncate) { int64_t i64 = Int64$from_int(i, truncate); int8_t i8 = (int8_t)i64; @@ -369,5 +415,6 @@ MACROLIKE PUREFUNC Int8_t Int8$from_int16(Int16_t i, bool truncate) { fail("Integer is too big to fit in a 8-bit integer: %ld", i); return (Int8_t)i; } +#pragma GCC diagnostic pop // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/nums.c b/stdlib/nums.c index b227ccb8..f1b7c7b7 100644 --- a/stdlib/nums.c +++ b/stdlib/nums.c @@ -62,6 +62,10 @@ public CONSTFUNC double Num$mod(double num, double modulus) { return (result < 0) != (modulus < 0) ? result + modulus : result; } +public CONSTFUNC double Num$mod1(double num, double modulus) { + return 1.0 + Num$mod(num-1, modulus); +} + public CONSTFUNC double Num$mix(double amount, double x, double y) { return (1.0-amount)*x + amount*y; } @@ -137,6 +141,10 @@ public CONSTFUNC float Num32$mod(float num, float modulus) { return (result < 0) != (modulus < 0) ? result + modulus : result; } +public CONSTFUNC float Num32$mod1(float num, float modulus) { + return 1.0f + Num32$mod(num-1, modulus); +} + public CONSTFUNC float Num32$mix(float amount, float x, float y) { return (1.0f-amount)*x + amount*y; } diff --git a/stdlib/nums.h b/stdlib/nums.h index 0b4cdc1b..af0e895b 100644 --- a/stdlib/nums.h +++ b/stdlib/nums.h @@ -24,6 +24,7 @@ CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute); Text_t Num$format(double f, Int_t precision); Text_t Num$scientific(double f, Int_t precision); double Num$mod(double num, double modulus); +double Num$mod1(double num, double modulus); CONSTFUNC bool Num$isinf(double n); CONSTFUNC bool Num$finite(double n); CONSTFUNC bool Num$isnan(double n); @@ -74,6 +75,7 @@ CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute); Text_t Num32$format(float f, Int_t precision); Text_t Num32$scientific(float f, Int_t precision); float Num32$mod(float num, float modulus); +float Num32$mod1(float num, float modulus); CONSTFUNC bool Num32$isinf(float n); CONSTFUNC bool Num32$finite(float n); CONSTFUNC bool Num32$isnan(float n); |
