CShort Question

General FreeBASIC programming questions.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

CShort Question

Post by schooner »

Why do these produce different numbers for the 32-bit gas? Shouldn't the rounding be the same for all variations?

Code: Select all

dim as integer x = 5
print cshort(3.1 * x - 79)
print cshort(3.1 * 5 - 79) 

-63
-64
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: CShort Question

Post by coderJeff »

Different things are happening at run time and compile time:

Code: Select all

'' run-time - 80 bits of precision on FPU stack
dim as integer x = 5
print cshort(3.1 * x - 79)     '' -63

'' compile-time constant folding - 64 bits of precision using DOUBLE type
print cshort(3.1 * 5 - 79)     '' -64

'' run-time, but emulate what compiler does with constant folding
dim as integer y = 5
dim as double t = 3.1 * y
print cshort(t - 79)               ''-64
The first part of the calculation 3.1 * 5 is VERY close to 15.5 but slightly higher in 80 bit precision compared to 64 bit.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: CShort Question

Post by lizard »

schooner wrote:Why do these produce different numbers for the 32-bit gas? Shouldn't the rounding be the same for all variations?

Code: Select all

dim as integer x = 5
print cshort(3.1 * x - 79)
print cshort(3.1 * 5 - 79) 

-63
-64
In case you need a workaround you maybe could use something like this, dear Schooner. It first multiplies with 10 and then divides with 10:

Code: Select all

dim as integer x = 5
print cshort(3.1 * x - 79)
print cshort(3.1 * 5 - 79)

sleep
print

print cshort((31 * x)/10 - 79)
print cshort((31 * 5)/10 - 79)

sleep

-63
-64

-64
-64
Although i am not sure if this is what you need.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: CShort Question

Post by schooner »

coderJeff wrote:Different things are happening at run time and compile time:

Code: Select all

'' run-time - 80 bits of precision on FPU stack
dim as integer x = 5
print cshort(3.1 * x - 79)     '' -63

'' compile-time constant folding - 64 bits of precision using DOUBLE type
print cshort(3.1 * 5 - 79)     '' -64

'' run-time, but emulate what compiler does with constant folding
dim as integer y = 5
dim as double t = 3.1 * y
print cshort(t - 79)               ''-64
The first part of the calculation 3.1 * 5 is VERY close to 15.5 but slightly higher in 80 bit precision compared to 64 bit.
Thank you coderJeff.
The 64-bit gcc always produces -64 so I suppose that is the correct answer. This becomes a nightmare to debug when trying to compare cross-compiles between 32 and 64 bit assemblies.
This is not a difficult problem with precision. It is possible this is a FreeBasic bug, although there are undoubtedly difficulties when trying to code the internal rounding.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: CShort Question

Post by schooner »

lizard wrote:In case you need a workaround you maybe could use something like this, dear Schooner. It first multiplies with 10 and then divides with 10:

Code: Select all

dim as integer x = 5
print cshort(3.1 * x - 79)
print cshort(3.1 * 5 - 79)

sleep
print

print cshort((31 * x)/10 - 79)
print cshort((31 * 5)/10 - 79)

sleep

-63
-64

-64
-64
Although i am not sure if this is what you need.
Thank you lizard. This also works:

Code: Select all

dim as integer x = 5
print cshort(( (3.1 * 10) * x)/10 - 79)
print cshort(( (3.1 * 10) * 5)/10 - 79) 
Fortunately I only need this for some pre-defined tables, otherwise this type of multiplication could genius a performance in a loop.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: CShort Question

Post by paul doe »

Simply convert the expression to single, and then cast it to short:

Code: Select all

dim as integer x = 5

? cast( short, csng( 3.1 * x - 79 ) )
? cast( short, csng( 3.1 * 5 - 79 ) ) 

sleep()

Output:
-64
-64
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: CShort Question

Post by coderJeff »

Just to put the orders of magnitude in perspective of correctness and rounding:
-63.500000000000
-63.4999999999998
Difference of 0.0000000000002.

This is like taking a point on on the earth's equator and rounding the location to nearest north pole or south pole where 1 micrometer makes the difference of which pole you go to.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: CShort Question

Post by paul doe »

schooner wrote:The 64-bit gcc always produces -64 so I suppose that is the correct answer. This becomes a nightmare to debug when trying to compare cross-compiles between 32 and 64 bit assemblies.
This needs not be. You can use GCC to spit a 32-bit executable:

fbc -gen gcc -Wc -m32

There. The executable will be 32-bit, compiled by GCC. They should be equivalent. Just be careful, for if you use any library, it needs to be 32-bit too.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: CShort Question

Post by lizard »

This reminds me of a friend i once had. He was very proud to show me the first invoice of a shop he just started. It was a simple one, only one article, taxes and sum. I looked at it for short time and pointed him at two mistakes: "Here is a cent to much and here one less."

He was shocked. He had completely trusted excel and couldn't believe excel would do wrong in such a simple calculation.

Never trust a computer when it comes to money and floatingpoint calculations. :-)

Solution would be to convert everything to cents, then 1 Euro is 100 cents and do all calculations with integers.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: CShort Question

Post by schooner »

paul doe wrote:Simply convert the expression to single, and then cast it to short:

Code: Select all

dim as integer x = 5

? cast( short, csng( 3.1 * x - 79 ) )
? cast( short, csng( 3.1 * 5 - 79 ) ) 

sleep()

Output:
-64
-64
Does not work on my configuration.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: CShort Question

Post by paul doe »

schooner wrote:Does not work on my configuration.
Which one is that? I get those results in 32-bit GAS, 32-bit GCC and 64-bit GCC. Tested on FreeBasic compiler version 1.05.0.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: CShort Question

Post by schooner »

paul doe wrote:
schooner wrote:Does not work on my configuration.
Which one is that? I get those results in 32-bit GAS, 32-bit GCC and 64-bit GCC. Tested on FreeBasic compiler version 1.05.0.
Hello paul doe.

It does not matter for this topic. There is a work-around from lizard. There is no need to change the FBC configuration unless something else goes wrong. However, it is surprising your results do not duplicate the others.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: CShort Question

Post by paul doe »

schooner wrote: Hello paul doe.

It does not matter for this topic. There is a work-around from lizard. There is no need to change the FBC configuration unless something else goes wrong. However, it is surprising your results do not duplicate the others.
I thought that the topic was about you getting different rounding results in 32-bit GAS vs 64-bit GCC?
schooner wrote:Why do these produce different numbers for the 32-bit gas? Shouldn't the rounding be the same for all variations?
schooner wrote:The 64-bit gcc always produces -64 so I suppose that is the correct answer. This becomes a nightmare to debug when trying to compare cross-compiles between 32 and 64 bit assemblies.
But whatever, suit yourself.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: CShort Question

Post by lizard »

lizard wrote:Never trust a computer when it comes to money and floatingpoint calculations. :-)
Another story i once heard: There was a programmer of a bank who had similar problems. Sometimes there was a cent to much in transactions. He found a simple solution. Whenever this happened he transfered this cent to his own account. It became a pretty high sum after some time. Until they found out and then he had opportunity in prison to think about what to program next ...
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: CShort Question

Post by grindstone »

Yes, and it ony came out because he let that snippet run while he went to holidays. So his holiday recover noticed and reported it...
Post Reply