#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Mon, 02 Dec 2019 11:25:51 +0100
changeset 25038 ff2e11bf3826
parent 25037 de5003b510c4
child 25039 803a48c7a8c5
#FEATURE by cg class: LargeInteger added: #mightBeASquare
LargeInteger.st
--- a/LargeInteger.st	Mon Dec 02 10:45:32 2019 +0100
+++ b/LargeInteger.st	Mon Dec 02 11:25:51 2019 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1994 by Claus Gittinger
 	      All Rights Reserved
@@ -5545,6 +5547,42 @@
     "Modified: 5.11.1996 / 16:12:56 / cg"
 !
 
+mightBeASquare
+    "a quick (and cheap) check if the receiver is possibly a square"
+
+    | lsb |
+
+    self negative ifTrue:[ ^ false ].
+
+    "In base 16, a square number can end only with 0,1,4 or 9 and
+    - in case 0, only 0,1,4,9 can precede it,
+    - in case 4, only even numbers can precede it.
+    See http://en.wikipedia.org/wiki/Square_number
+    So, in hex, the last byte must be one of:
+            00
+            10
+            40
+            90
+            x1
+            e4
+            x9
+    where x is any hex digit and e is any even digit
+    Also, the receiver must be an aven power of two."
+
+    lsb := self byteAt: 1.
+    ^ (lsb == 0 and: [ self lowBit odd ])     "00 (and even power of 2)"
+            or: [ lsb = 16r40                       "40"
+            or: [ (lsb bitAnd: 16r7) = 1            "any|1 or any|9"
+            or: [ (lsb bitAnd: 16r1F) = 4           "even|4"
+            or: [ (lsb bitAnd: 16r7F) = 16 ]]]]     "10 or 90"
+
+
+    "
+     123456789012345678901234567890 mightBeASquare
+     123456789012345678901234567890 squared mightBeASquare 
+    "
+!
+
 mul2
     "private helper for division:
        destructively multiply the receiver by 2."