From: Steve Lionel on
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
> 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
"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
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
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

 |  Next  |  Last
Pages: 1 2 3 4
Prev: Compatibility of MOD files
Next: TRANSFER on LOGICALs