From: steve on
On May 21, 11:56 pm, Uno <merrilljen...(a)q.com> wrote:
> On 5/21/2010 5:44 AM, Tobias Burnus wrote:
>
> > Tobias
>
> > (* For the moment I assume that kind number = variable size in bytes,
> > which is a common choice but by far not universal. Use
> > selected_real_kind, precision, and kind to choose the type/kind-number
> > you want [assuming it exists].)
>
> > PS: If I want to use double precision or - if present - the next higher
> > precsion, I use:
> >    integer, parameter :: qp =&
> >      max(kind(0.0d0), selected_real_kind(precision(0.0d0)+1))
>
> I missed this.
>
> E:\gcc_eq32>out
>             4           8          10
>     3.1415927       3.1415927410125732        3.1415927410125732422
>
> E:\gcc_eq32>type tobias1.f90
> implicit none
>
> integer, parameter :: sp = selected_real_kind(1,3)
> integer, parameter :: dp = selected_real_kind(15,300)
> integer, parameter :: qp = &
>      max(kind(0.0d0), selected_real_kind(precision(0.0d0)+1))

The calculation you do above for qp is not portable. As
pointed out by James, there is no ordering guarantee in
the Standard. It so happens the for gfortran the kinds
are ordered as 4, 8, 10 or 4, 8, 16 depending on the underlying
hardware.

> real (kind=sp) w
> real (kind=dp) y
> real (kind=qp) z
>
> w = 4.0_sp*atan(1.0)
> y = 4.0_dp*atan(1.0)
> z = 4.0_qp*atan(1.0)
>
> print *, sp,dp,qp
> print *, w,y,z
> endprogram
>
> ! gfortran  -Wall -Wextra tobias1.f90  -o out.exe
>
> E:\gcc_eq32>
>
> Looks like I got 3 sig figs for having asked for qp.

This isn't necessary true, but you can test for this with
numerical inquiry functions.

program askfp
!
! Using the kind values for gfortran on FreeBSD ia32
! and x86_64.
!
real(4) s
real(8) d
real(10) e
character(len=40) fmt
fmt = '(A,I6,1X,I6,1X,I6)'
write(*,fmt) ' precision: ', &
& precision(s), precision(d), precision(e)
write(*,fmt) ' digits: ', &
& digits(s), digits(d), digits(e)
write(*,fmt) 'minexponent: ', &
& minexponent(s), minexponent(d), minexponent(e)
write(*,fmt) 'maxexponent: ', &
& maxexponent(s), maxexponent(d), maxexponent(e)
write(*,fmt) ' range: ', &
& range(s), range(d), range(e)
end program askfp

On i686-*-freebsd,
laptop:kargl[221] gfc4x -o z askfp.f90
laptop:kargl[222] ./z
precision: 6 15 15
digits: 24 53 53
minexponent: -125 -1021 -16381
maxexponent: 128 1024 16384
range: 37 307 4931

On x86_64-*-freebsd,

troutmask:sgk[201] gfc4x -o z askfp.f90
troutmask:sgk[202] ./z
precision: 6 15 18
digits: 24 53 64
minexponent: -125 -1021 -16381
maxexponent: 128 1024 16384
range: 37 307 4931

--
steve
From: Ron Shepard on
In article <85pa05FjlU1(a)mid.individual.net>,
Uno <merrilljensen(a)q.com> wrote:

> w = 4.0_sp*atan(1.0)
> y = 4.0_dp*atan(1.0)
> z = 4.0_qp*atan(1.0)
>
> print *, sp,dp,qp
> print *, w,y,z
> endprogram
>
>
> ! gfortran -Wall -Wextra tobias1.f90 -o out.exe
>
> E:\gcc_eq32>
>
> Looks like I got 3 sig figs for having asked for qp.

I don't think you are computing what you think you are computing.
You are still taking a default real value of PI/4 and then
multiplying it by 4.0 (in various precisions). I think what you
want is something like

w = 4.0_sp*atan(1.0_sp)
y = 4.0_dp*atan(1.0_dp)
z = 4.0_qp*atan(1.0_qp)

You can tell how accurate things should be with the precision() or
the epsilon() intrinsic functions. The 10-byte values should have
about 5 more significant digits than the 8-byte values.

$.02 -Ron Shepard
From: Uno on
steve wrote:


> The calculation you do above for qp is not portable. As
> pointed out by James, there is no ordering guarantee in
> the Standard. It so happens the for gfortran the kinds
> are ordered as 4, 8, 10 or 4, 8, 16 depending on the underlying
> hardware.

But every implementation we talk about around here associates a greater
integer with increased width in the representation, right?

It seems like low-hanging fruit for a good idea to make standard next
time around.
> On i686-*-freebsd,
> laptop:kargl[221] gfc4x -o z askfp.f90
> laptop:kargl[222] ./z
> precision: 6 15 15
> digits: 24 53 53
> minexponent: -125 -1021 -16381
> maxexponent: 128 1024 16384
> range: 37 307 4931
>
> On x86_64-*-freebsd,
>
> troutmask:sgk[201] gfc4x -o z askfp.f90
> troutmask:sgk[202] ./z
> precision: 6 15 18
> digits: 24 53 64
> minexponent: -125 -1021 -16381
> maxexponent: 128 1024 16384
> range: 37 307 4931

$ pwd
/home/dan/source
$ gfortran -Wall -Wextra s1.f90 -o out
$ ./out
precision: 6 15 18
digits: 24 53 64
minexponent: -125 -1021 -16381
maxexponent: 128 1024 16384
range: 37 307 4931
$ type s1.f90
bash: type: s1.f90: not found
$ cat s1.f90
program askfp
!
! Using the kind values for gfortran on FreeBSD ia32
! and x86_64.
!
real(4) s
real(8) d
real(10) e
character(len=40) fmt
fmt = '(A,I6,1X,I6,1X,I6)'
write(*,fmt) ' precision: ', &
& precision(s), precision(d), precision(e)
write(*,fmt) ' digits: ', &
& digits(s), digits(d), digits(e)
write(*,fmt) 'minexponent: ', &
& minexponent(s), minexponent(d), minexponent(e)
write(*,fmt) 'maxexponent: ', &
& maxexponent(s), maxexponent(d), maxexponent(e)
write(*,fmt) ' range: ', &
& range(s), range(d), range(e)
end program askfp

! gfortran -Wall -Wextra s1.f90 -o out
$


It matches steve's x86_84, which I would expect given that this is an
x86_84.
--
Uno
From: Uno on
Ron Shepard wrote:
> In article <85pa05FjlU1(a)mid.individual.net>,
> Uno <merrilljensen(a)q.com> wrote:

>> Looks like I got 3 sig figs for having asked for qp.
>
> I don't think you are computing what you think you are computing.
> You are still taking a default real value of PI/4 and then
> multiplying it by 4.0 (in various precisions). I think what you
> want is something like
>
> w = 4.0_sp*atan(1.0_sp)
> y = 4.0_dp*atan(1.0_dp)
> z = 4.0_qp*atan(1.0_qp)
>
> You can tell how accurate things should be with the precision() or
> the epsilon() intrinsic functions. The 10-byte values should have
> about 5 more significant digits than the 8-byte values.

Oh, nuts.

$ pwd
/media/disk/gcc_eq32/source
$ gfortran -Wall -Wextra tobias1.f90 -o out.exe
gfortran: tobias1.f90: No such file or directory
$ ls
$ cd ..
$ ls
bin gcc-4.6-20100501-32.exe include out share tobias1.f90
dir gfortran lib out.exe Shortcut.bat tobias1.f90~
echo i686-pc-mingw32 libexec run1.bat source type
$ clear
$ pwd
/media/disk/gcc_eq32
$ ls
bin gcc-4.6-20100501-32.exe include out share tobias1.f90
dir gfortran lib out.exe Shortcut.bat tobias1.f90~
echo i686-pc-mingw32 libexec run1.bat source type
$ gfortran -Wall -Wextra tobias1.f90 -o out.exe
$ ./out
$ ./out.exe
4 8 10
3.1415927 3.1415926535897931 3.1415926535897932385
$ cat tobias1.f90
implicit none

integer, parameter :: sp = selected_real_kind(1,3)
integer, parameter :: dp = selected_real_kind(15,300)
integer, parameter :: qp = &
max(kind(0.0d0), selected_real_kind(precision(0.0d0)+1))




real (kind=sp) w
real (kind=dp) y
real (kind=qp) z

w = 4.0_sp*atan(1.0_sp)
y = 4.0_dp*atan(1.0_dp)
z = 4.0_qp*atan(1.0_qp)

print *, sp,dp,qp
print *, w,y,z
endprogram


! gfortran -Wall -Wextra tobias1.f90 -o out.exe
$

4 sig figs better. Thx, Ron
--
Uno
From: glen herrmannsfeldt on
Uno <merrilljensen(a)q.com> wrote:
(snip)

> Alright, let me see if I understand. We have at least three different
> categories to think of:

> 1) Pointer size
> 2) size of floating point entities
> 3) register width
> 4) Presumably other things that I won't understand.

1) Virtual address size (might be pointer size)
2) Real address size
3) General register size
4) Data bus size

My choice is to take the geometric mean of the four, but
most people don't like that method.

Floating point size is not usually considered.

> I'm not sure what you mean with your second paragraph, but is it that

> A) PowerPc
> B) Itanium (ia64)
> C) SPARC64/PA-SPARC, from s960, from MIPS
> D) x86-64 (= AMD64, Intel64, em64t, ...)

> have differing values for 1-4?

For compatability reasons, the archetectures that existed
in the 32 bit days will usually run 32 bit code in 32 bit mode.

You can install 32 bit Windows 7 on x86-64, or the 64 bit version.

Itanium has either hardware, or hardware assisted software
support for IA32 user code. (I believe that original IA64 had
hardware support, and would run IA32 systems. Itanium2 supports
user code in IA32 mode, but won't run an IA32 OS.)

Currently the usual distinction is virtual address size.
Many compilers supply a 64 bit integer type, and all appropriate
operations, even on 32 bit hardware. (It isn't that hard to
do except for divide, and divide can be done by subroutine call.)

Hardware support for 128 bit floating point goes back to
at least the IBM 360/85 in 1968. S/360 is usually considered
a 32 bit architecture, though it has a 24 bit addressing space,
and was implemented on hardware with a data bus size from 8 bits
(360/30) to 64 bits (high end 360's).

VAX has H-float as part of the intruction set, but was done
by software emulation on most systems. (The 11/730, bottom
of the line VAX, have microcode support standard. Sime others,
I believe have optional microcode support.)

The PPC books I have only list 32 and 64 bit (single and double)
floating point instructions, some of which are emulated in
software on some processors.

SPARCv9 includes a 128 bit floating point type. As said in
"The SPARC Architecture Mavual Verion 9":

"SPARC-V9's support ofr a 128-bit quad floating point format
is unique for microprocessors."

However, later on it indicates that instructions can either
be implemented in hardware, microcode, or software emulation.

I don't know specifically which, if any, SPARCv9 implementations
have hardware support for 128 bit floating point.

-- glen