diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e0f15db --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index ea7c316..3a4f570 100644 --- a/pom.xml +++ b/pom.xml @@ -4,9 +4,19 @@ info.istlab.IEEE754View IEEE754View jar - 1.0-SNAPSHOT + 0.10 IEEE754View http://maven.apache.org + + + 11 + UTF-8 + UTF-8 + 11 + 11 + + + junit @@ -15,4 +25,56 @@ test + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + info.istlab.IEEE754View.App + + + + + + maven-assembly-plugin + + + + + + + jar-with-dependencies + + ${project.artifactId}-${project.version}-launcher + false + + + + info.istlab.IEEE754View.App + + + all-permissions + . + + + + + + + + + diff --git a/src/main/java/info/istlab/IEEE754View/App.java b/src/main/java/info/istlab/IEEE754View/App.java index 4845708..81afc29 100644 --- a/src/main/java/info/istlab/IEEE754View/App.java +++ b/src/main/java/info/istlab/IEEE754View/App.java @@ -1,13 +1,24 @@ package info.istlab.IEEE754View; +import javax.swing.JFrame; + /** * Hello world! * */ public class App { + static JFrame jf; public static void main( String[] args ) { - System.out.println( "Hello World!" ); + jf = new JFrame("IEEE754 floating point viewer"); + IEEE754view view = new IEEE754view(); + jf.getContentPane().add(view); + // new IEEE754view(); + jf.pack(); + jf.setVisible(true); + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + jf.addWindowListener(view); } } diff --git a/src/main/java/info/istlab/IEEE754View/IEEE754view.java b/src/main/java/info/istlab/IEEE754View/IEEE754view.java new file mode 100644 index 0000000..d922ed3 --- /dev/null +++ b/src/main/java/info/istlab/IEEE754View/IEEE754view.java @@ -0,0 +1,283 @@ +package info.istlab.IEEE754View; + +import java.awt.BorderLayout; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +public class IEEE754view extends JPanel implements WindowListener { + + public static JFrame jf; + + /** + * @param args + */ + public static void main(String[] args) { + jf = new JFrame("IEEE754 floating point viewer"); + jf.getContentPane().add(new IEEE754view()); + // new IEEE754view(); + jf.pack(); + jf.setVisible(true); + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + } + + JTextField jtf10, jtf2, jtf16, jtf2real; + JTextArea jta, usage; + + public IEEE754view() { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + jtf10 = new JTextField(); + jtf2 = new JTextField(); + jtf2real = new JTextField(); + jtf16 = new JTextField(); + jtf16.setEditable(false); + JPanel v10P = new JPanel(new BorderLayout()); + v10P.setBorder(BorderFactory.createTitledBorder("10進数表記 (例:0.5, 0.25, -0.75)")); + v10P.add(jtf10); + JPanel v2P = new JPanel(new BorderLayout()); + v2P.setBorder(BorderFactory.createTitledBorder("IEEE754表記(2進数) 符号1bit, 指数8bit, 仮数23bit")); + v2P.add(jtf2); + JPanel v16P = new JPanel(new BorderLayout()); + v16P.setBorder(BorderFactory.createTitledBorder("上の「指数部」の説明")); + v16P.add(jtf16); + JPanel v2rP = new JPanel(new BorderLayout()); + v2rP.setBorder(BorderFactory.createTitledBorder("2進数表記 ( '1'+仮数23bit に、指数部を考慮して小数点や0を追加)")); + v2rP.add(jtf2real); + + jtf16.setEditable(false); + jtf2real.setEditable(false); + + jta = new JTextArea(10, 40); + JScrollPane scP = new JScrollPane(jta); + scP.setBorder(BorderFactory.createTitledBorder("IEEE754表記(2進数) ログ")); + jta.setEditable(false); + + usage = new JTextArea(4, 40); + usage.setBorder(BorderFactory.createTitledBorder("つかいかた説明")); + usage.setText("10進数表記のところに、好きな数字を入れてEnterを押すと、\nIEEE754表記(2進数)〜2進数表記 が更新されます。" + + "\n" + "逆に、IEEE754表記(2進数)のところに、0や1を入れてEnterを押すと、\n10進数表記などが更新されます。丸め誤差に着目してみましょう。"); + usage.setEditable(false); + + add(usage); + add(v10P); + add(v2P); + add(v16P); + add(v2rP); + add(scP); + + // setSize(500,500); + + jtf10.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent arg0) { + if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { + update10to2(jtf10.getText()); + } + } + + @Override + public void keyReleased(KeyEvent arg0) { + } + + @Override + public void keyTyped(KeyEvent arg0) { + + } + }); + // jtf10.addMouseListener(new MouseAdapter(){ + // public void mouseClicked(MouseEvent e){ + // jtf10.selectAll(); + // } + // }); + + jtf2.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent arg0) { + if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { + update2to10(jtf2.getText()); + } + } + + @Override + public void keyReleased(KeyEvent arg0) { + } + + @Override + public void keyTyped(KeyEvent arg0) { + + } + }); + // jtf2.addMouseListener(new MouseAdapter(){ + // public void mouseClicked(MouseEvent e){ + // jtf2.selectAll(); + // } + // }); + } + + void update10to2(String s10) { + System.out.println(s10); + float f = Float.parseFloat(s10); + System.out.println(Float.toHexString(f)); + StringBuffer sb = new StringBuffer("00000000000000000000000000000000"); + sb.append(Integer.toBinaryString(Float.floatToRawIntBits(f))); + + String orig = sb.substring(sb.length() - 32); + int sisuu = Integer.parseInt(orig.substring(1, 9), 2); + jtf2.setText(separated(orig)); + logappend(separated(orig) + " ← " + s10); + // jtf16.setText(Float.toHexString(f) + " / " + orig.substring(1, 9) + " = " + + // sisuu + " = 127 + ( " + (sisuu - 127) + // + " )"); + jtf16.setText(orig.substring(1, 9) + " = " + sisuu + " = 127 + ( " + (sisuu - 127) + + " )"); + System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f))); + + jtf2real.setText(orig754to2(orig)); + // System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(0.5f))); + // + // System.out.println(Integer.toBinaryString(1)); + // System.out.println(Integer.toBinaryString(2)); + } + + String orig754to2(String orig) { + int sisuu = Integer.parseInt(orig.substring(1, 9), 2); + int shift = sisuu - 127; + StringBuffer sb = new StringBuffer("1"); + sb.append(orig.substring(9)); + if (shift > -1) { + try { + sb.insert(shift + 1, "."); + } catch (StringIndexOutOfBoundsException ex) { + sb.append(" "); + for (int i = 1; i <= shift - 23; i++) + sb.append("0"); + // sb.deleteCharAt(23); + + } + } else { + StringBuffer pre = new StringBuffer(); + for (int i = 1; i <= Math.abs(shift); i++) { + pre.append("0"); + } + pre.insert(1, "."); + sb.insert(0, pre.toString()); + } + return sb.toString(); + } + + void logappend(String s) { + jta.append(s + "\n"); + jta.setCaretPosition(jta.getDocument().getLength()); + } + + void update2to10(String s2) { + // System.out.println(s2); + String orig = s2.replaceAll(" ", "") + "000000000000000000000000000000000000000000000"; + // System.out.println(orig); + int p; + try { + p = Integer.parseInt(orig.substring(1, 32), 2); + } catch (NumberFormatException e) { + JOptionPane.showMessageDialog(this, "入力値は変換できません"); + return; + } + int cursorpos = jtf2.getCaretPosition(); + jtf2.setText(separated(orig.substring(0, 32))); + jtf2.setCaretPosition(cursorpos); + float f = Float.intBitsToFloat(p); + if (orig.charAt(0) == '1') + f = -f; + int sisuu = Integer.parseInt(orig.substring(1, 9), 2); + // System.out.println(f); + if (Float.NaN != f) { + jtf10.setText(String.valueOf(f)); + jtf16.setText(orig.substring(1, 9) + " = " + sisuu + " = 127 + ( " + (sisuu - 127) + + " )"); + jtf2real.setText(orig754to2(orig.substring(0, 32))); + + // jtf16.setText(Float.toHexString(f) + " / " + orig.substring(1, 9) + " = " + + // sisuu + " = " + (sisuu - 127) + // + " + 127"); + logappend(separated(orig.substring(0, 32)) + " ⇒ " + String.valueOf(f)); + } else { + JOptionPane.showMessageDialog(this, "入力値は変換できません"); + } + } + + // IEEE754表記の、符号と指数と仮数4bitずつの区切りスペースをいれる。入力文字列は区切り無し。 + public String separated(String s) { + StringBuffer sb = new StringBuffer(s); + sb.insert(29, " "); + sb.insert(25, " "); + sb.insert(21, " "); + sb.insert(17, " "); + sb.insert(13, " "); + sb.insert(9, " "); + sb.insert(1, " "); + + return sb.toString(); + } + + // 10進数を2進数表記文字列へ変換するメソッド + public static final String toBinaryDigit(int a) { + StringBuffer buf = new StringBuffer(); + for (int i = 31; i >= 0; i--) { // Javaのintは32ビット(4バイト) + buf.append((a & (int) Math.pow(2, i)) >>> i); + } + return buf.toString(); + } + + @Override + public void windowOpened(WindowEvent e) { + jtf10.requestFocus(); + + } + + @Override + public void windowClosing(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowClosed(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowIconified(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowDeiconified(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowActivated(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowDeactivated(WindowEvent e) { + // TODO Auto-generated method stub + + } +}