C++ Calculate wrong answer.

J

Jepsensen

Dear Everybody.

I got a problem with my cpp code.
I'm trying to calculate a very simple Discrete Cosine Transform (DCT),
but my c++ code seams to calculate a wrong result.

I have just started to program c++ (3 month ago), so i'm very lost
with this problem.

I have been making a test i Visual Basic and one Borland C++, but the
results seams to be very different.

I realy hope some of you guys can see some errors i my c++ code.

/Jeppe

PS: Sorry about my english. It's my second language.


***Start of Visual Basic Result***
Buffer_Block (Start)
140 144 147 140 140 155 179 175
144 152 140 147 140 148 167 179
152 155 136 167 163 162 152 172
168 145 156 160 152 155 136 160
162 148 156 148 140 136 147 162
147 167 140 155 155 140 136 162
136 156 123 167 162 144 140 147
148 155 136 155 152 147 147 136

DCT_Block (After the DCT)
1210 -18 15 -9 23 -9 -14 -19
21 -34 26 -9 -11 11 14 7
-10 -24 -2 6 -18 3 -20 -1
-8 -5 14 -15 -8 -3 -3 8
-3 10 8 1 -11 18 18 15
4 -2 -18 8 8 -4 1 -7
9 1 -3 4 -1 -7 -1 -2
0 -8 -2 2 1 4 -6 0

Buffer_Block (After the IDCT)
140 144 147 141 140 155 179 175
144 152 140 147 140 148 167 179
152 155 136 167 163 162 152 172
168 145 156 160 152 154 136 160
162 148 156 148 140 136 147 162
147 167 140 155 155 140 136 162
136 156 123 166 162 144 140 148
148 155 136 155 152 147 147 136
***End of Visual Basic Result***

***Start of C++ Result***
Buffer_Block (Start)
140 148 155 136 155 152 147 14
144 152 140 147 140 148 167 17
152 155 136 167 163 162 152 17
168 145 156 160 152 155 136 16
162 148 156 148 140 136 147 16
147 167 140 155 155 140 136 16
136 156 123 167 162 144 140 14
148 155 136 155 152 147 147 13

DCT_Block (after the DCT)
1204 83 -79 71 -41 36 -46 1
57 -98 89 -72 47 -42 48 -5
-6 -24 0 -2 -6 -12 -11 0
-53 61 -46 34 -46 20 -20 21
3 4 14 -9 1 2 27 14
13 -13 -6 -5 22 -19 10 -8
7 4 -5 3 0 -11 1 -1
83 -79 71 -41 36 -46 1 6

Buffer_Block (After the IDCT)
147 156 160 139 162 158 155 17
147 150 145 157 140 152 163 13
163 171 144 168 178 171 173 4
169 140 161 172 147 158 127 90
175 169 166 150 159 149 170 10
151 165 147 169 153 146 131 17
149 172 134 173 178 156 159 54
156 160 139 162 158 155 171 37
***End of C++ Result***

my c++ codes goes here.

#include <stdio.h>
#include <math.h>

//General variables.
unsigned char buffer_block[7][7];
int dct_block[7][7];

//Function declarements
void disp_buffer_block();
void disp_dct_block();
double c(int number);
void init_buffer_block();

static const double pi = 3.141593;

void main() {
//Initilize buffer block.
init_buffer_block();

disp_buffer_block();

for(int u=0;u<8;u++) {
for(int v=0;v<8;v++) {
double temp = 0.0;

for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
temp += buffer_block[x][y] * cos(pi * (2 * x + 1) * u / 16) *
cos(pi * (2 * y + 1) * v / 16);
}
}

dct_block[v] = temp * (c(u) / 2) * (c(v) / 2);
}
}

disp_dct_block();

for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
double temp = 0.0;

for(int u=0;u<8;u++) {
for(int v=0;v<8;v++) {
temp += (c(u) / 2) * (c(v) / 2) * dct_block[v] * cos(pi * (2 *
x + 1) * u / 16) * cos(pi * (2 * y + 1) * v / 16);
}
}

buffer_block[x][y] = temp;
}
}

disp_buffer_block();
}

void disp_buffer_block() {
for(int i=0;i<8;i++) {
for(int j=0;j<8;j++) {
printf("%d\t",buffer_block[j]);
}
printf("\n");
}
printf("\n\n");
}

void disp_dct_block() {
for(int i=0;i<8;i++) {
for(int j=0;j<8;j++) {
printf("%d\t",dct_block[j]);
}
printf("\n");
}
printf("\n\n");
}

double c(int number) {
if(number == 0) {
return 1 / sqrt(2);
} else {
return 1;
}
}

void init_buffer_block() {
buffer_block[0][0] = 140;
buffer_block[1][0] = 144;
buffer_block[2][0] = 147;
buffer_block[3][0] = 140;
buffer_block[4][0] = 140;
buffer_block[5][0] = 155;
buffer_block[6][0] = 179;
buffer_block[7][0] = 175;
buffer_block[0][1] = 144;
buffer_block[1][1] = 152;
buffer_block[2][1] = 140;
buffer_block[3][1] = 147;
buffer_block[4][1] = 140;
buffer_block[5][1] = 148;
buffer_block[6][1] = 167;
buffer_block[7][1] = 179;
buffer_block[0][2] = 152;
buffer_block[1][2] = 155;
buffer_block[2][2] = 136;
buffer_block[3][2] = 167;
buffer_block[4][2] = 163;
buffer_block[5][2] = 162;
buffer_block[6][2] = 152;
buffer_block[7][2] = 172;
buffer_block[0][3] = 168;
buffer_block[1][3] = 145;
buffer_block[2][3] = 156;
buffer_block[3][3] = 160;
buffer_block[4][3] = 152;
buffer_block[5][3] = 155;
buffer_block[6][3] = 136;
buffer_block[7][3] = 160;
buffer_block[0][4] = 162;
buffer_block[1][4] = 148;
buffer_block[2][4] = 156;
buffer_block[3][4] = 148;
buffer_block[4][4] = 140;
buffer_block[5][4] = 136;
buffer_block[6][4] = 147;
buffer_block[7][4] = 162;
buffer_block[0][5] = 147;
buffer_block[1][5] = 167;
buffer_block[2][5] = 140;
buffer_block[3][5] = 155;
buffer_block[4][5] = 155;
buffer_block[5][5] = 140;
buffer_block[6][5] = 136;
buffer_block[7][5] = 162;
buffer_block[0][6] = 136;
buffer_block[1][6] = 156;
buffer_block[2][6] = 123;
buffer_block[3][6] = 167;
buffer_block[4][6] = 162;
buffer_block[5][6] = 144;
buffer_block[6][6] = 140;
buffer_block[7][6] = 147;
buffer_block[0][7] = 148;
buffer_block[1][7] = 155;
buffer_block[2][7] = 136;
buffer_block[3][7] = 155;
buffer_block[4][7] = 152;
buffer_block[5][7] = 147;
buffer_block[6][7] = 147;
buffer_block[7][7] = 136;
}

my vb codes goes here.

Private Buffer_Block(7, 7) As Byte
Private DCT_Block(7, 7) As Long

Private Const PI = 3.141593

Private Sub Command1_Click()
Dim Temp As Double
Dim U As Integer, V As Integer, X As Integer, Y As Integer

Print_Buffer

For U = 0 To 7
For V = 0 To 7
Temp = 0

For X = 0 To 7
For Y = 0 To 7
Temp = Temp + (Cos(PI * (2 * X + 1) * U / 16) *
Cos(PI * (2 * Y + 1) * V / 16) * Buffer_Block(X, Y))
Next Y
Next X

DCT_Block(U, V) = Temp * (C(U) / 2) * (C(V) / 2)
Next V
Next U

Print_DCT

For X = 0 To 7
For Y = 0 To 7
Temp = 0

For U = 0 To 7
For V = 0 To 7
Temp = Temp + ((C(U) / 2) * (C(V) / 2) * Cos(PI *
(2 * X + 1) * U / 16) * Cos(PI * (2 * Y + 1) * V / 16) * DCT_Block(U,
V))
Next V
Next U

Buffer_Block(X, Y) = Temp
Next Y
Next X

Print_Buffer
End Sub

Private Function C(Num As Integer) As Double
If Num = 0 Then
C = 1 / Sqr(2)
Else
C = 1
End If
End Function

Private Function Print_Buffer()
Dim I As Integer, J As Integer, Output As String

For I = 0 To 7
Output = Buffer_Block(0, I) & vbTab

For J = 1 To 7
Output = Output & Buffer_Block(J, I) & vbTab
Next J

Print #1, Output
Next I

Print #1, vbCrLf
End Function

Private Function Print_DCT()
Dim I As Integer, J As Integer, Output As String

For I = 0 To 7
Output = DCT_Block(0, I) & vbTab

For J = 1 To 7
Output = Output & DCT_Block(J, I) & vbTab
Next J

Print #1, Output
Next I

Print #1, vbCrLf
End Function

Private Sub Form_Load()
Buffer_Block(0, 0) = 140
Buffer_Block(1, 0) = 144
Buffer_Block(2, 0) = 147
Buffer_Block(3, 0) = 140
Buffer_Block(4, 0) = 140
Buffer_Block(5, 0) = 155
Buffer_Block(6, 0) = 179
Buffer_Block(7, 0) = 175
Buffer_Block(0, 1) = 144
Buffer_Block(1, 1) = 152
Buffer_Block(2, 1) = 140
Buffer_Block(3, 1) = 147
Buffer_Block(4, 1) = 140
Buffer_Block(5, 1) = 148
Buffer_Block(6, 1) = 167
Buffer_Block(7, 1) = 179
Buffer_Block(0, 2) = 152
Buffer_Block(1, 2) = 155
Buffer_Block(2, 2) = 136
Buffer_Block(3, 2) = 167
Buffer_Block(4, 2) = 163
Buffer_Block(5, 2) = 162
Buffer_Block(6, 2) = 152
Buffer_Block(7, 2) = 172
Buffer_Block(0, 3) = 168
Buffer_Block(1, 3) = 145
Buffer_Block(2, 3) = 156
Buffer_Block(3, 3) = 160
Buffer_Block(4, 3) = 152
Buffer_Block(5, 3) = 155
Buffer_Block(6, 3) = 136
Buffer_Block(7, 3) = 160
Buffer_Block(0, 4) = 162
Buffer_Block(1, 4) = 148
Buffer_Block(2, 4) = 156
Buffer_Block(3, 4) = 148
Buffer_Block(4, 4) = 140
Buffer_Block(5, 4) = 136
Buffer_Block(6, 4) = 147
Buffer_Block(7, 4) = 162
Buffer_Block(0, 5) = 147
Buffer_Block(1, 5) = 167
Buffer_Block(2, 5) = 140
Buffer_Block(3, 5) = 155
Buffer_Block(4, 5) = 155
Buffer_Block(5, 5) = 140
Buffer_Block(6, 5) = 136
Buffer_Block(7, 5) = 162
Buffer_Block(0, 6) = 136
Buffer_Block(1, 6) = 156
Buffer_Block(2, 6) = 123
Buffer_Block(3, 6) = 167
Buffer_Block(4, 6) = 162
Buffer_Block(5, 6) = 144
Buffer_Block(6, 6) = 140
Buffer_Block(7, 6) = 147
Buffer_Block(0, 7) = 148
Buffer_Block(1, 7) = 155
Buffer_Block(2, 7) = 136
Buffer_Block(3, 7) = 155
Buffer_Block(4, 7) = 152
Buffer_Block(5, 7) = 147
Buffer_Block(6, 7) = 147
Buffer_Block(7, 7) = 136

Open "C:\TestOut.txt" For Output As #1
End Sub

Private Sub Form_Unload(Cancel As Integer)
Close #1
End Sub
 
V

Victor Bazarov

Jepsensen said:
Dear Everybody.

I got a problem with my cpp code.
[...]
my c++ codes goes here.

#include <stdio.h>
#include <math.h>

//General variables.
unsigned char buffer_block[7][7];
int dct_block[7][7];

If you need your C++ arrays to contain 8x8 matrices, you need to
declare them that, [8][8], not [7][7]. In C++ array declarations
contain the number of elements, not the highest index.
 
D

Derek

Using GCC 3.2 your C++ program produces nearly-correct output. There
still appears to be a precision issue (input differs from output by
+/- 1 in many cases), but I'm not seeing the total failure you posted
in your original message.

140 148 155 136 155 152 147 147
144 152 140 147 140 148 167 179
152 155 136 167 163 162 152 172
168 145 156 160 152 155 136 160
162 148 156 148 140 136 147 162
147 167 140 155 155 140 136 162
136 156 123 167 162 144 140 147
148 155 136 155 152 147 147 136

1204 -7 6 -6 24 -15 -11 -16
13 -19 14 -5 -9 2 17 10
-16 -9 -13 9 -17 -4 -16 2
-13 7 4 -11 -7 -9 0 11
-8 20 0 4 -10 11 21 17
0 6 -24 10 8 -8 3 -5
6 6 -7 5 0 -10 0 0
-7 6 -6 24 -15 -11 -16 0

140 149 154 134 155 152 146 145
143 146 142 151 139 145 166 183
151 161 131 159 164 164 151 162
167 136 160 166 149 150 136 170
161 156 150 140 142 140 146 151
147 158 144 161 153 136 137 170
135 160 121 162 162 146 140 140
149 154 134 155 152 146 145 138
 
D

Derek

Using GCC 3.2 your C++ program produces nearly-correct output. There
still appears to be a precision issue (input differs from output by
+/- 1 in many cases), but I'm not seeing the total failure you posted
in your original message.

Sorry, I posted the wrong output. I meant to post the run with
Victor's change, which I noticed and made as well:

140 144 147 140 140 155 179 175
144 152 140 147 140 148 167 179
152 155 136 167 163 162 152 172
168 145 156 160 152 155 136 160
162 148 156 148 140 136 147 162
147 167 140 155 155 140 136 162
136 156 123 167 162 144 140 147
148 155 136 155 152 147 147 136


1209 -17 14 -8 23 -9 -13 -18
20 -34 26 -9 -10 10 13 6
-10 -23 -1 6 -18 3 -20 0
-8 -5 14 -14 -8 -2 -3 8
-3 9 7 1 -10 17 18 15
3 -2 -18 8 8 -3 0 -6
8 0 -2 3 -1 -7 -1 -1
0 -7 -2 1 1 4 -6 0


140 143 146 139 140 154 178 174
144 152 139 147 140 149 166 178
151 154 136 166 162 161 151 171
167 144 155 160 152 154 135 159
161 147 155 148 140 137 145 161
147 165 140 154 154 140 136 161
136 155 124 166 161 143 140 145
148 154 137 154 152 147 146 136
 
B

Bill Stockwell

Dear Everybody.

I got a problem with my cpp code.
I'm trying to calculate a very simple Discrete Cosine Transform (DCT),
but my c++ code seams to calculate a wrong result.
(snipped for brevity)

Your main problem is that in C++, when you divide an integer by an integer,
it give an int result (so u / 16 == 0 if u < 16) whereas VB will map this
result to floating point. Use a floating point value or just do the divide
as u / 16.0 to force this to floating point in C++.

I think another poster mentioned the fact that C++ arrays start their
indexing at 0 instead of 1; consider this also.

-- Dr. Bill Stockwell
Computer Science Department
University of Central Oklahoma
 
R

Ron Natalie

Bill Stockwell said:
Your main problem is that in C++, when you divide an integer by an integer,
it give an int result (so u / 16 == 0 if u < 16)

That's true, but the multiplicative operators associate left to right, and since his left
most operand is of type double (as are some of the intervening operands) the u,
and the 16 both get promoted to double (regardless of the order the compiler actually
computes them).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,883
Members
47,414
Latest member
djangoframe

Latest Threads

Top