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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

3643閲覧

byte の論理和に関するコンパイルエラーについて

GuielNo4

総合スコア88

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2017/07/17 09:21

###前提・実現したいこと
byte の論理和でコンパイルエラーが発生するのですが、
どのような基準でエラーとしているのか
ご存知の方がいらっしゃいましたらご教授願います。

###発生している問題・エラーメッセージ
コンパイルエラーはキャストで解決できるのでエラー自体は問題ではないのですが、
以下のコードを「なぜエラーとするのか」仕組みをご存じの方がいらっしゃいましたら、
ご教授頂けると助かります。

###該当のソースコード
List<byte> frame = new List<byte>() { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
byte[] arrayByte = frame.ToArray();
byte data = 0xFF & 0xFF; ---------(1)
data = arrayByte[0]; -----------------(2)
data = arrayByte[0] & 0xFF; ---------(3)
data = arrayByte[0] & (byte)0xFF; -----(4)
data = (byte)( arrayByte[0] & 0xFF ); -----(5)

(1)(2)(5) はエラーになりません。
(3)(4) は int を byte に暗黙的に変換できませんと言われます。

ひょっとして論理和とはいえ構文的には演算なので、
「桁上がり」が関係するのかと思い、(1)は 0xFF & 0xFF にしてみましたが、
エラーにはなりませんでした...

(5)で解決するのですが、それなら(4) でも解決しそうなのですが...
ちょっとモヤモヤするので質問させて頂きました。

アドバイスの程宜しくお願い致します。

###補足情報(言語/FW/ツール等のバージョンなど)
visual studio 2013
.NET Framework 3.5

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

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

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

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

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

guest

回答3

0

ベストアンサー

多分そういうことだろうと思って言語仕様を調べてみるとそうでした。
C# 言語仕様 | Microsoft Docs
の 7.3.6.2 Binary numeric promotions に記述があります。

&を含む二項数値演算子は、どちらかのオペランドが decimal、double、float、ulong、long、uint のどれでもない場合、両方のオペランドは int型 に暗黙変換されます。

つまり、事前にbyte型にキャストしようが、演算する時点でまたint型になってしまいます。演算結果も当然int型です。

(1)がエラーにならない理由は日本語のページに書いてあります。
暗黙的な数値変換の一覧表 (C# リファレンス) | Microsoft Docs

int 型の定数式は、定数式の値が変換後の型の範囲内にある場合、sbyte、byte、short、ushort、uint、または ulong に変換できます。

と、定数式で値がbyte型に収まるため、byte型に暗黙変換されます。

投稿2017/07/17 11:05

編集2017/07/17 11:07
otn

総合スコア84507

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

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

GuielNo4

2017/07/17 12:15

回答ありがとうございます。 >両方のオペランドは int型 に暗黙変換されます。 >定数式の値が変換後の型の範囲内にある場合、byte に変換される。 以上2点で理解が出来ました。 もやもやがなくなりました。 ありがとうございました。
guest

0

リテラル(変数に代入されていない 0xFF などの数値)や
コンパイル時定数(const)同士の演算の場合、
ビルドの時点で値を確定することができるのでキャストが不要となるようです。

以下のようなコードで確認するとわかりやすいかと思います。

const byte B1 = 0xFF; const byte B2 = 0xFF; byte data1 = B1 + B2; //NG byte data2 = B1 - B2; //OK

投稿2017/07/17 10:20

oika

総合スコア425

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

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

GuielNo4

2017/07/17 12:18

回答ありがとうございます。 int型に変換されることは理解できたのですが、 キャストすることに抵抗がなくなったわけではありませんので、 アドバイス頂きました方法でなんとかできないかやってみたいと思います。 ありがとうございました。
guest

0

引用:より大きな記憶領域のサイズを持つ、リテラル以外の数値型を暗黙的に byte に変換することはできません。
byte (C# リファレンス)
※0xFFはint型のリテラルです。

投稿2017/07/17 10:05

hihijiji

総合スコア4150

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

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

GuielNo4

2017/07/17 12:20

回答ありがとうございます。 0xFFがint型のリテラルとのこと、ご教授有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問