問題へのリンク
解答コード
詳細
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final int M = scanner.nextInt();
final int P = scanner.nextInt();
final int Q = scanner.nextInt();
double numerator = M * (100 - P) * (100 - Q);
double denominator = 100 * 100;
double answer = numerator / denominator;
System.out.println(answer);
scanner.close();
}
}
10進数計算
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final BigDecimal M = BigDecimal.valueOf(scanner.nextLong());
final BigDecimal P = BigDecimal.valueOf(scanner.nextLong());
final BigDecimal Q = BigDecimal.valueOf(scanner.nextLong());
BigDecimal unsolded = sold(M, P);
BigDecimal answer = sold(unsolded, Q);
System.out.println(answer);
scanner.close();
}
private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
private static BigDecimal sold(BigDecimal food, BigDecimal salePercentage) {
BigDecimal remainingPercentage = HUNDRED.subtract(salePercentage);
BigDecimal unsolded = food.multiply(remainingPercentage).divide(HUNDRED,4,RoundingMode.HALF_UP);
return unsolded;
}
}
}
解説
詳細
誤差について(基本情報技術者試験合格や高ランクを目指す人向け)
人間はこじらせている人以外は10進数で計算を行いますが、コンピュータは2進数で計算を行います。循環小数になる条件が10進数と2進数で異なる為、基本的に整数計算で行い、最後に除算を行うと誤差が最小限に抑えられます。
具体的には、分母・分子が整数かつ約分済み分数表記を行った際に、分母が2の乗数でないならば循環小数になります。10進数の場合は、分母が2と5の乗数で構成できない場合に、循環小数になりますので条件が緩いわけですね。
誤差をあまり気にしたくないなら
そういった誤差を最小限におさえるコツは、可能な限り整数計算で行うことです。
今回は、分子と分母を求め、最後に除算しています。
解法
Cでは誤差はさほど気にしなくても許容範囲内に収まることがほとんどですが、今のうち意識する癖をつけた方がいいです。
80%売れた場合、残りは20%になります。
言い換えれば80%売れた場合、(100-80)%残ります
(100-80)%残るということは、元の値を(100-80)倍して、100で割ると残量になります。
つまりMの(100-P)%残るということは
M * (100 - P) / 100
残るということです。
更にQも計算すると
M * (100 - P) / 100 * (100 - Q) / 100
が解答になります
できる限り整数計算を行う場合
M * (100 - P) * (100 - Q) ...分子
から
100 * 100 ...分母
を割るといいでしょう
10進数計算
銀行の基幹システムなど、10進数と2進数の違いが許されないパターン対応です。2進数計算と比較して、メモリに無駄が出る、パフォーマンスが落ちるといった弊害が出ますので。使用は最小限にしましょう。
BigDecimalは10進数かつ、有効桁数を自由に設定できるクラスです。ただ、有効桁数を設定しない状態で循環小数となる場合、例外が発生してしまいますので注意しましょう。
今回は小数点以下4桁あれば誤差は出ないのでスケールは4にしてます。