From fda9dd22ad4c94c17bde37b2bbff49e14ee2562c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 1 Nov 1996 18:51:22 -0800
Subject: [PATCH] sqrt optimized

Rev: src/ChangeLog:1.16
Rev: src/modules/math/math.c:1.2
Rev: src/modules/math/testsuite.in:1.2
---
 src/ChangeLog                 |  1 +
 src/modules/math/math.c       | 17 +++++++++++------
 src/modules/math/testsuite.in |  2 ++
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 401f04e77e..bcc046c3e0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -6,6 +6,7 @@ Fri Nov  1 15:47:48 1996  Fredrik Hubinette  <hubbe@tymin.blarg.com>
 	* some documentation about pike internals added
 	* htmlify_docs.pike fixed to handle internal docs
 	* mpz->powm fixed
+	* modules/math/math.c: sqrt optimized
 	
 Tue Oct 29 16:12:03 1996  Fredrik Hubinette  <hubbe@tymin.blarg.com>
 
diff --git a/src/modules/math/math.c b/src/modules/math/math.c
index baa0b35d78..844696cdee 100644
--- a/src/modules/math/math.c
+++ b/src/modules/math/math.c
@@ -68,14 +68,19 @@ void f_sqrt(INT32 args)
 
   if(sp[-args].type==T_INT)
   {
-    INT32 a,b,c,q;
-    q=sp[-args].u.integer;
-    for(a=0,b=0x10000;a+1<b;)
+    unsigned INT32 n, b, s, y=0;
+    unsigned INT16 x=0;
+    
+    n=sp[-args].u.integer;
+    for(b=1<<(sizeof(INT32)*8-2); b; b>>=2)
     {
-      c=(a+b)/2;
-      if(c*c>q) b=c; else a=c;
+      x<<=1; s=b+y; y>>=1;
+      if(n>=s)
+      {
+	x|=1; y|=b; n-=s;
+      }
     }
-    sp[-args].u.integer=a;
+    sp[-args].u.integer=x;
   }
   else if(sp[-args].type==T_FLOAT)
   {
diff --git a/src/modules/math/testsuite.in b/src/modules/math/testsuite.in
index 44001823a2..6d8eefbb9f 100644
--- a/src/modules/math/testsuite.in
+++ b/src/modules/math/testsuite.in
@@ -26,7 +26,9 @@ test_true(cos(atan(1.0))<0.708)
 test_eq(4,sqrt(16))
 test_eq(4,sqrt(17))
 test_eq(4,sqrt(24))
+test_eq(sqrt(0x7fffffff),46340)
 test_eq(4.0,sqrt(16.0))
+test_any([[int e,i; for(e=0;e<100000;e++) { i=sqrt(e); if(i*i>e || (i+1)*(i+1)<e) return e; } return -1;]],-1)
 // - floor
 test_eq(17.0,floor(17.0))
 test_eq(17.0,floor(17.1))
-- 
GitLab