Math.round()のように小数点以下を四捨五入するメソッド作りたいです。
できれば、数値計算(数学的に?)で実数を処理したいです。
自分で作れたのはintで型キャストするやり方で、あまり納得していません。
うまく数学的な処理で小数点以下を判別して、四捨五入の結果を返すことはできませんか?
ちなみに自作したものはこんなかんじです↓。
public class MyRoundTest {
// 四捨五入
static int myRound(double d){
int sign = (d < 0) ? -1 : 1;
double mid = (int)(d)+sign*0.5;
return (d*sign >= mid*sign)? (int)d+sign: (int)d;
}
public static void main(String[] args){
double[] d = {2.4, 2.5, -2.4, -2.5, 4.5};
for(double element : d){
System.out.println(element+"\t→\t"+myRound(element));
}
}
}
/*
出力結果は
2.4→2
2.5→3
-2.4→-2
-2.5→-3
4.5→5
です。
*/
No.3ベストアンサー
- 回答日時:
面白そうなので、ソースコードを追い掛けてみました。
OpenJDKのものですが、これを見ると、Math.round等は、StrictMathへのラッパーになってます。
http://grepcode.com/file/repository.grepcode.com …
StrictMathについては、以下に説明があります。
http://docs.oracle.com/javase/jp/6/api/java/lang …
roundについては
http://docs.oracle.com/javase/jp/6/api/java/lang …
そこにあった「Freely Distributable Math Library」から、floorのソースコードを見ます。
http://www.netlib.org/fdlibm/s_floor.c
これによれば。
・浮動小数点数の内部形式に直接アクセスして、 指数と仮数を得る。
浮動小数点数は、 符号(+1または-1) * a * 2^n (1.0<= a < 2.0 )の形式になっている
・a * 2^n の整数部だけ残すようにビットシフトする
はみ出た分(=小数部)は削られるので、整数化される
という方法が取られています。
質問を「round()の中身が見たい!」っていえば質問がわかりやすかったような気がしています...
ご回答ありがとうございます。
リンクすごくためになります。見たいもの色々と見れて、round以外もみたいです。お気に入りにしました☆
>これによれば。(省略します)
説明があって助かります。
Cの知らない所ばかりで書かれていて、ほとんど読めないので助かりました。
用意されているメソッドは効率よく作られているイメージがあるので、ビットレベル(?)で操作しているような気はしていました。小数をどのように管理しているかの仕組みを勉強してから、戻ってきます。
ありがとうございました。
No.6
- 回答日時:
あ、もしかして、
>そのとおりなんですけど。
というのは、「roundを使え」という意味だと思ったのですか?
リンク先を見ればわかりますが、roundの解説に、次の式が書いてあります。
Math.floor(a + 0.5)
これが直前に書いた(1)の丸め方の、もっともありふれた数学的(?)な表現です。
(リンク先には(2)の丸め方ととれるような書き方になっていますが、正しくは(1)の丸め方です)
>というのは、「roundを使え」という意味だと思ったのですか?
そう思ってしまいました。ごめんなさい。
この質問をした理由になるのですが、
(同じ内容が他のお礼と重複してしまいます)
なるべく最初から、round()メソッドを作ってみたかったということです。
既存の仕組みに頼ることなく(型キャストやメソッド)、何らかの式(四則演算で表せるような)でround()を実装してみたかったということです。
No.5
- 回答日時:
余計なことかもしれませんが、前に書いた、
>丸める数がきっちり0.5の時の扱いは、つごう3通りのやり方がある(それぞれ結果が違う)のですが、
について説明しておきます。
まず、これは、少数点以下の部分がきっちり0.5の時(0.5000000・・・)に限った話です。
で、3通りのやり方というのは、
(1) 常に+∞方向に丸める。-3.5は-3になる。
(2) 常に0から遠ざかる方向に丸める。-3.5は-4になる。
(3) JISの丸め規則に従った丸め方で、丸めた数が偶数になるように丸める。-3.5は-4に、-2.5は-2になる。
一番誤差が少なくなるのは(3)の丸め方ですが、通常は(1)の丸め方を使います。何のメリットがあるのか分かりませんが、事務系などでは(2)を使うこともあるようです。
前の解答で書いたリンクの方法では(1)の丸め方になります。
(3)のJIS丸めをしたい場合は。
(d-Math.floor(d))=0.5 ? Math.floor(d/2+0.5)*2 : Math.floor(d+0.5)
となります。
ちなみに(2)のまるめは
d >= 0 ? Math.floor(d+0.5) : Math.ceil(d-0.5)
とすればできます。
親身にご回答ありがとうございます。
「丸める」という言葉にあまり馴染みがなかったですが、文字のイメージからわかります。
>事務系などでは(2)を使うこともあるようです。
普通の四捨五入(算数でする)のイメージは個人的には(2)のような気がするのですが...
確認させてください。
(2)の方法では、
2.4 → 2.0
2.5 → 3.0
-2.4 → -2.0
ですよね?
No.4
- 回答日時:
たぶん一番手っ取り早いのは
目的の数値に対して0.5を足してその足した値に対してint型にキャストして少数以下を切り捨てる。
ご回答ありがとうございます。
なるべくなら、型キャストを使いたくなかったのです。
理由はなるべく自分で最初から作りたかったからです。既存の仕組みに頼らず、
小数点以下を切り捨てる仕組みを元に帰れば、「四則演算+剰余」ぐらいで作ってみたかったということです。
No.2
- 回答日時:
四捨五入なら、ごく普通に使われている丸め式を使えばよいです。
たとえば、ここのroundの解説を見てください。
http://www.javadrive.jp/start/math/index7.html
丸める数がきっちり0.5の時の扱いは、つごう3通りのやり方がある(それぞれ結果が違う)のですが、細かいことを言わなければ、前記の式で無問題
ご回答ありがとうございます。
>丸める数がきっちり0.5の時の扱いは、つごう3通りのやり方がある(それぞれ結果が違う)のですが、細かいことを言わなければ、前記の式で無問題
そのとおりなんですけど。
少しアルゴリズム的な問題で、どのようにすれば、自分でround()のようなメソッドを作ることができるかな?ということを考えたかったのです。
どうしても小数点以下を取り出す計算式を考えつくことができなかったので、質問させていただきました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
実数からの小数部の取得
-
0dの意味を教えてください
-
Javaで何パーセント%かを表示...
-
javaでのプログラミング
-
androidアプリが強制終了してし...
-
System.err. printlnとSystem.o...
-
ダブルクォーテーションのrepla...
-
IF関数でEmpty値を設定する方法。
-
Javaで改行などが出来ないのです。
-
JSPやサーブレットでSystem.out...
-
パソコンキーボードで時分秒を...
-
[Ljava.lang.Stringってなんですか
-
ダブルクォーテーションを含む...
-
sin曲線とcos曲線を描くプログ...
-
C言語のポインターに関する警告
-
C言語 重複しない4ケタの乱数...
-
マルチスレッドで同時にFTPアッ...
-
int型のゼロ埋め
-
Visual C++ でコントロールを...
-
1~100までの数字を表示し、か...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0dの意味を教えてください
-
実数からの小数部の取得
-
べき乗
-
Javaで何パーセント%かを表示...
-
Javaコンパイルエラー
-
最大値と最小値の求め方
-
double型変数値の整数部分のみ...
-
double型の足し算について
-
javaでC++のdefine文に相当する...
-
java のfor文について質問です。
-
java プログラム 範囲を指定し...
-
Javaのeval関数処理
-
Math.sin() を使った計算が合わ...
-
doubleとintの違い
-
自然対数の底Eを含むStringの数...
-
割り算
-
四捨五入
-
プログラムのおかしいところを...
-
doubleで入力するには?
-
実数 2.0 に対して int(2.0) ==...
おすすめ情報