
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で質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java Java 配列<選挙> 4 2023/07/31 15:07
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# (C言語)めちゃくちゃな値になってしまいます。 5 2022/08/13 11:55
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
double型変数値の整数部分のみ...
-
実数からの小数部の取得
-
プログラミング演習エラーについて
-
挿入演算子<<をオーバーロード...
-
Vectorクラスの使い方
-
javaアプレット repaintのタイ...
-
ピクチャボックスのクリックイ...
-
JAVAサーブレット。 HTML...
-
わかりません
-
System.err. printlnとSystem.o...
-
要素数が10の配列で、乱数0~9...
-
Javaで改行などが出来ないのです。
-
Excelの配列数式について
-
C言語のポインターに関する警告
-
変数を動的に利用するには?
-
String型の値が大文字か小文字...
-
JPanelの重ね方/OverlayLayout他
-
javaの演算子の部分ですが 4行...
-
C# 特定文字の数を調べる方法を...
-
for文を使った累乗の計算方法に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
実数からの小数部の取得
-
0dの意味を教えてください
-
べき乗
-
double型変数値の整数部分のみ...
-
フラクタルで雲を作る。
-
Javaで何パーセント%かを表示...
-
java のfor文について質問です。
-
最大値と最小値の求め方
-
プログラムのおかしいところを...
-
double型の足し算について
-
演算子を使わない演算
-
Javaによる利率計算の実装方法
-
四捨五入をするメソッドを実装...
-
Javaで計算
-
実数 2.0 に対して int(2.0) ==...
-
99.98+0.01の誤差
-
Java math.powメソッド
-
doubleで入力するには?
-
Javaのeval関数処理
-
掛け算演算を使わない掛け算
おすすめ情報