//
/* ----------------------------------------------------------------------------------------------
adder32.java 32ビットの加算 ver. 1.00 (JDK 1.02)
ueyama@infonet.co.jp 2002.01.04
---------------------------------------------------------------------------------------------- */
import java.applet.Applet;
import java.awt.*;
import java.util.*;
public class adder32 extends Applet
{
int S[]=new int[4]; // 8ビット演算の和
int S1=0, S4=0; // 演算ステップ数
int X1=58, Y1=26; // 32ビット演算表示オフセット
int X4=30, Y4=236; // 8ビット演算表示オフセット
boolean C=false; // Carry
boolean Ac=true; // Add with Carry
boolean B8=false; // true: 8, false: 32 ビット演算
int Bp=19; // 2進数表示ピッチ
int Op=Bp*8+20; // 1バイト表示ピッチ
long La=0, Lb=0;
String Sa, Sb, Ss;
String Ba[]=new String[4], Bb[]=new String[4], Bs[]=new String[4];
int A[]=new int[4], B[]=new int[4];
int grn=Integer.valueOf("ccffcc",16).intValue(); // 表示色の定義
int orn=Integer.valueOf("ffcccc",16).intValue();
int blu=Integer.valueOf("ccffff",16).intValue();
int pnk=Integer.valueOf("ffccff",16).intValue();
int bgc;
Image Img;
Random rnd=new Random();
Graphics gr;
public void init()
{
String Bg=getParameter("BgColor");
bgc=Integer.valueOf(Bg,16).intValue();
setBackground(new Color(bgc));
MediaTracker mt=new MediaTracker(this);
Img=getImage(getCodeBase(), getParameter("figure"));
mt.addImage(Img, 0);
try
{
mt.waitForID(0);
}
catch(InterruptedException e){};
gr=getGraphics();
new_ab();
}
public void cal_sum() // 8ビット演算 和の文字列をつくる
{
for(int i=0;i<4;i++)
{
if(Ac) Bs[3-i]=Ss.substring(i*8,(i+1)*8); // 8ビットに分割する
else Bs[3-i]=Integer.toString((Integer.parseInt(Ba[3-i],2)+Integer.parseInt(Bb[3-i],2))%256,2);
while(Bs[3-i].length()<8) Bs[3-i]="0"+Bs[3-i]; // "0" を加えて8ビットにする
}
}
public void b_to_s()
{
Sa=Long.toString(La,2); // 2進数文字列をつくる
Sb=Long.toString(Lb,2);
Ss=Long.toString(La+Lb,2);
while(Sa.length()<32) Sa="0"+Sa; // "0" を加えて32ビットにする
while(Sb.length()<32) Sb="0"+Sb;
while(Ss.length()<32) Ss="0"+Ss;
A[3]=(int)La/16777216; A[2]=(int)(La/65536)%256; A[1]=(int)(La/256)%256; A[0]=(int)La%256;
B[3]=(int)Lb/16777216; B[2]=(int)(Lb/65536)%256; B[1]=(int)(Lb/256)%256; B[0]=(int)Lb%256;
for(int i=0;i<4;i++)
{
Ba[i]=Integer.toString(A[i],2); // 2進数文字列をつくる
while(Ba[i].length()<8) Ba[i]="0"+Ba[i]; // "0" を加えて8ビットにする
Bb[i]=Integer.toString(B[i],2);
while(Bb[i].length()<8) Bb[i]="0"+Bb[i];
}
}
public void new_ab() // 加数・被加数を作る
{
int i, f=1;
while(f>0)
{
La=(long)Math.abs(rnd.nextInt());
Lb=(long)Math.abs(rnd.nextInt());
b_to_s();
for(i=0;i<3;i++) if(A[i]+B[i]>256) f=0; // 加算でキャリーが立つ
if(La+Lb>0x7fffffffL) f=1;
if(A[3]+B[3]<32) f=1;
}
cal_sum();
}
public boolean inside(int x, int a, int b)
{
return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
}
public void dsp_img(int x, int y, int n, int m) // 画像の表示
{
Graphics gx=gr.create();
int w=0,h=0, ox=0,oy=0;
switch(n)
{
case 0: w= 16; h= 24; ox= 0; oy= 0; break; // 数字
case 1: w= 26; h= 23; ox=183; oy= 0; break; // |> ボタン
case 2: w= 26; h= 23; ox=183; oy= 23; break; // レ ボタン
case 9: w= 26; h= 23; ox=261; oy= 0; break; // □ ボタン
case 3: w= 12; h= 16; ox= 0; oy= 24; break; // Carry 表示用数字
case 4: w= 14; h= 14; ox= 60; oy= 18; break; // Check Box
case 5: w= 27; h= 14; ox= 88; oy= 18; break; // "ADD"
case 6: w= 95; h= 14; ox= 88; oy= 18; break; // "ADD with Carry"
case 7: w= 94; h= 19; ox= 88; oy= 32; break; // "10進数表示"
case 8: w= 11; h= 18; ox= 48; oy= 0; break; // 数字
}
gx.clipRect(x,y,w,h);
gx.drawImage(Img,x-(ox+w*m),y-oy,this);
gx.dispose();
}
public void dsp_bin(int x, int y, String s, int n) // 2進数の表示
{
for(int i=n-1;i>=0;i--) dsp_img(x+Bp*i,y,0,Integer.parseInt(s.substring(i,i+1)));
}
public void dsp_dec(int y, int n) // n: 0 = 32 bit, 1〜4 = 8 bit
{
int i, l, v, x=162;
String dec, bin="";
dsp_img(x-108, y-1, 7, 0);
if(n==0) v=Integer.parseInt(Ss,2);
else
{
for(i=n; i>0; i--) bin+=Bs[i-1];
v=Integer.parseInt(bin,2);
}
dec=Integer.toString(v);
l=dec.length();
for(i=0;i<12;i++, x+=13)
{
gr.setColor(new Color(bgc));
gr.fillRect(x, y, 13, 18);
dsp_img(x, y, 8, (i=0;i--) // 8ビット演算部の表示
{
x=Op*(3-i)+X4;
gr.setColor(new Color(blu));
gr.fillRect(x-4, Y4-4, Bp*8+4, 32);
gr.fillRect(x-4, Y4+40-4, Bp*8+4, 32);
dsp_bin(x, Y4, Ba[i], 8);
dsp_bin(x, Y4+40, Bb[i], 8);
dsp_ans4(x, i);
}
}
public void dsp_cary(int x, int y, int n) // Carry の表示
{
int c, f=(C)?1:0, d=(n%8==7 && y>Y1)?2:0;
if(B8 && !Ac && n%8==7) c=0;
else c=(Integer.parseInt(Sa.substring(31-n,32-n))+Integer.parseInt(Sb.substring(31-n,32-n))+f)/2;
dsp_img(x+2, y, 3, c+d);
if(n==31) dsp_img(x+2, y, 3, 4);
C=(c==1)?true:false;
}
public void dsp_ans1() // 32ビット加算の和の表示
{
gr.setColor(new Color((S1>0)? orn: bgc));
gr.fillRect(X1-4,Y1+86-4,Bp*32+4,32);
if(S1>0) gr.setColor(new Color(orn-0x006666));
for(int i=0;i<3;i++) gr.fillOval(Bp*8*(i+1)+X1-3,Y1+116,6,6);
if(S1>0) dsp_bin(X1, Y1+86, Ss, 32);
}
public void dsp_ans4(int x, int n) // 8ビット加算の和の表示
{
gr.setColor(new Color((S4>n)? pnk: bgc));
gr.fillRect(x-4, Y4+86-4, Bp*8+4, 32);
if(S4>n) dsp_bin(x, Y4+86, Bs[n], 8);
}
public void paint(Graphics g)
{
int i,j;
dsp_img(X4 -26,Y4 +40,0,2); dsp_img(X1-26,Y1+40,0,2); // + 符号の表示
dsp_img(630,Y1+130,2,(S1==0)?2:0);
dsp_img(630,Y4+130,2,(S4==0)?2:0); // レ ボタンの表示
dsp_img(660,Y1+130,1,(S1==0)?0:2);
dsp_img(660,Y4+130,1,(S4>3)?2:0); // |> ボタンの表示
dsp_img(590,Y4+130,9,(S4>0)?2:0); // □ ボタンの表示
dsp_add(); // 加算数値の表示
if(S1>0) for(i=0;i<32;i++) dsp_cary(Bp*(31-(i+1))+X1, Y1-24, i);
if(S1>0) dsp_dec(Y1+134, 0);
for(i=3;i>=0;i--)
{
if(i0) dsp_dec(Y4+134, S4);
dsp_img(382,Y4+135,4,(Ac)?1:0); // ADD Check Box
dsp_img(458,Y4+135,4,(Ac)?0:1); // ADD with Carry Check Box
dsp_img(402,Y4+135,5,0); // "ADD"
dsp_img(478,Y4+135,6,0); // "ADD with Carry"
}
public boolean mouseDown(Event e, int mx, int my)
{
int i,n=99,x;
long l=0, m=1;
boolean a=false;
if(inside(my,Y1+130,Y1+130+23)) // 32 ビット演算
{
B8=false;
if(inside(mx,660,660+26) && S1==0) // |> ボタン
{
dsp_img(660,Y1+130,1,1);
dsp_img(590,Y4+130,9,2);
for(i=0;i<32;i++) dsp_cary(Bp*(31-(i+1))+X1, Y1-24, i);
}
if(inside(mx,630,630+26) && S1>0) // レ ボタン
{
dsp_img(630,Y1+130,2,1);
if(S4==0) dsp_img(590,Y4+130,9,0);
}
}
if(inside(my,Y4+130,Y4+130+23)) // 8 ビット演算
{
B8=true;
if(inside(mx,660,660+26) && S4<4) // |> ボタン
{
dsp_img(660,Y4+130,1,1);
dsp_img(590,Y4+130,9,2);
for(i=0;i<8;i++)
{
n=S4*8+i;
dsp_cary(Op*(3-(n+1)/8)+Bp*(7-(i+1)%8)+X4, Y4-24, n);
}
}
if(inside(mx,630,630+26) && S4>0) // レ ボタン
{
dsp_img(630,Y4+130,2,1);
if(S1==0) dsp_img(590,Y4+130,9,0);
}
if(inside(mx,590,590+26) && S1==0 && S4==0) dsp_img(590,Y4+130,9,1); // □ ボタン
if(inside(mx,382,574)) // 加算切り替え
{
Ac=!Ac;
dsp_img(382,Y4+135,4,(Ac)?1:0); // "ADD" Check Box
dsp_img(458,Y4+135,4,(Ac)?0:1); // "ADD with Carry" Check Box
cal_sum();
}
}
if(S1+S4==0 && (inside(my,Y1-4,Y1+68) || inside(my,Y4-4,Y4+68))) // 数値の編集
{
x=mx-X4; i=152;
if((inside(x,0,i) || inside(x,Op,Op+i) || inside(x,Op*2,Op*2+i) || inside(x,Op*3,Op*3+i)) && my>Y4-4) n=(x-20*(x/Op))/Bp;
if(inside(mx-X1,0,Bp*32) && my0) dsp_dec(Y1+134, 0);
}
if(inside(my,Y4+130,Y4+130+23)) // 8 ビット演算
{
int i;
if(inside(mx,660,660+26) && S4<4) // |> ボタン
{
S4++;
dsp_img(630,Y4+130,2,0);
dsp_img(660,Y4+130,1,(S4>3)?2:0);
dsp_ans4(Op*(3-S4+1)+X4, S4-1);
dsp_dec(Y4+134, S4);
}
if(inside(mx,630,630+26)) // レ ボタン
{
S4=0; C=false;
dsp_img(630,Y4+130,2,2);
dsp_img(660,Y4+130,1,0);
if(S1==0) dsp_img(660,Y4+130,1,0);
for(i=0;i<4;i++) dsp_ans4(Op*(3-i)+X4, i);
gr.setColor(new Color(bgc));
gr.fillRect(0,Y4-24,size().width,16);
gr.fillRect(54,Y4+132, 258,20);
}
if(inside(mx,590,590+26) && S1==0 && S4==0) // □ ボタン
{
dsp_img(590,Y4+130,9,0);
new_ab();
dsp_add();
}
}
return true;
}
}
// 戻る