String型をfloat型に変換して計算した結果が予想と異なる理由

このQ&Aのポイント
  • 質問者は、String型からfloat型に変換して計算するプログラムを作成しました。
  • しかし、予想とは異なる結果が出力されています。
  • この理由について教えていただけると助かります。
回答を見る
  • ベストアンサー

出力結果について

java初心者です。 String型からfloat型に変換して計算するプログラムを作成しました。 class Foo { public static void main(String[] args){ String a = "0.00012"; String s = "1.2"; float f = Float.parseFloat(a); float g = Float.parseFloat(s); float t = (f+g); System.out.println(t); } } というプログラムを作ったんですが出力結果について 1.2001201 と出力され、最後の結果が”1.20012"になると思ったんですが "1.2001201"となっています。これはどうしてなんでしょうか? 教えていただけると助かります。

  • ci06
  • お礼率100% (8/8)
  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
noname#94983
noname#94983
回答No.1

まず、勘違いしてはならないのは、「0.00012」という数字は、実は「0.00012」ではない、という点。これは、正しくは「だいたい0.00012」だということを忘れてはならない。 コンピュータの世界では、実数は正しく扱うことができない。コンピュータの内部では数値は全て2進数で表現されるが、小数の場合、2進数では、10進数の小数をは正確な表現で表せないことがある。たとえば、0.1という値は、2進数では循環数(永遠に割り切れない数)となってしまう。これはたとえば「3分の1」が、10進数では正確に表現できないのと同じだと考えればいい。0.33333333……という値は、コンピュータのように「有限の桁数」で表現しようとすると必ず誤差を含んでしまう。 そんなわけで、実数の値には常に誤差が含まれている、と考えなければならない。1.2と0.00012を足すと、本来は1.20012のはずだが、両者の数字に含まれていた誤差が足されて0.0000001を越えてしまい、1.2001201という値になった、と考えればいいだろう。floatに限らずdoubleでも、これは変わらない。常に「実数は見えない誤差が含まれている」ということを考えながら処理するものだ、と考えるべき。

ci06
質問者

お礼

回答ありがとうございます。 わかりやすい説明で理解できました。 ありがとうございました。

関連するQ&A

  • 出力結果が得られる理由が分かりません

    一つ目のプログラムソース: public class Array{ public static void main(String[] args){ int[] a={1,2,3,4}; int[] b={5,6,7,8}; System.out.print(a[2]); System.out.print(b[2]); b=a; System.out.print(a[2]); System.out.print(b[2]); b[2]=0; System.out.print(a[2]); System.out.print(b[2]); } } 出力結果:  373300 二つ目のプログラムソース: class Box{ private int value; public Box(){value=0;} public Box(int v){setValue(v);} public void setValue(int v){value=v;} public int getValue(){return value;} public Box copy(){ Box b=new Box(); b.setValue(getValue()); return b; } } public class BoxTest{ public static void main(String[] args){ Box x=new Box(1); Box y=new Box(2); Box z=new Box(3); x=z.copy(); y=z; System.out.print(x.getValue()); System.out.print(y.getValue()); System.out.println(z.getValue()); System.out.println(x==y); System.out.println(y==z); System.out.println(z==x); } } 出力結果:  333 false true false この二つのプログラムがどうしてこのような出力結果になるのかが分かりません。 良かったら教えてください。

    • ベストアンサー
    • Java
  • シンプソン法の出力結果について

    シンプソン法の区間分割数nを10~100まで10ずつ増やして計算値と計算誤差を求めるプログラムを書きに作成したのですが、出力結果に-7.341865999405491E-5などとあります。この「E-数字」とはJavaではどういうこと示しているのですか? また、計算誤差の求め方は下記のプログラムでいいのですか? public class Simpson { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 100; // 区間分割数 for(n=10; n <=100; n+=10){ double h = (b - a) / (double)n; // 分割幅 double s, s1 = 0.0, s2 = 0.0; for (int i = 1; i <= n / 2; i++) { s1 += f(a + (2 * i - 1) * h); } for (int i = 1; i <= n / 2 - 1; i++) { s2 += f(a + 2 * i * h); } s = h / 3.0 * (f(a) + 4.0 * s1 + 2.0 * s2 + f(b)); double suti = (s-0.68269)/0.68269*100;  //計算誤差=(計算値ー真値)/真                                         値×100 System.out.println("区間分割数 =" + n); System.out.println("シンプソン法による計算値 =" + s); System.out.println("シンプソン法による計算誤差 ="+suti+"\n"); } } }

  • コンパイラのバグ?それとも

    下のようなコードを書いて、たとえば java PossibleCompilerMalfunction Hello のように実行すると、 Hello と表示されることを期待していたのですが、 null と表示されてしまいます。 (JDK1.5を使っています) final String t = args[0]; の部分を final String t = "Hello"; のように書き換えると、 Hello と表示されます。 つまり、コンパイル時に「t」の値が決まっていなければ nullになってしまうようです。 これってコンパイラのバグでしょうか。 あるいは私の考えに間違いがあるのでしたら、 指摘していただけるとありがたいです。 public class PossibleCompilerMalfunction { public static void main(String[] args) { final String t = args[0]; MyClass mc = new MyClass() { void foo() { System.out.println(t); } }; } static abstract class MyClass { MyClass() { foo(); } abstract void foo(); } }

    • ベストアンサー
    • Java
  • ファイルへの出力

    例えば、以下のようなプログラムがあります。 public class rei{ public static void main(String args[]){ for(int i=0;i<100;i++){ System.out.println(i); } } } ここで、iの値をエクセルファイルに出力することはできるのでしょうか?できれば具体的に教えてください。よろしくお願いします。

  • 参照・値渡しについて

    下記プログラム(ソース1)を実行すると「1」という値が出力されます。しかし、2行目をprivate static int a;とすると「0」という値が出力されます。 オブジェクトは参照渡しで基本データ型は値渡しと思ったのですが、2行目の値をString型で行ったところ全く変更されていない値が出力されました。(ソース2) 一体どういうことでしょうか? 回答のほどよろしくお願い致します。 (ソース1) public class X{ private static int a[] = new int[1]; public static void main(String []args){ modify(a); System.out.println(a[0]); } public static void modify(int a[]){ a[0]++; } } (ソース2) public class X{ static String a = "a"; public static void main(String []args){ modify(a); System.out.println(a); } public static void modify(String a){ a = "b"; } }

    • ベストアンサー
    • Java
  • JAVAアソシエイツの問題

    「SUN教科書 JAVAアソシエイツ P209 問5-7」からの問題についてです。 次のプログラムの空欄(1)に入れて実行すると、出力結果がtrueになる コードはどれですか。4つ選択してください。 class Sample{ public static void main(String[] args){ String s1 = "Hello"; String s2 = "Hello"; String s3 = new String("Hello"); System.out.println( 【(1)】 ); } } A. s1 == s2 B. s1 == s3 C. s2 == s3 D. s1 == "Hello" E. s3 == "Hello" F. s1.equals(s3) G. s2.equals(s3) 正解はADFGです。AFGに関しては理解出来るのですが、 どうして選択肢Dがtrueなのに選択肢Eはfalseになるのでしょうか。 よろしくお願い致します。  

    • ベストアンサー
    • Java
  • javaの出力結果について

    javaのプログラムを記述してますが、出力結果がnullになってしまいます。 解決策を教えて下さい。 ------出力結果------- null null null null null null -----------下記、ソースになります。------------ public class LibApp { public static void main(String[] args) { Library my_lib= new Library(); my_lib.addBook(new Book("吾輩は猫である","夏目 漱石","小説")); my_lib.addBook(new Book("奥の細道","松尾 芭蕉","小説")); my_lib.showBooks(); } } import java.util.ArrayList; import java.util.List; public class Library { List<Book> bList; public Library() { bList=new ArrayList<Book>(); } public void showBooks() { for (Book str : bList) { str.showBook(); } } public void addBook(Book book) { this.bList.add(book); } } public class Book { String title; String author; String content; public Book(String title, String author, String content) { title = this.title; author = this.author; content = this.content; } public void showBook() { System.out.println(title); System.out.println(author); System.out.println(content); } }

    • ベストアンサー
    • Java
  • 実行結果が1つしか出ない。

    いつも教えてくださり有難うございます。 Sample3 ↓ →JREシステム・ライブラリー src ↓ (デフォルト・パッケージ)   ↓ Sample3.java public static void main (String[] args) { System.out.println(1+1); System.out.println(1+1+2); } 実行結果が2は出るのですが 4が出ません。 どうしてでしょうか? ご回答のほど、宜しくお願い申し上げます。

    • ベストアンサー
    • Java
  • 1を0001として出力する処理

    public class Test_file { public static void main(String args[]) { for( int count = 0 ; count <= 10 ; count++) { System.out.println(count); } } } このプログラムを実行すると 0 1 2 3 4 5 6 7 8 9 10 と出力されますが、これを 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 と、連続して出力する処理を作成したいのですが、 この1桁を4桁にする処理が思い浮かばず苦戦している最中です。 自分でも考えてみたのですが、1を0001にしたり、 100を0100にする処理がどうしても思いつきません。 お手数ですが、上記のような処理ができる手立てを ご教授の程お願いします。

    • ベストアンサー
    • Java
  • final修飾子

    Javaでfinal修飾子があると学びました. ・メソッドはオーバーライドできない ・変数は値の変更ができない ・クラスは継承できない この3点を実現することが可能ですよね? #間違っている・他にもあるなら教えてください. 私はfinalを引数につけてみました. public class Test {   public static void main(String[] args) {      char[] s = {'s','a','t','o'};      System.out.println(s);      modify(s);      // finalのはずが変更されている      System.out.println(s);      Integer i = 3;      Integer j = 6;      swap(i, j);      System.out.println(i + ":" + j);      Foo f1, f2;      f1 = new Foo();      f2 = new Foo();      f1.i = 3;      f2.i = 6;      swap(f1, f2);      System.out.println(f1.i + ":" + f2.i);    }    static void modify(final char[] s) {      s[0] = 'k';    }    static void swap(Integer i, Integer j) {      Integer temp;      temp = i;      i = j;      j = temp;    }    static void swap(Foo f1, Foo f2) {      int temp;      temp = f1.i;      f1.i = f2.i;      f2.i = temp;    } } class Foo {    int i; } modify関数でfinal修飾子をつけるとsatoがkatoにならないと予想していました. ですが,実際にはコンパイルエラーにもならずsato→katoになりました. final修飾子はC言語でいうところのchar * const c;でしょうか? #ポインタの値は変更できないが,参照先の値は変更できるということですか? あと,swap関数についても質問があります. そもそもポインタがないので,基本型を実引数に与えるときはコピーされ, 参照型はコピーされないですよね? なので,swap関数を2つ用意してみました. Fooクラスのswap関数,Integerクラスのswap関数の2つです. Fooクラスがうまく交換でき,Integerクラスが交換できない理由がわかりません. #Integer temp;を使って参照値を交換していると思うのですが,違うのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう