引き算
問題
今度は引き算です。6種類の言語を使って、とてもカンタンな引き算「128-256」の値を確認してみましたが、1つだけ出力結果が異なるものがあります。さて、それはどれでしょうか?
program Project1; {$APPTYPE CONSOLE} var x: Shortint; begin x := 128-256; Write(x); end.
#include <iostream> using namespace std; int main(int argc, char* argv[]) { __int8 x = 128-256; cout << x; return 0; }
public class Project1 { public static void main(String[] args) { byte x = 128-256; System.out.print(x); } }
namespace project1 { public class Project1 { public static void Main() { sbyte x = 128-256; System.Console.Write(x); } } }
<?php
$x = 128-256;
echo $x;
?>
x = 128-256 print x
解説
正解は「C++」。
C++では、期待した「-128」は出力されません。それ以外の言語では正しく「-128」が出力されます。Delphi/Java/C#/Ruby/PHPでは結果について特別意識することはないでしょう。C++では、通常の「int型」ではなく「__int8型」を使用しているのが気にかかります。
確かに「__int8型」は8bitの範囲(-128~127)の値を扱えますから、「-128」と出力されるべきでしょう。しかし一般的な実装では「__int8型」は「char型」であることから、「-128」を「文字(16進数で0x80)」として出力する処理が実行されます。この結果、「-128」とは出力されません。
問題のコードでは、short型などへの明示的なキャストが必要になります。以下に示すようなコードにより、期待した「-128」が出力されます。
cout << (short)x;
なお、C#では「byte型」ではなく「sbyte型」を使用しています。C#の「byte型」は符号無しですので、符号付きの値を処理するには「sbyte型」が必要となる点に注意が必要です。