気になるJavaの問題を見つけたのでpaiza.IOで試してみた
こんなツイートを見つけた。
int a=1;
— おおおとり (@uwdd) 2017年7月18日
int b=++a;
System.out.println("a+b" + a+b);
の実行結果は
int a=1;
int b=++a;
System.out.println("a+b" + a+b);
の答えはどうなるか?という問題である。
本来の狙いはSystem.out.printlnのカッコの中の
"a+b" + a+b
のところが、最初に文字列があるのでそのあとの + 演算子が算術演算子ではなく文字列の連結を意味するという引っ掛け問題だ。
ツイートにはその後のやり取りで答えが書かれていて、ツイートの主によれば答えは
a+b12
だという。
私は引っ掛けに見事に騙されたが、答えが違う気がした。
コードをブラウザ上で実行できるサイトはいくつかあるが、その一つであるpaiza.IOで調べてみることにした。
Web-based online coding environment | paiza.IO
以下が実行結果である。
Web-based online coding environment | paiza.IO
答えは
a+b22
である。
考えてみれば、当たり前で++というインクリメンタル演算子でaの値は1が加算されて2になるはずである。
そして++の位置はaの前なので、bの値はaが2になったあとでそれが代入されたものになる。
とするとaもbも2になる。
ツイッターで間違っていると指摘したのだが、無反応だった。
FF外だから仕方がないかもしれないが。
とりあえず自分の考えが合っていたのがわかって良かった。
この文字列のあとの + が算術演算子にならないという引っ掛けにハマる人は結構多いようだ。
int a,b;
— ねぴちゃん (@NEPISAT) 2017年6月11日
a=10;
b=20;
System.out.println("A"+a+b);
みたいにするとA1020になるツボ
System.out.println("A"+a+b);
は
System.out.println("A"+(a+b));
とすれば、a+bは数値として加算される。
ちょっと気になった時に、気軽に試せるpaiza.IOは便利だ。
この問題もやってみた。
日経サイエンス2017年06月号パズル
— GEN (@gen_no_tweet) 2017年5月21日
int b=9765625;
int a=0;
for(int i=101; i<1101; i+2){
a=b*i;
if(全ての桁数が奇数か調べる関数(a)){
System.out.println("答え="a);
}
}
for文の3番目の書き方がおかしい。
多分、i = i + 2だと思う。
答えの出力の「"答え=“a」もおかしい。
文字列を連結しないといけない。
もろもろ修正して
int b = 9765625;
int a = 0;
for(int i = 101; i < 1101; i = i + 2) {
a = b * i;
if(全ての桁数が奇数か調べる関数(a)) {
System.out.println("答え = " + a);
}
}
これをif文なしで走らせてみたらintが最大値を超えてマイナスの値になってしまう。
2^31 - 1 = 2147483647
以上はマイナスの値になる。
多分、問題は正の値について考えるのだろうから、aとbはintではなくlongにした。
全ての桁数が奇数か調べる関数(a)をcheck(a)として、関数を作った。
全ての桁数という意味が良くわからないが、各桁の数について奇数か偶数か調べて、全てが奇数ならtrueを、一つでも偶数ならfalseを返すのだと解釈した。
各桁の数を抜き出すには以下のリンクの方法を使った。
複数桁10進数の*桁目だけを抽出したい - C言語・C++・C# 解決済 | 教えて!goo
a = (value % 10);
value /= 10;
1桁目は素直に10で割ったその余りがその数。
2桁目は10で割った答えとそれを10で割った余り。
と順にやっていく。
全部、合わせてこんな感じにしてみた。
public class Main {
public static void main(String[] args) throws Exception {
// Here your code !
long b = 9765625;
long a = 0;
for(int i = 101; i < 1101; i = i+2){
a = b*i;
if(check(a)) {
System.out.println("i = " + i);
System.out.println("答え = " + a);
}
}
}
static boolean check(long a) {
int value = 0;
boolean isOdd = true;
while(a > 0) {
value = (int)(a % 10);
isOdd = (value % 2 != 0);
if(!isOdd) break;
a /= 10;
}
return isOdd;
}
}
実行結果はこれ
Web-based online coding environment | paiza.IO
i = 327
答え = 3193359375
一つしかないらしい。
合っているかどうかはわからない。
久しぶりにJavaをやってみた。
あと
double a = 1.0; double b = 3.0; double c = 4.0; System.out.println(a+(b+c)); これの出力結果が7.9999999999999になるんだけどJava詳しい人教えて
— ゆとり (@os_yutori) 2017年4月22日
こういうのもあったので、これも試してみたが8.0になった。
Javaのバージョンや実行環境にもよるのだろう。
これも面白かった。
A related @java puzzle, how is this true?
— Peter Lawrey (@PeterLawrey) 2017年5月4日
double a= 017;
double b= 017.0;
System.out.println(a < b);#100DaysofJava
017と書くと8進数を意味する。
なのでaの値は10進数で15(浮動小数点の値を表すdoubleなので正しくは15.0)。
017.0だと通常の10進数の少数になって頭の0は無視される。
だから、a = 15.0とb=17.0を比べるとbの方が大きい。
よってa > b はtrueとなる。
0x17と入力すると16進数を表すので、これは10進数の23になる。
記憶とちょっと違ったのがこれ。
[Java] 老生常谈的 Java 面试题 字符相等: String a="abc";
— just4v2ex (@just4v2ex) 2017年3月24日
String b="abc";
System.out.println(a==b); https://t.co/uPTMiXPRR9
String a = "abc";
String b = "abc";
System.out.println(" a == b : " + (a == b));
System.out.println(" a.equals(b) : " + (a.equals(b)));
System.out.println(" a == \"abc\" : " + (a == "abc"));
これは本来はa == bはfalseになるべきだったはずだと記憶しているのだが、間違っていただろうか?
文字列変数としてのaとbは別なので、a == bはfalseになり、中身の文字を比べるための関数equals()で比べて、trueを得るのだったと思う。
“abc"がプールされて、共通に使われるためにこれを共通に参照するaとbは、a == bでもtrueになってしまうんだったと思う。
a == “abc"も同じか。
String b = new Stirng(“abc”)とするとaとbとは別になるので、a == bはfalseになる。