|
Prev: Compatibility of MOD files
Next: TRANSFER on LOGICALs
From: Steve Lionel on 22 Jan 2008 10:37 On Jan 22, 8:24 am, "FX" <coud...(a)alussinan.org> wrote: > Most compilers should do what you describe (ie lossless I/O) when you use > the default format: > > write (unit,*) my_real > > even though I'm not too sure this is actually required by the Standard. It's not required and you can't rely on this. I'd be astonished if it was actually the case in any implementation. If I recall from IEEE 754, one needs at least three additional decimal digits past the stated precision to guarantee lossless conversion to and from decimal. I may be misremembering the details. List-directed output may give you one digit extra, if that - the number of digits is implementation-dependent. I think you'd be safe to write out the values in an E format with three or four more digits in the fraction past what the datatype provides. For example, E17.10E2 for single-precision and E27.19E3 for double precision. This assumes of course that the implementation converts such values precisely. Steve
From: FX on 22 Jan 2008 11:06 > It's not required and you can't rely on this. I'd be astonished if it > was actually the case in any implementation. Well, it is the case for gfortran and g95, at least. (For gfortran, some system C libraries have trouble correctly dealing with denormals, but apart from that, it is working fine.) I am a bit sad if other implementations don't take care of that; I think the default format should be one of lossless transmission of information. In gfortran, the default formats are fixed-width and correspond to: - 1PG15.8E2 for REAL(4) - 1PG25.17E3 for REAL(8) - 1PG29.20E4 for REAL(10) - 1PG44.35E4 for REAL(16) I think they're safe. -- FX
From: James Van Buskirk on 22 Jan 2008 11:09 "Steve Lionel" <steve.lionel(a)intel.com> wrote in message news:f8e3dc49-5c10-4249-bad6-2d359abd856d(a)v4g2000hsf.googlegroups.com... > On Jan 22, 8:24 am, "FX" <coud...(a)alussinan.org> wrote: >> Most compilers should do what you describe (ie lossless I/O) when you use >> the default format: >> write (unit,*) my_real >> even though I'm not too sure this is actually required by the Standard. > It's not required and you can't rely on this. I'd be astonished if it > was actually the case in any implementation. When I require exactly reproducible results as I do for every post :) I write out more digits than I need and start deleting, reading them back in to see where a discrepancy arises. That works provided the same processor is going to read it next time, but it seems to me that a different processor may use a slightly different algorithm to read so I also check adjacent possible outputs to attempt to detect borderline cases and include an extra digit if so. Works great by hand, but I haven't automated it. P.S. Steve, I looked at your forum today: C:\gfortran\clf\change_rank>type change_rank.f90 program change_rank use ISO_C_BINDING implicit none real, target :: x3(3,4) real, pointer :: x1(:) integer, pointer :: i1(:) type(C_PTR) intermediate character(80) fmt x3 = reshape([ 1.0, 1.1, 1.2, 1.3, & 2.0, 2.1, 2.2, 2.3, & 3.0, 3.1, 5.7, 3.3], & shape(x3), order = [2,1]) intermediate = C_LOC(x3) write(fmt,'(a,i0,a)') '(',size(x3,2),'(f3.1:1x))' write(*,'(a)') 'Original matrix =' write(*,fmt) transpose(x3) call C_F_POINTER(intermediate, x1, [size(x3)]) write(fmt,'(a,i0,a)') '(',size(x1,1),'(f3.1:1x))' write(*,'(/a)') 'Rank-1 matrix =' write(*,fmt) x1 call C_F_POINTER(intermediate, i1, [size(x3)]) write(fmt,'(a,i0,a)') '(',size(i1,1)/2,'(z8.8:1x))' write(*,'(/a)') 'Bits of matrix =' write(*,fmt) i1 end program change_rank C:\gfortran\clf\change_rank>C:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran cha nge_rank.f90 -ochange_rank C:\gfortran\clf\change_rank>change_rank Original matrix = 1.0 1.1 1.2 1.3 2.0 2.1 2.2 2.3 3.0 3.1 5.7 3.3 Rank-1 matrix = 1.0 2.0 3.0 1.1 2.1 3.1 1.2 2.2 5.7 1.3 2.3 3.3 Bits of matrix = 3F800000 40000000 40400000 3F8CCCCD 40066666 40466666 3F99999A 400CCCCD 40B66666 3FA66666 40133333 40533333 -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: glen herrmannsfeldt on 22 Jan 2008 13:18 Steve Lionel wrote: > On Jan 22, 8:24 am, "FX" <coud...(a)alussinan.org> wrote: >>Most compilers should do what you describe (ie lossless I/O) >> when you use the default format: >> write (unit,*) my_real >>even though I'm not too sure this is actually required by the Standard. > It's not required and you can't rely on this. I'd be astonished if it > was actually the case in any implementation. Java requires it, and I hate it. Well, it wouldn't be so bad if they provided a convenient alternative. It is nice to have simple values come out with a simple representation, especially for quick testing. It might make some sense for NAMELIST output, which is rarely used otherwise. -- glen
From: glen herrmannsfeldt on 22 Jan 2008 13:29
Gus Gassmann wrote: > Having all sorts of problems in C/C++ with the conversion in the > subject line, I thought to try my luck in the Fortran forum. > The situation is this: I have a (large number of) floating point > number(s), let's assume in double precision --- this might be subject > to change --- that I have to write to a file in ASCII format (an XML > file, if that makes a difference) and subsequently read back in (into > the same type of real that I used before; I'll make sure of this > somehow). Traditionally when you wanted to write out data and read in the exact same data you used UNFORMATTED I/O. For many years of Fortran there were many different floating point representations that it didn't make sense to ask for same value back again on a different system. Over the years, the default REAL has varied from 36 bits, to 32, to 60, to 64, on different systems. (Probably some others in there, too.) > Are there any tools available in Fortran that will allow me to do the > conversion from REAL (assume binary) to string (assume decimal) and > back to REAL _without_loss_of_precision_? (That is, I must be > guaranteed that the two versions of the real number have the same > internal representation. Side condition: I'd like to use the smallest > string representation that will give this guarantee. You could do it in a loop, using internal I/O, write out the value with different format widths in E format, and do binary search to find the appropriate width. That may only guarantee it using the same library, though. If I were doing this, I might try for a base 16 system. -- glen |