summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedja Beader <fedja@protonmail.ch>2025-05-03 14:46:53 +0000
committerJesusalva Jesusalva <jesusalva@tmw2.org>2025-05-03 14:46:53 +0000
commit2805ee04adc7c20f5dc2a866ea1422d5dbc748d3 (patch)
tree11fd143386b8e2c72dc34c958609b195ce3fc94b
parentdf8cce5728bdf0a3155e6412a39cd7544570a1db (diff)
downloadserverdata-2805ee04adc7c20f5dc2a866ea1422d5dbc748d3.tar.gz
serverdata-2805ee04adc7c20f5dc2a866ea1422d5dbc748d3.tar.bz2
serverdata-2805ee04adc7c20f5dc2a866ea1422d5dbc748d3.tar.xz
serverdata-2805ee04adc7c20f5dc2a866ea1422d5dbc748d3.zip
Simplify base 2 logarithm computation
Could put shift into while loop condition, but this is more readable. Untested, ofc... * Add some testcases for log2, too * Simplify base 2 logarithm computation **** ml/serverdata!169
-rw-r--r--npc/dev/test.txt5
-rw-r--r--npc/functions/math.txt32
2 files changed, 14 insertions, 23 deletions
diff --git a/npc/dev/test.txt b/npc/dev/test.txt
index 268639102..b430dd57d 100644
--- a/npc/dev/test.txt
+++ b/npc/dev/test.txt
@@ -629,6 +629,11 @@ function script HerculesSelfTestHelper {
callsub(OnCheck, "array shrink", .@x[1], 0);
callsub(OnCheck, "array shrink and getarraysize", getarraysize(.@x), 0);
+ // log2
+ callsub(OnCheck, "log2(0)", log2(0), -1);
+ callsub(OnCheck, "log2(1)", log2(1), 0);
+ callsub(OnCheck, "log2(3<<29)", log2(0x60000000), 30);
+
// min and max
callsub(OnCheck, "min()", min(5, -10, 8, 3, -2, 1000), -10);
callsub(OnCheck, "max()", max(5, -10, 8, 3, -2, 1000), 1000);
diff --git a/npc/functions/math.txt b/npc/functions/math.txt
index 22cf88159..d54558352 100644
--- a/npc/functions/math.txt
+++ b/npc/functions/math.txt
@@ -40,31 +40,17 @@ function script lognbaselvl {
}
// log2(<int>)
-// returns the log base 2 of the passed integer, up to 20 (2**20=1.048.576) (round down always)
-
+// returns the base 2 logarithm of the passed integer
+// Note: Negative values are first converted to positive.
+// For 0, -1 is returned instead
+// (as if passed value == 0.5, but that is not possible for integers).
function script log2 {
- .@v=abs(getarg(0));
- .@ok=0;
- .@i=0;
- if (.@v < 1)
- return -1;
-
- freeloop(true);
- while (!.@ok) {
- // exact match
- if (2**.@i == .@v) {
- .@ok=1;
- // inexact match, or limit exceeded
- } else if (2**.@i >= .@v || .@i > 20) {
- .@ok=1;
- .@i-=1; // round down
- // not yet
- } else {
- .@i+=1;
- }
+ .@v = abs(getarg(0));
+ .@i = -1;
+ while (.@v > 0) {
+ .@i += 1;
+ .@v >>= 1;
}
- freeloop(false);
-
return .@i;
}