//Bit function macros for positive intergers 
// by Leroy Whetstone Email lrwii@joplin.com

// this should be called only once per use

//Bit(interger,bit place) returns 0,1 
//Bits(interger) number of bits in number
//BitsOn(interger) number of bits on(1) in number
//BitOR(interger, interger) bit OR two numbers 
//BitAND(interger, interger) bit And two numbers 
//BitClear(interger, bit) clears bit from number
//BitSet(interger, bit) Sets bit in number
//StrTno(String,interger) turns string "0001" into interger 8
//NoTstr(interger,String) turns interger 12 into string "0011" 

#macro Bit(a,b) //no.,bit return 0 or 1
 #local c= int(a/pow(2,b));
 select(mod(c, 2), 1, 0, 1)
#end

#macro Bits(a) //no. return int O= number of bits places
 #local O=int(log(a)/log(2));
 //#debug concat("O=",str(O,3,3),"\n")
 O
#end

#macro BitsOn(a)//no. N_bits returns number of value 1 bits
 #local Ot=0;
 #if(a!=0)
  #local c=Bits(a);
  #local P=0;
  #while (P<c+1)
   #if (Bit(a,P)) #local Ot=Ot+1; #end
  #local P=P+1;
  #end
 #end
 Ot
#end

#macro BitOr(a,b)//no.,no. N_bits returns a=int number<512
 #local Ot=0;
 #local c=a; #if (b>a) #local c=b; #end
 #local c=Bits(c);
 #local P=0;
 #while (P<c+1)
  #if (Bit(a,P)|Bit(b,P)) #local Ot=Ot+pow(2,P); #end
 #local P=P+1;
 #end
 #declare a=Ot;
#end

#macro BitAnd(a,b)//no.,no. N_bits returns int number<512
 #local Ot=0;
 #local c=a; #if (b>a) #local c=b; #end
 #local c=Bits(c);
 #local P=0;
 #while (P<c+1)
  #if (Bit(a,P)&Bit(b,P)) #local Ot=Ot+pow(2,P); #end
 #local P=P+1;
 #end
 #declare a=Ot;
#end

#macro BitClear(a,b)//no.,bit. returns int 
  #if(Bit(a,b)) 
   #local d= pow(2,b);
   #declare a=a-d;
  #end
#end

#macro BitSet(a,b)//no.,bit. returns int 
  #if(!Bit(a,b))
   #local d=pow(2,b);
   #declare a=a+d;
  #end
#end    

#macro StrTno(s,N)//N,str returns N=int 
  #local b=strlen(s);
  #declare N = 0;
  #local Cnt = 1;
 #while (Cnt <= b)
   #if(asc(substr(s,Cnt,1))=49) #declare N=N+pow(2,Cnt-1); #end
 #local Cnt = Cnt+1; 
 #end
#end

#macro NoTstr(N,s)//str,N returns a=string 
  #if(N<0) #error "NoTstr(N,s) has a negative value" #end
  #local a=N;
  #local Cnt = 1;
 #while (a >0)
   #local a=a/2;
   #if(a!=int(a)) #declare s=concat(s,"1")
   #else #declare s=concat(s,"0")
   #end
   #local a=int(a);
 #end
#end


#ifndef(Get)
#include "colors.inc"

 #declare A=37;
 #declare B=68;
 #declare Bt=0;//bit location
  
 #declare C=Bit(A,Bt);
  #debug concat("\n\nA= ",str(A,0,0),"  B= ",str(B,0,0),"  Bt= ",str(Bt,0,0),"\n\n")
  #debug concat("Bit(A,Bt) the Bit ",str(Bt,0,0)," in ",str(A,0,0)," is ",str(C,0,0),"\n\n")
 #declare C=Bits(A); 
  #debug concat("Bits(A) number of Bits in ",str(A,0,0)," is ",str(C,0,0),"\n\n")
 #declare C=BitsOn(A); 
  #debug concat("BitsOn(A) number of Bits on(1) of ",str(A,0,0)," is ",str(C,0,0),"\n\n")
 #declare C=A; BitOr(A,B) 
  #debug concat("BitOr(A,B) ",str(C,0,0)," or ",str(B,0,0)," = ",str(A,0,0),"\n")
  #debug concat("... A= A or B ...\n\n")
  #declare A=C;
 #declare C=A; BitAnd(A,B) 
  #debug concat("BitAnd(A,B)  ",str(C,0,0)," and ",str(B,0,0)," = ",str(A,0,0),"\n")
  #debug concat("... A= A and B ...\n\n")
  #declare A=C;
 #declare C=A; BitClear(A,Bt) 
  #debug concat("BitClear(A,Bt) Clear bit ",str(Bt,0,0)," of ",str(C,0,0)," Now A= ",str(A,0,0),"\n\n")
  #declare A=C;
 #declare C=A; BitSet(A,Bt) 
  #debug concat("BitSet(A,Bt) Set bit ",str(Bt,0,0)," of ",str(C,0,0)," Now A= ",str(A,0,0),"\n\n")
  #declare A=C;
 #declare Str="0101"; StrTno(Str,A)
  #debug concat("StrTno(Str,A) String is \"",Str,"\"  Now A= ",str(A,0,0),"\n\n")
  #declare A=C;
 #declare Str=""; NoTstr(A,Str)
  #debug concat("NoTstr(A,Str) A is ",str(A,0,0),"  Now Str= ",Str,"\n\n")

 camera{ location <0,5,-20>
        look_at <0,5,0>
        right x*image_width/image_height
        }
 background{rgb<.3,.4,.5>}
 light_source{<0,0,-10> color White}
 light_source{<10,0,-3> color White}
 light_source{<-10,0,-3> color White}

 text {
  ttf             // font type (only TrueType format for now)
  "crystal.ttf",  // Microsoft Windows-format TrueType font file name
  //"Binary Math",      // the string to create
   "Bit Macros",
  .01,              // the extrusion depth
  0               // inter-character spacing
 pigment{White}
 finish{ambient 1 diffuse 0}
 translate -x*2.5 scale 6  translate <0,8,0>
 no_shadow
 }
 text {
  ttf             // font type (only TrueType format for now)
  "crystal.ttf",  // Microsoft Windows-format TrueType font file name
  "11010101011",      // the string to create
  .01,              // the extrusion depth
  0               // inter-character spacing
 pigment{White}
 finish{ambient .8 diffuse 0}
 translate -x*2.75 scale 5  translate <0,-2,0>
 no_shadow
 }
 #declare Str="11010101011";
  StrTno(Str,A)
  #declare C=Bits(A);#debug concat("C =",str(C,0,0),"\n") 
 #declare Cnt = 0;
 #while (Cnt < C)
  #if(Bit(A,Cnt)>0) sphere{<Cnt*2.75-12.5,4,0>,.75 pigment{White}}
  #else sphere{<Cnt*2.75-12.5,4,0>,.5 pigment{Blue}}
  #end
 #declare Cnt = Cnt+1; 
 #end

#end
