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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

5回答

4215閲覧

うるう年について(小数点以下の割り切れるかの判別について)

ksk_2200

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/07/27 01:06

先日、こちらでいろいろな方々に答えていただいたことを参考に改善はしたのですが、どうにも解決しないので、もう一度お知恵を貸していただけないでしょうか。うるう年のコードなのですが、%の剰余による判別で割り切れるか割り切れないか条件式で算出していました。

従来までは閏年の年号を条件式で整数で割り切れると思っていたので閏年でも閏年ではないと出力していました。そこで小数点以下で割り切れるか判断するために、yearの変数をint型からdouble型にするなどしてみましたがうまくいきませんでした。```Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

//西暦が4で割り切れる年は閏年である。
//ただし、100で割り切れる年は閏年ではない。
//ただし、400で割り切れる年は閏年である。
public class Uru_year {
public static void main(String[]args)throws IOException{

System.out.println("西暦で年号を入力してください"); BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); try{ String num=br.readLine(); double year=Integer.parseInt(num); if(year<1898){ System.out.println(year+"年は日本がまだ閏年を考えた暦を採用していません。wiki参照。"); }else if(year%4==0 && year%100!=0 && year%400==0){ System.out.println(year+"年は閏年です。"); }else if(year%4==0 && year%100==0 && year%400!=0){ System.out.println(year+"年は閏年ではありません"); }else if(year>2100&&year<2999){ System.out.println(year+"年はあまり現実的ではありません。"); }else{ System.out.println(year+"年は閏年ではありません"); } } catch(NumberFormatException e){ System.out.println(e); System.out.println("数字が入力されていません。"); }

}
}

どうか解決策のヒントをください。 よろしくお願いします。

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

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

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

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

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

m.ts10806

2017/07/27 01:13

<code>部分が正しく反映されていません。質問編集画面で右側にプレビューが出ているのでそちらを確認しながら質問を編集してください。
swordone

2017/07/27 15:05

前回の質問に一切コメントなどせず、何を参考にして「改善」したのか全く不明です。前回の質問への回答をきちんと読んでいれば、こんなコードには絶対なるはずがありません。
ksk_2200

2017/07/27 15:24

snowdone様へ 前回の質問の件まったくその通りだと思います。先走って行動してしまい確認を怠ってしまったことを深く反省してます。質問に答えて頂き本当にありがとうございました。
guest

回答5

0

前回の質問からなぜdoubleにするという発想に至ったのかが大変謎です。
条件演算子の&&や||が理解できていないようです。

うるう年の判定条件は
0. 4で割り切れること
0. ただし、100で割り切れるものは平年
0. ただし、400で割り切れるものはうるう年

です。図にするとこうなります。(オレンジの部分がうるう年)
うるう年
これを表現するのにyear%4==0 && year%100!=0 && year%400==0では適しません。前二つが外側のオレンジ部分を、最後の条件が内側のオレンジ部分を示しているので、これを&&でつないだら該当するものが1個もなくなります。

投稿2017/07/27 01:21

swordone

総合スコア20651

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

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

ksk_2200

2017/07/27 15:33

図解でイメージが掴めました。わざわざ忠告して頂きありがとうございました。色々と勉強になりました。 ありがとうございます。
guest

0

グレゴリオ暦以前は、うるう年は4年に一度(=400年間で100日)でした。
地球の公転周期は365.25日ではなく、365.2422日ですから、400年間で (0.2422 * 400)、96.88 日分補正する必要があります。
そこでざっくりと「400年間に97日追加する」というのを実現するのが、現在のグレゴリオ暦でのうるう年の法則です。

  1. 4で割り切れる年はうるう年とする(400年間で100日)
  2. ただし、100で割り切れる年はうるう年としない(400年間で100-4 = 96日)
  3. ただし、400で割り切れる年はうるう年とする(100-4+1 = 97日)

これを素直に if の多重で実現してもよし、あるいは少し変形して「4で割り切れるが100で割り切れない、もしくは400で割り切れる」として

Java

1 bool isLeap = ( ( (year % 4 == 0) && (year % 100 != 0) ) || (year % 400 == 0) );

としてもよいです。
まあ普通に Java 使う、ならそもそも GlegorianCalendar 型使えば、isLeapYear で判定できるのですけれどもね。(課題などで使えないなら仕方ないですが)

Java

1 GlegorianCalendar cal = new GlegorianCalendar(); 2 string msg1 = cal.isLeapYear(2020) ? "うるう年" : "平年"; // うるう年 3 string msg2 = cal.isLeapYear(2100) ? "うるう年" : "平年"; // 平年 4 string msg3 = cal.isLeapYear(2000) ? "うるう年" : "平年"; // うるう年

※ちなみに400年間の総日数は 365400 + 97 = 146097 で、これは7で割り切れます。(=720871)
つまり、本日と400年後の本日は、必ず曜日が同じになります。

投稿2017/07/27 02:02

tacsheaven

総合スコア13703

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

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

ksk_2200

2017/07/27 15:30

グレゴリオ歴について知ることができました。ありがとうございます!
guest

0

double型にする必要はありません。条件式に問題があります。

Java

1else if(year%4==0 && year%100!=0 && year%400==0){ 2 System.out.println(year+"年は閏年です。"); 3} 4else if(year%4==0 && year%100==0 && year%400!=0){ 5 System.out.println(year+"年は閏年ではありません"); 6}

『4で割り切れて、100で割りきれなくて、400で割り切れたらうるう年』という判定になっています。


泥臭い方法ですが、素直に組んでみればいいんじゃないですかね。

Java

1else if(4で割り切れる) { 2 if(100で割り切れる) { 3 if(400で割り切れる) { 4 // うるう年 5 } 6 else { 7 // うるう年じゃない 8 } 9 } 10 else { 11 // うるう年 12 } 13}

かなり冗長なプログラムですが、まずは簡単な方法でやってみましょう。

投稿2017/07/27 01:28

LouiS0616

総合スコア35660

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

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

m.ts10806

2017/07/27 01:35 編集

> 泥臭い方法ですが ヘタにたくさんつなげるよりもこの書き方の方が読みやすいし条件を理解しやすいですしね。
LouiS0616

2017/07/27 01:53

そうですね。結局問題を分解する力が、最低限のセンスとして求められている気がします。
ksk_2200

2017/07/27 15:31

やっていて混乱するので紐解く技術が必要なんですね。勉強になりました。
guest

0

いろいろ他の方の回答は出そろってるので別観点で...。
・プログラム的な話
double型で正確な計算はできないのは知ってるでしょうか?特に割り算は破壊的。今回のケースはたまたま上手くいくかもしれないが。
・ロジックの話
「year%100==0 && year%400!=0」とかそもそもありえんよ、という話は他の方がさんざんしてるのではしょりますが(大事なとこですが)、仮にここらのロジックがうまくかけてたとしてyear=4000いれたたどうですか?先に閏年判定のif文入ってしまうので「else if(year>2100&&year<2999)」には入らないが問題ない?
・コーディングの話
条件がはっきりしてるものから先に判定してその先に処理をながさないという作り方もアリだと思う。
イメージでいうと「全集合を分割する」のではなく「フィルタをかけていく」感じ。
(私ならelse if使わないでreturnちゃいますが。)

Java

1if(year<1898){ 2return; 3} 4if(year>2100&&year<2999){ 5return; 6} 7if(year%400==0 || (year%4==0 && year%100!=0)){ 8return; 9} 10//ここまできたら閏年でない

投稿2017/07/27 05:06

kurokoba

総合スコア276

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

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

ksk_2200

2017/07/27 15:28

別観点からお話ありがとうございます!
guest

0

代理検索:JAVA leap year
こんなんで、事例が見つかりますけど、検索してみましたか?

投稿2017/07/27 01:18

daive

総合スコア2028

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

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

ksk_2200

2017/07/27 15:33

調べて見ます!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問