forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Funny overflow?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
Wilfried Linder



Joined: 14 Nov 2007
Posts: 314
Location: Düsseldorf, Germany

PostPosted: Tue Dec 02, 2014 12:55 pm    Post subject: Funny overflow? Reply with quote

I'm not sure about the following: To allocate storage for an image, I need of course the amount of bytes = size of the image. This is calculated via "rows * columns * bits / 8", giving the result in [bytes]. No look at the following example of a really big image, 12000 rows by 12000 columns with 24 bits per pixel:

Code:
      program test
      IMPLICIT NONE

      integer*4      i,j,zei,spa,bit

      zei = 12000
      spa = 12000
      bit = 24

      j = zei*spa*bit/8
      print*,j

      i = bit/8
      j = zei*spa*i
      print*,j
      end


The first "print*j" gives an incorrect value, the second a correct one. I think that "zei*spa*bit" (bevor "/8") gives a value too big for an integer*4 variable - but why there is no error message??

Wilfried
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7923
Location: Salford, UK

PostPosted: Tue Dec 02, 2014 1:17 pm    Post subject: Reply with quote

By default integer overflow is not trapped.
You need /check for example.
Back to top
View user's profile Send private message AIM Address
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Tue Dec 02, 2014 10:57 pm    Post subject: Reply with quote

Just a demonstration of how technology sometimes goes backwards. The computers I used in the 1960s and 1970s were based on 24 bit words, and as in Fortran 66, INTEGER and REAL both took the same number of words (on those machines 2), then you were getting effectively INTEGER*6 and REAL*6. Your expression wouldn't overflow INTEGER*6 (or *8 for that matter). I went on to use various other machines with different word lengths, including a Cray with 60 bit words, and others I can't remember.

Where there is a possibility of integer overflow you always need to take special precautions. Paul's suggestion of /check will check every operation. You wouldn't have hit the problem if you had multiplied by "number of bytes to represent the colour of a pixel" instead of "number of bits per pixel/8" as there are only 1,2,3 and 4 as answers. Maybe using brackets could force that, but in order to get the right answer for 2 bit (monochrome) if you do the divide by 8 explicitly, you need a more sophisticated equation!

Maybe

j = zei*spa*MAX(bit/8,1)

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Tue Dec 02, 2014 11:03 pm    Post subject: Reply with quote

You can't be sure of the order of calculation, so integer overflow should always be checked.

certainly
Code:
      program test
      IMPLICIT NONE

      integer*4      i,j,zei,spa,bit,byte

      zei = 12000
      spa = 12000
      bit = 24
      byte = bit/8

      j = zei*spa*byte
      print*,j

      i = bit/8
      j = zei*spa*i
      print*,j
      end


I am wondering, can it be assumed that 24 bit colour is always stored in 3 bytes or is it sometimes stored in 4 bytes ?

John
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Wed Dec 03, 2014 2:46 pm    Post subject: Reply with quote

John,

Certainly if there is an alpha (transparency) channel it will take that fourth byte, and if the bits per pixel is 8, 16, 24 or 32, then dividing by 8 will give the right answer for bytes per pixel. It doesn't if the image is monochrome.

You could always do the calculation in floating point first, then test the size of the result - the order of the variables wouldn't matter for that - but even if the result fits, and intermediate step has the potential to overflow, which is why the order of the variables is so important.

Eddie
Back to top
View user's profile Send private message
Wilfried Linder



Joined: 14 Nov 2007
Posts: 314
Location: Düsseldorf, Germany

PostPosted: Wed Dec 03, 2014 4:09 pm    Post subject: Reply with quote

I think that Eddie described the solution: Calculating the size via real*8 variables like r = dble(zei)*dble(spa)*dble(bit)/8.D0, then testing whether this value is less then 2147483647 (= maximum size fitting into integer*4), and then using size = nint(r).

This will help to find the size for allocating memory until the image is indeed not bigger. Or ist is possible to use allocate with a real*8 argument? But I think that it will need at least 20 years more to have such big images Wink

Wilfried
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Wed Dec 03, 2014 5:51 pm    Post subject: Reply with quote

Hi Wilfried, I actually meant doing the calculation in REAL first for the test, but to do it in INTEGER afterwards if the test worked, and doing some other workaround if the test didn't work out. I don't know (without thinking about it a lot!) if the precision of DOUBLE PRECISION is good enough to survive the calculation and type conversion, but maybe it is. There's always the problem in the rounding of any division in INTEGER that is very different in real arithmetic.

I'm always worried about the final roundoff when you go from REAL to INTEGER when sometimes you want to round up, sometimes down, and sometimes to nearest.

I've almost never worried about overflow in the middle of an integer calculation before when the final result isn't an overflow.

Eddie
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Thu Dec 04, 2014 7:57 pm    Post subject: Reply with quote

What is wrong with just putting the following if bit is a multiple of 8?

Code:

j = zei*spa*(bit/8)

_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Dec 04, 2014 11:14 pm    Post subject: Reply with quote

Actually, putting a bit more might give you the answer you require.
Code:
      program test
       IMPLICIT NONE

       integer*4      i,j,zei,spa
       real*4         mb,bit

       zei = 12000
       spa = 12000
       bit = 24

       mb = real(zei)*real(spa)*bit/8./1024./1024.
       print*,mb,' mb required'

       i = bit/8
       j = zei*spa*i
       print*,j
       end
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Fri Dec 05, 2014 6:32 pm    Post subject: Reply with quote

David, bit may not be a multiple of 8 (monochrome)

zei and spa in the present context may be 12000, but if they got a lot bigger the problem would recur.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group