The question of the correctness of calculations Compiler

New to FreeBASIC? Post your questions here.
VANYA
Posts: 1411
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

The question of the correctness of calculations Compiler

Postby VANYA » May 01, 2011 9:24

My question is:

So it should be?

Code: Select all

Dim a As integer=(32*32+31)/32*4
Dim b As integer=(32*32)/32*4
? a,b
sleep


132
128


C++ compiler output:

Code: Select all

#include <iostream>
using namespace std;

int main()
 {
cout << (32*32+31)/32*4;
cin.get();
 }


128
128
fxm
Posts: 9993
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » May 01, 2011 9:46

It is as if C++ compiler did this calculation!:
int((32*32+31)/32)*4
Richard
Posts: 3038
Joined: Jan 15, 2007 20:44
Location: Australia

Postby Richard » May 01, 2011 10:29

With integer arithmetic the order of computation is very important. Doing the fp divide by 32 after the multiply by 4 makes a difference. Intermediate results are not necessarily integers. Following the floating point division the result can be rounded or Int()egered.

All these are being precomputed as constants at compile time. This is not necessarily the same as the runtime results.

Code: Select all

Dim a As Integer = (32 * 32 + 31) / 32 * 4
Dim b As Integer = (32 * 32)      / 32 * 4
Print " Integer ", a, b     '   Integer       132           128

Dim x As Double = (32 * 32 + 31) / 32 * 4
Dim y As Double = (32 * 32)      / 32 * 4
Print " Double", x, y       '   Double        131.875       128

a = (32*32 + 31) \ 32 * 4
b = (32*32)      \ 32 * 4
Print "Int divide", a, b    '   Int divide     8             8

a = 4 * (32*32 + 31) \ 32
b = 4 * (32*32)      \ 32
Print "IntDiv order", a, b  '   IntDiv order   131           128

a = (4 * (32*32 + 31)) / 32
b = (4 * (32*32)     ) / 32
Print "changed order", a, b '   changed order  132           128

print int((32*32 + 31) / 32) * 4    ' 128
print    ((32*32 + 31) / 32) * 4    ' 131.875
print    ((32*32 + 31) \ 32) * 4    ' 128

Sleep
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Postby KristopherWindsor » May 01, 2011 10:36

If compile-time results differ from run-time results, IMO that is a bug. But that is not the case here.

We have "/" for floating point division, and "\" for integer division.
Casting floats to ints in FB is done with rounding, but in C and most languages, the floats would be rounded down (truncated).
So that's why it's different.
VANYA
Posts: 1411
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Postby VANYA » May 01, 2011 10:41

Judging by your statements, so it should be. I just thought it was a glitch ...

Thank you.
fxm
Posts: 9993
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » May 01, 2011 11:11

KristopherWindsor wrote:... but in C and most languages, the floats would be rounded down (truncated).
So that's why it's different.

In addition, it should be done that rounding after the division by 32, but before the multiplication by 4, as I suggested, to get 128:
int((32 * 32 + 31) / 32) * 4 = 128
Otherwise if the rounding was done at the end, there should be 31:
int((32 * 32 + 31) / 32 * 4) = 131
marcov
Posts: 3020
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Postby marcov » May 01, 2011 11:38

The C code uses integer division, FB probably changes most of the expression to float, and only converts back to integer at the end.

There is no good or wrong, this kind of stuff depends on the type-promotion rules of the language, and if the language has a special way to signal integer or float division.

Some languages have DIV for integer division and use / only for float. If you specify the float division, you more or less force the compiler to change the expression to float.
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Postby Gonzo » May 02, 2011 15:35

KristopherWindsor wrote:If compile-time results differ from run-time results, IMO that is a bug. But that is not the case here.

We have "/" for floating point division, and "" for integer division.
Casting floats to ints in FB is done with rounding, but in C and most languages, the floats would be rounded down (truncated).
So that's why it's different.


and i really dont understand why its different with fb :(
(sorry, i had to!)

in all seriousness, it's caused me some grief, because i never assumed that the compiler would prefer floats over ints :)
counting_pine
Site Admin
Posts: 6230
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » May 02, 2011 21:42

In BASIC, it's generally given that an operation involving two numbers will give the same (approximate) result, regardless of the actual types of those numbers. For most operators (e.g. +, -, *), it's safe to assume that if you give it two integers you'll get an integer back, but not so with division.

I think BASIC does it better than C, because it lets me choose easily, while preserving intuitive behaviour for '/'. I'd have been very annoyed when I started out in QB if 3/4 returned 0.

Having '/' being type-dependent in QB would either have required things like 3/4 = 0, or for literal integer numbers to have been treated as floating-point internally. And then m% / n% would still catch people by surprise.

Return to “Beginners”

Who is online

Users browsing this forum: Majestic-12 [Bot] and 7 guests