私が書いた小さなプログラムで 64 ビット整数を使用すると、非常に奇妙な動作が見られます。私のプログラムは次のことを行います...
- 2D long long int 配列 (X x Y) を作成します
- すべての配列インデックス値を 0 から X*Y -1 に初期化します
- 最初の行と最初の列のインデックスを値 1 に設定します
これが私のプログラムのコードです(numWaysXY_iterative.cc)
#include<stdio.h>
#include<iostream>
using namespace std;
void printMap(int X, int Y, long long int **map)
{
printf("printing map(%d, %d)...\n\n", X, Y);
for(long long int i = 0; i < Y; i++)
{
for(long long int j = 0; j < X; j++)
{
printf("(%lld, %lld) value: %lld\t", j, i, map[j][i]);
}
printf("\n");
}
printf("Finished Printing map\n");
}
long long int numWaysXY_iterative(long long int X, long long int Y)
{
long long int **map = new long long int*[X];
long long int value = 0;
for(long long int i = 0; i < X; i++)
{
map[i] = new long long int(Y);
for(long long int j = 0; j < Y; j++)
{
printf("i: %lld, j: %lld, value: %lld\n", i, j, value);
map[i][j] = value;
value++;
}
}
//debugging - print map
printMap(X,Y, map);
//initialize first row and first column entries to 1
for(long long int i = 0; i < X; i++)
{
map[i][0] = 1;
}
for(long long int j = 0; j < Y; j++)
{
map[0][j] = 1;
}
//debugging - print map
printMap(X,Y, map);
/*
for(int i = 0; i < X, i++)
{
for(int j = 0; j > Y, j++)
{
if
}
}
*/
return map[X-1][Y-1];
}
int main()
{
(void) numWaysXY_iterative(5,3);
}
コードをコンパイルして実行すると、この出力が得られます
$ g++ my_solution/numWaysXY_iterative/numWaysXY_iterative.cc -m64 -o executables/numWaysXY_iterative
$
$
$
$ ./executables/numWaysXY_iterative
i: 0, j: 0, value: 0
i: 0, j: 1, value: 1
i: 0, j: 2, value: 2
i: 1, j: 0, value: 3
i: 1, j: 1, value: 4
i: 1, j: 2, value: 5
i: 2, j: 0, value: 6
i: 2, j: 1, value: 7
i: 2, j: 2, value: 8
i: 3, j: 0, value: 9
i: 3, j: 1, value: 10
i: 3, j: 2, value: 11
i: 4, j: 0, value: 12
i: 4, j: 1, value: 13
i: 4, j: 2, value: 14
printing map(5, 3)...
(0, 0) value: 0 (1, 0) value: 3 (2, 0) value: 6 (3, 0) value: 9 (4, 0) value: 12
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10 (4, 1) value: 13
(0, 2) value: 3 (1, 2) value: 6 (2, 2) value: 9 (3, 2) value: 12 (4, 2) value: 14
Finished Printing map
printing map(5, 3)...
(0, 0) value: 1 (1, 0) value: 1 (2, 0) value: 1 (3, 0) value: 1 (4, 0) value: 1
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10 (4, 1) value: 13
(0, 2) value: 1 (1, 2) value: 1 (2, 2) value: 1 (3, 2) value: 1 (4, 2) value: 14
Finished Printing map
Problems:
1. After initializing the values of the array in lines 26 - 35, even though the value
variable is strictly increasing, and each array indice is supposedly getting a unique
value assigned to it, this is not being reflected in the array. You can see that
map[0][2] == map[1][0] for example.
2. I'm setting the first row and first column array elements to have the value 1 in lines
40 - 48, but again this is not reflected when the array is printed out. Instead it
seems that the first row, first column, and all elements in the last row besides the
last are being set to 1.
ロジックを何度か見直した後、何も問題がなかったので、代わりに「long long int」変数を int に置き換えるだけで、プログラムの別のバージョンを作成することにしました。
このコードを以下に貼り付けます (debug_numWaysXY_iterative.cc)
#include<stdio.h>
#include<iostream>
using namespace std;
void printMap(int X, int Y, int **map)
{
printf("printing map(%d, %d)...\n\n", X, Y);
for(int i = 0; i < Y; i++)
{
for(int j = 0; j < X; j++)
{
printf("(%d, %d) value: %d\t", j, i, map[j][i]);
}
printf("\n");
}
printf("Finished Printing map\n");
}
int numWaysXY_iterative(int X, int Y)
{
int **map = new int*[X];
int value = 0;
for(int i = 0; i < X; i++)
{
map[i] = new int(Y);
for(int j = 0; j < Y; j++)
{
printf("i: %d, j: %d, value: %d\n", i, j, value);
map[i][j] = value;
value++;
}
}
//debugging - print map
printMap(X,Y, map);
//initialize first row and first column entries to 1
for(int i = 0; i < X; i++)
{
map[i][0] = 1;
}
for(int j = 0; j < Y; j++)
{
map[0][j] = 1;
}
//debugging - print map
printMap(X,Y, map);
/*
for(int i = 0; i < X, i++)
{
for(int j = 0; j > Y, j++)
{
if
}
}
*/
return map[X-1][Y-1];
}
int main()
{
(void) numWaysXY_iterative(5,3);
}
これら 2 つのプログラムの唯一の違いは、"long long int" 変数を "int" に置き換えたこと (およびそれに応じて printf 呼び出しを変更したこと) であることを証明するために、2 つのソース ファイルの違いを次に示します。
$ diff my_solution/numWaysXY_iterative/numWaysXY_iterative.cc my_solution/numWaysXY_iterative/debug_numWaysXY_iterative.cc
6c6
< void printMap(int X, int Y, long long int **map)
---
> void printMap(int X, int Y, int **map)
9c9
< for(long long int i = 0; i < Y; i++)
---
> for(int i = 0; i < Y; i++)
11c11
< for(long long int j = 0; j < X; j++)
---
> for(int j = 0; j < X; j++)
13c13
< printf("(%lld, %lld) value: %lld\t", j, i, map[j][i]);
---
> printf("(%d, %d) value: %d\t", j, i, map[j][i]);
20c20
< long long int numWaysXY_iterative(long long int X, long long int Y)
---
> int numWaysXY_iterative(int X, int Y)
22c22
< long long int **map = new long long int*[X];
---
> int **map = new int*[X];
24c24
< long long int value = 0;
---
> int value = 0;
26c26
< for(long long int i = 0; i < X; i++)
---
> for(int i = 0; i < X; i++)
28,29c28,29
< map[i] = new long long int(Y);
< for(long long int j = 0; j < Y; j++)
---
> map[i] = new int(Y);
> for(int j = 0; j < Y; j++)
31c31
< printf("i: %lld, j: %lld, value: %lld\n", i, j, value);
---
> printf("i: %d, j: %d, value: %d\n", i, j, value);
41c41
< for(long long int i = 0; i < X; i++)
---
> for(int i = 0; i < X; i++)
45c45
< for(long long int j = 0; j < Y; j++)
---
> for(int j = 0; j < Y; j++)
$
ただし、このバージョンのコードを実行すると、期待どおりの出力が得られます!!
$ g++ my_solution/numWaysXY_iterative/debug_numWaysXY_iterative.cc -m64 -o executables/debug_numWaysXY_iterative
$
$
$
$ ./executables/debug_numWaysXY_iterative
i: 0, j: 0, value: 0
i: 0, j: 1, value: 1
i: 0, j: 2, value: 2
i: 1, j: 0, value: 3
i: 1, j: 1, value: 4
i: 1, j: 2, value: 5
i: 2, j: 0, value: 6
i: 2, j: 1, value: 7
i: 2, j: 2, value: 8
i: 3, j: 0, value: 9
i: 3, j: 1, value: 10
i: 3, j: 2, value: 11
i: 4, j: 0, value: 12
i: 4, j: 1, value: 13
i: 4, j: 2, value: 14
printing map(5, 3)...
(0, 0) value: 0 (1, 0) value: 3 (2, 0) value: 6 (3, 0) value: 9 (4, 0) value: 12
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10 (4, 1) value: 13
(0, 2) value: 2 (1, 2) value: 5 (2, 2) value: 8 (3, 2) value: 11 (4, 2) value: 14
Finished Printing map
printing map(5, 3)...
(0, 0) value: 1 (1, 0) value: 1 (2, 0) value: 1 (3, 0) value: 1 (4, 0) value: 1
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10 (4, 1) value: 13
(0, 2) value: 1 (1, 2) value: 5 (2, 2) value: 8 (3, 2) value: 11 (4, 2) value: 14
Finished Printing map
$
私が示したように、両方のプログラムを -m64 フラグでコンパイルしました。また、私のラップトップには 64 ビット プロセッサである i7 プロセッサがあります。「long long int」のすべてのインスタンスを「long int」に置き換えたプログラムのバージョンと、すべての「long long int」を「int64_t」に置き換えた別のバージョンも試しましたが、間違った出力が得られますこれらのバージョンの両方についても。
ここで動作に違いが見られる理由を知っている人はいますか?