This is a multi-part message in MIME format.
On 10/22/2024 6:57 PM, Lawrence D'Oliveiro wrote:
On Tue, 22 Oct 2024 18:14:14 -0600, Louis Krupp wrote:
On 10/21/2024 10:26 PM, Lawrence D'Oliveiro wrote:
On Sun, 20 Oct 2024 05:35:25 -0000 (UTC), Steven G. Kargl wrote:
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
https://en.wikipedia.org/wiki/Niven%27s_theorem
So a whole set of extra functions, just to get a nice result for one
value?
For arguments in degrees, functions taking arguments in degrees are
slightly more accurate than functions taking arguments converted to
radians. Here's an expanded version of Steve's program:
===
subroutine s_real
implicit none
real x, y
x = 30+360*1111
y = x * (4 * atan(1.) / 180)
print *, 'single precision', sind(x), sin(y)
end subroutine s_real
subroutine s_double
implicit none
double precision x, y
x = 30+360*1111
y = x * (4 * datan(1.d0) / 180)
print *, 'double precision', dsind(x), dsin(y)
end subroutine s_double
program foo
implicit none
call s_real
call s_double
end program foo
===
The output using gfortran:
===
single precision 0.500000000 0.500089288
double precision 0.50000000000000000 0.50000000000024070
===
For 30° plus a large multiple of 360°, the degree-argument function is
(1) demonstrably exact and (2) more accurate using single precision
values than the radian-argument function using converted double
precision values. For just plane 30° (i.e., x = 30), the results are
slightly surprising: === single precision 0.500000000 0.500000000 double precision 0.50000000000000000 0.49999999999999994 === So you *could*
write your own sind function, converting the argument to its equivalent
modulo 360 (and handling negative arguments properly) and then to
radians and finally calling the radian sine function, or you could just
use the sind intrinsic that's provided. No one is forcing you to do one
or the other, and if your angle is already in radians, no one is
suggesting that you convert it to degrees just so you can call the
degree sine function. What makes 30° special? Along with 0° and 90°, it
has a rational sine (0.5) that can also be represented exactly in IEEE
floating point. The cosine of 30°, as I'm sure you know, is (in Fortran) sqrt(3.0) / 2.0, which is irrational and not as obviously correct or
incorrect as the sine of 30°. Louis
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div class="moz-cite-prefix">On 10/22/2024 6:57 PM, Lawrence
D'Oliveiro wrote:<br>
</div>
<blockquote type="cite" cite="mid:vf9hli$1nad3$
[email protected]">
<pre wrap="" class="moz-quote-pre">On Tue, 22 Oct 2024 18:14:14 -0600, Louis Krupp wrote:
</pre>
<blockquote type="cite">
<pre wrap="" class="moz-quote-pre">On 10/21/2024 10:26 PM, Lawrence D'Oliveiro wrote:
</pre>
<blockquote type="cite">
<pre wrap="" class="moz-quote-pre">On Sun, 20 Oct 2024 05:35:25 -0000 (UTC), Steven G. Kargl wrote:
</pre>
<blockquote type="cite">
<pre wrap="" class="moz-quote-pre">% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
</pre>
</blockquote>
<pre wrap="" class="moz-quote-pre">Does it work for 29° and 31° as well? What’s so special about 30°?
</pre>
</blockquote>
<pre wrap="" class="moz-quote-pre"><a
class="moz-txt-link-freetext"
href="
https://en.wikipedia.org/wiki/Niven%27s_theorem"
moz-do-not-send="true">
https://en.wikipedia.org/wiki/Niven%27s_theorem</a>
</pre>
</blockquote>
<pre wrap="" class="moz-quote-pre">So a whole set of extra functions, just to get a nice result for one
value?
</pre>
</blockquote>
<br>
For arguments in degrees, functions taking arguments in degrees are
slightly more accurate than functions taking arguments converted to
radians. Here's an expanded version of Steve's program:<br>
===<br>
subroutine s_real<br>
implicit none<br>
real x, y<br>
x = 30+360*1111<br>
y = x * (4 * atan(1.) / 180)<br>
print *, 'single precision', sind(x), sin(y)<br>
end subroutine s_real<br>
<br>
subroutine s_double<br>
implicit none<br>
double precision x, y<br>
x = 30+360*1111<br>
y = x * (4 * datan(1.d0) / 180)<br>
print *, 'double precision', dsind(x), dsin(y)<br>
end subroutine s_double<br>
<br>
program foo<br>
implicit none<br>
<br>
call s_real<br>
call s_double<br>
end program foo<br>
===<br>
<br>
The output using gfortran:<br>
===<br>
single precision 0.500000000 0.500089288 <br>
double precision 0.50000000000000000 0.50000000000024070 <br>
===<br>
<br>
For <span style="white-space: pre-wrap">30° plus a large multiple of 360</span><span
style="white-space: pre-wrap">°</span><span
style="white-space: pre-wrap">, the degree-argument function is (1) demonstrably exact and (2) more accurate using single precision values than the radian-argument function using converted double precision values.
For just plane </span><span style="white-space: pre-wrap">30° (i.e., x = 30), the results are slightly surprising:
===
single precision 0.500000000 0.500000000
double precision 0.50000000000000000 0.49999999999999994
===
So you *could* write your own sind function, converting the argument to its equivalent modulo 360 (and handling negative arguments properly) and then to radians and finally calling the radian sine function, or you could just use the sind intrinsic that's
provided. No one is forcing you to do one or the other, and if your angle is already in radians, no one is suggesting that you convert it to degrees just so you can call the degree sine function.
What makes </span><span style="white-space: pre-wrap">30° special? Along with 0</span><span
style="white-space: pre-wrap">° and 90</span><span
style="white-space: pre-wrap">°, it has a rational sine (0.5) that can also be represented exactly in IEEE floating point. The cosine of 30</span><span
style="white-space: pre-wrap">°, as I'm sure you know, is (in Fortran) sqrt(3.0) / 2.0, which is irrational and not as obviously correct or incorrect as the sine of 30</span><span
style="white-space: pre-wrap">°.
Louis
</span><span style="white-space: pre-wrap">
</span>
</body>
</html>
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)