From: frank on
There's been an elsethread discussion of a skewing of floating point
values around .5. I've been dinking with this since last night and
wonder what it is that this program shows:

implicit none

INTEGER, PARAMETER :: SP=SELECTED_REAL_KIND(6,37)
INTEGER, PARAMETER :: DP=SELECTED_REAL_KIND(15,307)

REAL(KIND=SP) :: begin, B, C
REAL(KIND=DP) :: V, accum, summa, eps_fourth

integer, parameter :: r = 1000

real(KIND=SP), dimension(1:r) :: myarray
integer, dimension(1:r) :: ticks
integer i, mult


! main control
v = epsilon(begin)
print *, "epsilon is ", v
eps_fourth = v/ 10.0_dp

begin = .49999_sp
myarray(1) = begin
ticks(1) = 45



do i =2,r
! inner control
mult = 0
accum = 0.0_dp
b = myarray ( i - 1)
c = myarray ( i - 1)
summa =0.0_dp
do while ( b == c )
accum = mult * eps_fourth
summa = accum + real(b, kind=dp)
c = real(summa, kind=sp)
mult = mult + 1
end do
myarray(i) = c
ticks(i) = mult

end do

do i = 1, r
print *, "i= ", i, myarray(i), "mult is ", ticks(i)

end do

end program



! gfortran real3.f90 -Wall -o out
! ./out >text1.txt

Abridged output:
i= 331 0.49999982 mult is 3
i= 332 0.49999985 mult is 3
i= 333 0.49999988 mult is 3
i= 334 0.49999991 mult is 3
i= 335 0.49999994 mult is 3
i= 336 0.49999997 mult is 3
i= 337 0.50000000 mult is 3
i= 338 0.50000006 mult is 4
i= 339 0.50000012 mult is 4
i= 340 0.50000018 mult is 4
i= 341 0.50000024 mult is 4
i= 342 0.50000030 mult is 4
i= 343 0.50000036 mult is 4

This is suggestive of an asymmetry that Ron Shephard and steve mentioned.

I'm curious that these values seem to be spaced at epsilon over something
in the range of [2.5-3.33).

I was elected to church council today (They must need warm bodies).
Since I became an ecclesiastical authority, and I've been wrestling with
what title I would be known by. I always like Mencken's quip about the
Archbishop: A Christian ecclesiastic of a rank superior to that attained
by Christ. I've decided to become

Your Frankness,
--
frank

"Guns: yes, they are harmful."
From: steve on
>
> This is suggestive of an asymmetry that Ron Shephard and steve mentioned.
>
> I'm curious that these values seem to be spaced at epsilon over something
> in the range of [2.5-3.33).
>

program hj
integer(8) i
real x
x = 0
i = 0
! Count number of floats in [0,0.5)
do
i = i + 1
x = nearest(x, 1.)
if (x >= 0.5) exit
end do
print '(A,I0)', '[0,0.5) = ', i
x = 0.5
i = 0
! count number of floats in [0.5,1)
do
i = i + 1
x = nearest(x, 1.)
if (x >= 1.) exit
end do
print '(A,I0)', '[0.5,1) = ', i

x = 0.5
do i = 1, 10
x = nearest(x, -1.)
end do
do i = 1, 20
print *, x, spacing(x)
x = nearest(x, 1.)
end do

end program hj

REMOVE:kargl[209] gfc4x -o z -O hj.f90
REMOVE:kargl[210] ./z
[0,0.5) = 1056964608
[0.5,1) = 8388608
0.49999970 2.98023224E-08
0.49999973 2.98023224E-08
0.49999976 2.98023224E-08
0.49999979 2.98023224E-08
0.49999982 2.98023224E-08
0.49999985 2.98023224E-08
0.49999988 2.98023224E-08
0.49999991 2.98023224E-08
0.49999994 2.98023224E-08
0.49999997 2.98023224E-08
0.50000000 5.96046448E-08
0.50000006 5.96046448E-08
0.50000012 5.96046448E-08
0.50000018 5.96046448E-08
0.50000024 5.96046448E-08
0.50000030 5.96046448E-08
0.50000036 5.96046448E-08
0.50000042 5.96046448E-08
0.50000048 5.96046448E-08
0.50000054 5.96046448E-08

Note, the above counting does not include subnormal numbers.

--
steve
From: frank on
On Sun, 22 Nov 2009 15:52:29 -0800, steve wrote:

[code and output elided]
> Note, the above counting does not include subnormal numbers.

I don't know what those are. We seem to have the same machine parameters:

dan(a)dan-desktop:~/source$ gfortran real5.f90 -Wall -Wextra -o out
dan(a)dan-desktop:~/source$ ./out
epsilon is 1.19209290E-07
[0,0.5) = 1056964608
[0.5,1) = 8388608
0.49999970 2.98023224E-08 z is 0.25000000
0.49999973 2.98023224E-08 z is 0.25000000
0.49999976 2.98023224E-08 z is 0.25000000
0.49999979 2.98023224E-08 z is 0.25000000
0.49999982 2.98023224E-08 z is 0.25000000
0.49999985 2.98023224E-08 z is 0.25000000
0.49999988 2.98023224E-08 z is 0.25000000
0.49999991 2.98023224E-08 z is 0.25000000
0.49999994 2.98023224E-08 z is 0.25000000
0.49999997 2.98023224E-08 z is 0.25000000
0.50000000 5.96046448E-08 z is 0.50000000
0.50000006 5.96046448E-08 z is 0.50000000
0.50000012 5.96046448E-08 z is 0.50000000
0.50000018 5.96046448E-08 z is 0.50000000
0.50000024 5.96046448E-08 z is 0.50000000
0.50000030 5.96046448E-08 z is 0.50000000
0.50000036 5.96046448E-08 z is 0.50000000
0.50000042 5.96046448E-08 z is 0.50000000
0.50000048 5.96046448E-08 z is 0.50000000
0.50000054 5.96046448E-08 z is 0.50000000
dan(a)dan-desktop:~/source$ cat real5.c
cat: real5.c: No such file or directory
dan(a)dan-desktop:~/source$ cat real5.f90
program hj
implicit none
integer(8) i
real x, y, z

y = epsilon(x)
print *, "epsilon is ", y
x = 0
i = 0
! Count number of floats in [0,0.5)
do
i = i + 1
x = nearest(x, 1.)
if (x >= 0.5) exit
end do
print '(A,I0)', '[0,0.5) = ', i
x = 0.5
i = 0
! count number of floats in [0.5,1)
do
i = i + 1
x = nearest(x, 1.)
if (x >= 1.) exit
end do
print '(A,I0)', '[0.5,1) = ', i

x = 0.5
do i = 1, 10
x = nearest(x, -1.)
end do
do i = 1, 20
z = spacing(x)/y
print *, x, spacing(x), "z is ", z
x = nearest(x, 1.)
end do



end program hj

! gfortran real5.f90 -Wall -Wextra -o out
! ./out >text1.txt
dan(a)dan-desktop:~/source$

This program shows the virtues of the nearest function, whose second
argument is of the kind of the first and nonzero, which then returns the
closest value of that kind in the direction of the second argument.

Spacing is an intrinsic that does what I tried to calculate!
--
frank

"Guns: yes, they are harmful."
From: mecej4 on
frank wrote:

> On Sun, 22 Nov 2009 15:52:29 -0800, steve wrote:
>
> [code and output elided]
>> Note, the above counting does not include subnormal numbers.
>
> I don't know what those are.
Floating point numbers whose significand has less than full precision.
They used to be called denormals. Using them avoids sudden underflow.

> We seem to have the same machine parameters:
>
> dan(a)dan-desktop:~/source$ gfortran real5.f90 -Wall -Wextra -o out
> dan(a)dan-desktop:~/source$ ./out
> epsilon is 1.19209290E-07
> [0,0.5) = 1056964608

which is equal to 126 X 2^23. There are seven bits for the biased exponent;
2^7=128, but then your numbers don't include +Inf and NaN.

> [0.5,1) = 8388608
which is exactly 2^23. The significand takes all possible values, while the
sign and biased exponent are fixed (because the range is 2^-1 to 2^0).

<--CUT-->

-- mecej4

From: frank on
On Sun, 22 Nov 2009 15:52:29 -0800, steve wrote:

> print *, x, spacing(x)
> x = nearest(x, 1.)
> end do
>
> end program hj
>
> REMOVE:kargl[209] gfc4x -o z -O hj.f90 REMOVE:kargl[210] ./z
> [0,0.5) = 1056964608
> [0.5,1) = 8388608
> 0.49999970 2.98023224E-08
> 0.49999973 2.98023224E-08
> 0.49999976 2.98023224E-08
> 0.49999979 2.98023224E-08
> 0.49999982 2.98023224E-08
> 0.49999985 2.98023224E-08
> 0.49999988 2.98023224E-08
> 0.49999991 2.98023224E-08
> 0.49999994 2.98023224E-08
> 0.49999997 2.98023224E-08
> 0.50000000 5.96046448E-08
> 0.50000006 5.96046448E-08
> 0.50000012 5.96046448E-08
> 0.50000018 5.96046448E-08
> 0.50000024 5.96046448E-08
> 0.50000030 5.96046448E-08
> 0.50000036 5.96046448E-08
> 0.50000042 5.96046448E-08
> 0.50000048 5.96046448E-08
> 0.50000054 5.96046448E-08

I was expecting it to split the difference:

dan(a)dan-desktop:~/source$ gfortran real6.f90 -Wall -Wextra -o out
dan(a)dan-desktop:~/source$ ./out
0.50000000 5.96046448E-08
dan(a)dan-desktop:~/source$ cat real6.f90
real x
x = .5
print *, x, spacing(x)
end program

! gfortran real6.f90 -Wall -Wextra -o out
! ./out >text1.txt
dan(a)dan-desktop:~/source$
--
frank

"Guns: yes, they are harmful."