算術オーバーフローは、算術演算や型変換などの計算の結果が、受け取る側の型に収まる範囲を超えたときに発生します。
int型とlong型、およびそれらの符号なしの型の式では、このような状況で暗黙のうちに値がラップアラウンドします。
整数の計算の動作は、checkedキーワードを使うことで変更できます。checkedブロックの中でオーバーフローが発生すると、OverflowExceptionのインスタンスがスローされます。
int one = 1;
checked
{
int expr = int.MaxValue + one; // OverflowException is thrown
}
// or
int expr2 = checked(int.MaxValue + one); // OverflowException is thrown
float型とdouble型の式では、無限大という特別な値になります。
decimal型の式では、OverflowExceptionのインスタンスがスローされます。
ハイペリアという国は、さまざまな問題を抱えています。とりわけ深刻なのが、制御不能なインフレです。中央銀行での仕事を引き受けるため、はるばる呼び寄せられました。
中央銀行は、内部の管理を簡単にするために、それぞれの額面を2つの部分に分けました。比較的変化しない_ベース_と、すべての額面で共通の_倍率_です。この_倍率_は、年に一度でも、週に一度でも、毎日でも変更できます。
紙幣に印刷される額面は、_ベース_と_倍率_の積になります。
この仕組みが導入された時点で、最小の紙幣の額面はすでに10,000,000でした。下の表は、この仕組みが最初に導入されたときの状況(最初の3つの額面)を示しています。それからというもの、状況はさらに悪化し、倍率だけでなくベースまで変わるようになりました。
| ベース | 倍率 | 額面 |
|---|---|---|
| 10,000 | 1,000 | 10,000,000 |
| 50,000 | 1,000 | 50,000,000 |
| 100,000 | 1,000 | 100,000,000 |
| ... | 1,000 | ... |
まとめると、額面 = ベース * 倍率 ということです。
CentralBank.DisplayDenomination()メソッドを実装してください。このメソッドはベースと倍率を受け取り、その積(ベース * 倍率)を文字列として返します。返される数値の文字列は整形しないでください。
乗算でオーバーフローが発生した場合は、文字列"*** Too Big ***"を返してください。
CentralBank.DisplayDenomination(10000L, 1000L);
// => "10000000"
CentralBank.DisplayDenomination(long.MaxValue / 2, 10000L);
// => "*** Too Big ***"
中央銀行は、内部でGDPを記録するときにも同じ倍率の考え方を使っています。統計はベースの額面で記録され、その後、倍率を使って引き上げられます。
CentralBank.DisplayGDP()メソッドを実装してください。このメソッドはベースのGDPと現在の倍率を受け取り、GDPを文字列として返します。
GDPを計算できない場合は、"*** Too Big ***"が返されます。
CentralBank.DisplayGDP(555f, 10000f);
// => "5550000"
CentralBank.DisplayGDP(float.MaxValue / 2, 10000f);
// => "*** Too Big ***"
銀行の上司は、給与支払いのときに問題が起きないようにしたいと考えています。
CentralBank.DisplayChiefEconomistSalary()メソッドを実装してください。このメソッドは、ベース単位で表された給与(上記と同じ)と倍率を受け取り、その積を含む文字列を返します。
給与を計算できない場合は、"*** Much Too Big ***"が返されます。
CentralBank.DisplayChiefEconomistSalary(555000m, 10000m);
// => "5550000000"
CentralBank.DisplayChiefEconomistSalary(555000m, decimal.MaxValue / 2L);
// => "*** Much Too Big ***"