- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I searched for rounding code but found all (and my own first attempt) suffered from integer overflow when using 12 significant figures. My new code makes use of a variable format internal write. The Fortran runtime appears to have a suitable rounding capability used for the IO but is it exposed to the user via any extension?
[bash]pure doubleprecision function roundNominal(num, n) result(res) doubleprecision, intent(in) :: num integer, intent(in) :: n character*25 temp if (isNaN(num)) then res = num return end if if (num == 0.0) then res = 0.0 return end if write(temp, 10) num read(temp, *) res 10 format(0p, d25.) end function [/bash]
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please elaborate on why you want to do the rounding. Is it only for decimal conversion in conjunction with I/O, or is it to examine the effect of rounding on remaining calculations?
Will truncation do, instead? Will truncation of, say, 12 bits of the signifand do? If so, here is an example. It uses the deprecated EQUIVALENCE statement, but you can rewrite it with TRANSFER.
Will truncation do, instead? Will truncation of, say, 12 bits of the signifand do? If so, here is an example. It uses the deprecated EQUIVALENCE statement, but you can rewrite it with TRANSFER.
[fortran]program chop12x real*8 x,y integer*4 ix(2),iy(2) equivalence (ix,x),(iy,y) x=acos(0d0)*2d0 y=x call chop12(y) write(*,'(1x,F20.16,4x,2Z8)')x,ix(2),ix(1),y,iy(2),iy(1) contains subroutine chop12(x) real*8 x,r8 integer*4 i4(2) equivalence(r8,i4) r8=x i4(1)=iand(i4(1),Z'FFFFF000') x=r8 return end subroutine chop12 end program chop12x [/fortran]The result of running this program:
[bash] 3.1415926535897930 400921FB54442D18 3.1415926535883050 400921FB54442000 [/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider:
[fortran]pure doubleprecision function roundNominal(num, n) result(res) doubleprecision, intent(in) :: num integer, intent(in) :: n character*25 temp if (isNaN(num)) then res = num return end if if (num == 0.0) then res = 0.0 return end if if(n == 0) then res = num end if if(n .gt. 0) then res = DNINT(num*DBLE(n)) / DBLE(n) else res = DNINT(num/DBLE(-n)) * DBLE(-n) endif end function[/fortran]
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thankyou both. DNINT will obviously do what I want. I should have searched a bit more before posting this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also note that temp should be removed, and you should use double precision literals for 0.0 (0.0D0)
Jim Dempsey
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please use the generic ANINT rather than the specific DNINT. In general, I recommend against using specific functions unless you are passing them as actual arguments.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page