質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

3回答

4438閲覧

小数点から整数への計算方法

nanu

総合スコア12

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2017/01/25 21:21

###前提・実現したいこと
いつもお世話になっております。
現在、日記のような形で『獲得した得点が表示される』表作りをしています。
参考にしている大元のURLです→株式会社ブライトシステム
また、前回の質問の続きでもあるので、こちらも再掲しておきます→過去の質問内容

AndroidStudio2.0での開発で進めており、
SQLなどもここにいらっしゃる有志様のおかげでやや進んでいる状態です。
以下、突き当たっている問題点です。
大雑把ですが、ご解答いただけるとありがたいです。

【進捗】
・数値の入力に整数を使い、入力画面から参照画面に移動する。
・移動した数値を小数にするため10で割り、参照画面で表示する。
-----

【実行したいこと】
・表示した参照画面の小数を整数に戻し、再編集画面に移動したい。
一度整数に戻したら、また参照画面に戻り、きちんと直っている状態を作る。
-----

###試したこと
単に10倍しただけではダメということはわかっているのですが、その方法がいまいち理解できていないです。とりあえずただ単に10倍しただけのものを載せておきます。

double a1 = Double.parseDouble(tv_point1.getText().toString()); double a2 = (double) a1 * 10; final TextView tv_point1 = (TextView) findViewById(R.id.TextView_view_point1); tv_point1.setText(String.valueOf(a2));

結果としては、例えば100,101,102…となっていた時、
3文字までと指定したときは100,100,100と表示されたり、4文字に増やしてみると100.,101.,102.…というように小数点が残ってしまいます。

わかりにくい文章で申し訳ありません。ご指摘よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

次のようにしてみてください。

int a2 = (int)(a1 * 10);

投稿2017/01/25 21:55

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanu

2017/01/25 22:24

お早い返答ありがとうございます。 一度試してみたのですが、結果はすべての数値が100になってしまいました… よく見たら勘違いされても仕方ない文章だったのでもう一度説明させていただきます。 もともと入れている数値は10.0,10.1,10.2,10.3…と続いており、a1=10.0となっています。 この10.0を一度再編集画面に移動したときには100にしたくて、参照画面に戻す時にはもう一度10.0にして表示させるようになります。
Zuishin

2017/01/25 23:20

この式ですべての数値が100になるということは、a1 は必ず 10 になっているということです。10.1, 10-.2... というデータは反映されていないと思います。 編集画面では 10 倍し、編集が終わったらそれを double に直して 1/10 しなければなりませんが、そのあたりいかがでしょうか?
nanu

2017/01/25 23:38

大まかな形をざっと説明すると、 ・入力画面、参照画面、再編集画面の3画面で構成されている ・入力画面(ユーザの入力は100,101,102)→そのまま渡される→参照画面(1度ここで10.0,10.1,10.2にする)→参照画面の表示も10.0,10.1,10.2と正常→そのまま渡される→再編集画面で10倍する→再編集画面の時点で100,100,100と表示されたり、100.,101.,102.と小数点が後ろに残る形になったりする。 という感じです…
Zuishin

2017/01/26 00:37

小数点が後ろに残るのは double から変換しているからだと思うので、一度 int に変換すれば直るはずです。その際すべて 100 になるのは int に変換してから 10 倍しているか、もしくは別のバグがあります。 int a2 = (int)(a1 * 10); と書きましたが、これを int a2 = (int)a1 * 10; としていませんか?
nanu

2017/01/26 07:38

お返事遅れました。 ご指摘通りの間違え方をしていました(お恥ずかしい)。 結果しっかりと整数値に直すことが出来ました。 作業が進みます!また機会があればよろしくお願いします。
guest

0

ご質問のプログラム自体は以下のようにすれば期待どおりの結果になると思います。

tv_point1.setText(String.valueOf((int)a2));

ただこうした計算にdoubleを使うことはあまりよくないと思うのでコメントします。

小数点以下の桁があるような数値を正確に扱いたい場合次のような戦略もあると思います。

  • 文字列のまま扱う

takitoさんがおっしゃっている文字として扱うときの一例です。数値型として値を10倍・10分の1にすると考えるのではなく文字列として表現されたもののまま小数点の文字を左右に移動すると考えます。

java

1// Stringとして表現した10進数sの小数点位置をn桁右へ移動する(n<0のときは左に移動) 2static String slideFloatingPoint(String s, int n) { 3 int fp = s.indexOf('.'); 4 String t = s.replace(".", ""); // 小数点を取り去る 5 if (fp == -1) 6 fp = t.length(); 7 fp += n; 8 while (fp <= 0) { 9 fp++; 10 t = "0" + t; 11 } 12 if (fp < t.length()) 13 return t.substring(0, fp) + "." + t.substring(fp); 14 while (fp > t.length()) { 15 t = t + "0"; 16 } 17 return t; 18} 19... 20String s1 = slideFloatingPoint("101", -1); // 10で割る(小数点を1桁左へ) 21// => s1 は "10.1"になる 22String s2 = slideFloatingPoint("10.1", 1); // 10かける(小数点を1桁右へ) 23// => s2 は "101"になる
  • BigDecimalを使う

文字列としてではなく数値としても扱う必要があるなら何らかの数値型を使うことになりますが、10進数として循環小数でない小数を正確に扱う必要があるならdoubleは不適切でBigDecimalを使うのがよいと思います。

java

1// "101"(を数値として解釈したもの)を10で割る 2BigDecimal d1 = new BigDecimal("101").divide(BigDecimal.TEN); 3String s1 = d1.toString(); 4//=> d1は10.1に、s1 は "10.1"になる 5 6// "10.1"(を数値として解釈したもの)に10かける 7BigDecimal d2 = new BigDecimal("10.1").multiply(BigDecimal.TEN); 8String s2 = d2.toString(); 9//=> d2は101.0に、s2 は "101.0"になっちゃいます 10 11// d2の小数点以下の桁が不要だと分かっているとき 12int i3 = d2.intValue(); 13long l3 = d2.longValue(); 14String s3 = String.valueOf(l3); 15//=> i3とl3は101に、s3は"101"になる

余談:
doubleは科学技術計算など一定の誤差があることを許容するような計算に向いていますが、10進数での小数を正確に表現する必要がある場合は向きません。なぜなら計算機の中では我々が普段使う10進数ではなく2進数で数値を表現しており、10進数と2進数では同じ値でも循環小数になるかどうかが違うからです。例えば0.1は10進数では循環小数ではありませんが、2進数では循環小数(0.0001100110011001...)になります。
本件では整数を10で割ったりかけたりしており小数点数以下の値となったときに実は誤差が生じています。この程度だとdoubleを用いても10かけた結果は元の値と(多分)一致します。しかし元の値がlongの範囲だったり、100で割ったりかけたりすると期待外の結果になる場合が生じます。例えば以下のようなプログラムを動かすと"mismatch!"と印字されます。

java

1int i = 7; // 他に14,28,29,55,56,57,58,...なども結果が不一致になる 2double d = i / 100 * 100; 3if (i != d) { 4 System.out.println("mismatch!"); 5}

doubleを使っても数値によっては期待通りに動いたりするのでバグに気が付きにくいのですが、いつか同じ考え方で100で割ったりかけたりするプログラムを書いたときに落とし穴にはまってしまうかも知れません。doubleを使っても問題ないかBigDecimalのようなものを使うべきかは意識しておいた方がよいと思います。

投稿2017/01/26 04:29

編集2017/01/26 04:31
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanu

2017/01/26 07:47

お返事ありがとうございます。 非常にわかりやすく、丁寧な解答で見やすかったです! 同じような記事を見た時、面倒そうで(難しそうで)手をつけたくないと思っていたのですが、takito様のご意見と合わせて参考にして挑戦してみたいとも思いました。 ゆっくりと挑戦できそうなので、後々試してみようと思います。 また機会があったらよろしくお願いします。 ご丁寧にありがとうございました!
guest

0

・入力画面、参照画面、再編集画面の3画面で構成されている

・入力画面(ユーザの入力は100,101,102)→そのまま渡される→参照画面(1度ここで10.0,10.1,10.2にする)→参照画面の表示も10.0,10.1,10.2と正常→そのまま渡される→再編集画面で10倍する→再編集画面の時点で100,100,100と表示されたり、100.,101.,102.と小数点が後ろに残る形になったりする。

このあたりを読んで思ったことは
「入力した文字を内部で数値にしなければいけない理由がるか?」
です

内部的には入力した数値を「文字」のまま保持して、別画面で使いたいときに、必要なかたちに加工して表示するなり計算するなりしたらよいと思いますが、いかがでしょうか

投稿2017/01/26 00:27

takito

総合スコア3111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanu

2017/01/26 07:43

お返事ありがとうございます。 一度数値に直さなければならない理由は特にないようでしたので  別の方法も試してみたいと思いました。(調べた時は面倒そうだなと思って手をつけていなかったので…) 貴重なご意見ありがとうございました! また機会があればよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問