|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Tue Dec 02, 2014 12:55 pm Post subject: Funny overflow? |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Dec 02, 2014 1:17 pm Post subject: |
|
|
By default integer overflow is not trapped.
You need /check for example. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Dec 02, 2014 10:57 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Dec 02, 2014 11:03 pm Post subject: |
|
|
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 |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Dec 03, 2014 2:46 pm Post subject: |
|
|
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 |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Wed Dec 03, 2014 4:09 pm Post subject: |
|
|
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
Wilfried |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Dec 03, 2014 5:51 pm Post subject: |
|
|
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 |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Dec 04, 2014 7:57 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Dec 04, 2014 11:14 pm Post subject: |
|
|
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 |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Fri Dec 05, 2014 6:32 pm Post subject: |
|
|
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 |
|
|
|
|
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
|