- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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 kopiert
5 Antworten
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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]
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Thankyou both. DNINT will obviously do what I want. I should have searched a bit more before posting this.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Also note that temp should be removed, and you should use double precision literals for 0.0 (0.0D0)
Jim Dempsey
Jim Dempsey
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.

Antworten
Themen-Optionen
- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite