Я вижу очень странное поведение при использовании 64-битных целых чисел в небольшой программе, которую я написал. Моя программа делает следующее …
Вот код для моей программы (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);
}
Просто чтобы доказать, что единственное различие, которое я сделал между этими двумя программами, заключается в замене переменных «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, и у меня на ноутбуке есть процессор i7,
который является 64-битным процессором. Я также пробовал версии моей программы со всеми экземплярами «long long int», замененными на «long int», и другой версией, где я заменил все «long long int» на «int64_t», и я получаю неправильный вывод для обеих этих версий тоже.
У кого-нибудь есть идеи, почему я вижу здесь разницу в поведении?
Задача ещё не решена.