数値の型や演算子などについて学習する。
成果物
情報源
プロジェクト作成
dotnet new console -n NumbersInCSharp -o . cd NumbersInCSharp
備考。以下のように-o .
するとソリューションディレクトリが作成されず、ファイルがカレントディレクトリに展開される。
dotnet new console -n NumbersInCSharp -o .
ウザいので以下のようにしてソリューションディレクトリを作成するようにする。
dotnet new console -o NumbersInCSharp cd NumbersInCSharp
コード
Program.cs
using System; namespace NumbersInCSharp { class Program { static void Main(string[] args) { int a = 18; int b = 6; int c = a + b; Console.WriteLine(c); } } }
実行
dotnet run
やってみた
ドキュメントに書いてあるヤツをちょっとだけ自己流にしながら。すると多数のコンパイルエラーに遭遇した。
コンパイルエラー
とくに最後の面積を求める課題でつまづいた。
CS0220
: オーバーフロー
オーバーフロー時、コンパイルエラーになったようだ。
int what = int.MaxValue + 3;
Program.cs(76,24): error CS0220: この操作はチェック モードでコンパイルしたときにオーバーフローします。 [/tmp/work/NumbersInCSharp/NumbersInCSharp.csproj]
だが、ドキュメントには負数になると書いてある。
整数がオーバーフローして最大値から最小値に ”折り返され” たため、計算結果が非常に大きな負の値になっています。
挙動が違う。なぜ? 原因は不明だが、以下のコードに修正するとドキュメントどおりになる。
int max = int.MaxValue; int what = max + 3;
CS0664
: decimalリテラルにはM
サフィックスが必要
decimal r = 2.5;
Program.cs(128,25): error CS0664: 型 double のリテラルを暗黙的に型 'decimal' に変換することはできません。'M' サフィックスを使用して、この型のリテラルを作成してください [/tmp/work/NumbersInCSharp/NumbersInCSharp.csproj]
以下のコードに修正すること。
decimal r = 2.5M;
CS0193
: べき乗の演算子は**
でない
decimal aria = r**2 * Math.PI;
Program.cs(129,30): error CS0193: * または -> 演算子はポインターに対して使用してください。 [/tmp/work/NumbersInCSharp/NumbersInCSharp.csproj]
べき乗の演算子は**
でないってことかな? なら^
かな?
以下のコードに修正してみる。
decimal area = r^2 * Math.PI;
だが、以下のエラーになる。
CS0019
: 演算子 '^' を 'decimal' と 'double' 型のオペランドに適用することはできません
decimal area = r^2 * Math.PI;
Program.cs(129,28): error CS0019: 演算子 '^' を 'decimal' と 'double' 型のオペランドに適用することはできません [/tmp/work/NumbersInCSharp/NumbersInCSharp.csproj]
Math.PI
がdouble型なので、これに合わせるしかない。ということかな? 以下のようにコード修正してみる。
double r = 2.5; double area = r^2 * Math.PI; Console.WriteLine($"半径{r}cmの円の面積は{area}です。");
だが、以下のエラーになる。
CS0019
: 演算子 '^' を 'double' と 'double' 型のオペランドに適用することはできません
double r = 2.5; double area = r^2 * Math.PI; Console.WriteLine($"半径{r}cmの円の面積は{area}です。");
Program.cs(129,27): error CS0019: 演算子 '^' を 'double' と 'double' 型のオペランドに適用することはできません [/tmp/work/NumbersInCSharp/NumbersInCSharp.csproj]
どうやら型の問題ではないらしい。べき乗の計算をする演算子は**
でも^
でもないってことか?
ググってみると以下だった。
Math.Pow(r, 2);
というわけで、以下が答え。
double r = 2.5; double area = Math.Pow(r, 2) * Math.PI; Console.WriteLine($"半径{r}cmの円の面積は{area}です。");
ちなみに、C#における^
は排他的論理和の意味らしい。ビット演算子。
最終的なコード
using System; namespace NumbersInCSharp { class Program { static void Main(string[] args) { int a = 18; int b = 6; code0(a, b); code1(a, b); code2(); code3(); code4(); code5(); code6(); code7(); code8(); code9(); code10(); code11(); code12(); } static void code0(int a, int b) { int c = a + b; Console.WriteLine(c); } static void code1(int a, int b) { Console.WriteLine(a + b); Console.WriteLine(a - b); Console.WriteLine(a * b); Console.WriteLine(a / b); Console.WriteLine(a % b); } static void code2() { int a = 5; int b = 4; int c = 2; int d = a + b * c; Console.WriteLine(d); d = (a + b) * c; Console.WriteLine(d); d = (a + b) - 6 * c + (12 * 4) / 3 + 12; Console.WriteLine(d); } static void code3() { int e = 7; int f = 4; int g = 3; int h = (e + f) / g; Console.WriteLine(h); } static void code4() { int a = 7; int b = 4; int c = 3; int d = (a + b) / c; int e = (a + b) % c; Console.WriteLine($"quotient: {d}"); Console.WriteLine($"remainder: {e}"); } static void code5() { int max = int.MaxValue; int min = int.MinValue; Console.WriteLine($"The range of integers is {min} to {max}"); } static void code6() { int max = int.MaxValue; int what = max + 3; Console.WriteLine($"An example of overflow: {what}"); // int what = int.MaxValue + 3; // Console.WriteLine($"An example of overflow: {what}"); } static void code7() { double a = 5; double b = 4; double c = 2; double d = (a + b) / c; Console.WriteLine(d); double e = 19; double f = 23; double g = 8; double h = (e + f) / g; Console.WriteLine(h); } static void code8() { double max = double.MaxValue; double min = double.MinValue; Console.WriteLine($"The range of double is {min} to {max}"); } static void code9() { double third = 1.0 / 3.0; Console.WriteLine(third); } static void code10() { decimal min = decimal.MinValue; decimal max = decimal.MaxValue; Console.WriteLine($"The range of the decimal type is {min} to {max}"); } static void code11() { double a = 1.0; double b = 3.0; Console.WriteLine(a / b); decimal c = 1.0M; decimal d = 3.0M; Console.WriteLine(c / d); } static void code12() { double r = 2.5; double area = Math.Pow(r, 2) * Math.PI; // べき乗する演算子は`^`でも`**`でもない Console.WriteLine($"半径{r}cmの円の面積は{area}です。"); } } }
最終的な実行結果
$ time dotnet run 24 24 12 108 3 0 13 18 25 3 quotient: 3 remainder: 2 The range of integers is -2147483648 to 2147483647 An example of overflow: -2147483646 4.5 5.25 The range of double is -1.7976931348623157E+308 to 1.7976931348623157E+308 0.3333333333333333 The range of the decimal type is -79228162514264337593543950335 to 79228162514264337593543950335 0.3333333333333333 0.3333333333333333333333333333 半径2.5cmの円の面積は19.634954084936208です。 real 0m56.795s user 0m20.087s sys 0m1.710s
勉強になったこと
Console.WriteLine($"{変数名}")
標準出力のフォーマット形式。いつの間にこんなのができたんだ。
所感
エラーから正解を推論するには知識と慣れが必要か。だが、それを得るためにはネット検索が必要。
ビルド&実行がとにかく遅い。もう実行には最低1分かかると思ったほうがいい。とてつもなく遅い。信じられないほど遅い。もうC#触りたくなくなるくらい遅い。とにかく遅い。遅い遅い遅い。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux