Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Re: Rounding off double precision
> Yes! You are expecting calculations done with floating point numbers
> to be EXACT. Such calculations are actually approximate. Each
> operation has a small quantity of error built in. That's the nature of
> floating point.

No I am not. I understand how (binary) floating points are used to
represent actual (decimal) numbers. If I thought they were exact, I
wouldn't be asking how to round it off properly so that the errors are
not shown.

However I have since found where I went wrong. I was using

double precision Speed, Azimuth, V
Azimuth = 90.
parameter(Pi = 3.141592653589793238d0)
V = Speed * cos(Azimuth * Pi / 180.)
print *, V

The problem with the unusually large value of -4.37113886E-06 arose
because I didn't declare Pi to be double precision, even though I
assigned a double precision value to it. Thus rounding off its value
to real. I realized that after studying Richard Maine's short program,
which gave me a smaller answer of 6.12303177E-17 in the expected range
of precision.

Now that I have a value in the range E-17 instead of E-06, I can now
use F15.12 to round it off! My question has been answered. Thanks to
all who helped!

Report this thread to moderator Post Follow-up to this message
Old Post
Bamm
03-30-08 12:24 AM


Re: Rounding off double precision
Bamm wrote:
(snip)

> However I have since found where I went wrong. I was using

> double precision Speed, Azimuth, V
> Azimuth = 90.
> parameter(Pi = 3.141592653589793238d0)
> V = Speed * cos(Azimuth * Pi / 180.)
> print *, V

> The problem with the unusually large value of -4.37113886E-06 arose
> because I didn't declare Pi to be double precision, even though I
> assigned a double precision value to it.

This problem might be more likely to occur to ex-C programmers.

C uses #define is places where Fortran uses PARAMETER,
but #define is typeless.

It might be nice for compilers to give a warning in this case.
There are enough reasons to assign double precision values to
single precision variables that I wouldn't want a default warning
in that case.   I don't believe the same is true for PARAMETER.

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
03-30-08 12:24 AM


Re: Rounding off double precision
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

> Bamm wrote:
> (snip)
> 
> 
> 
>
> This problem might be more likely to occur to ex-C programmers.
>
> C uses #define is places where Fortran uses PARAMETER,
> but #define is typeless.

There's a little more to it than that.  In C, the literal constant "0.1"
has type double precision, in Fortran, the literal constant "0.1" has
type single precision.  So

double x = 0.1;

in C gives x the double precision value

+1. 6000000000000000888178419700125232338905
33447265625 / 16

whereas

DOUBLE PRECISION X
X = 0.1

in Fortran gives X the single precision value

+1.60000002384185791015625 / 16

Actually, now that I look at it, the OP actually had the opposite
problem, analogous to

X = 0.1D0

where X is implicitly typed default real (single precision), but the
literal constant has type double precision.

Chip

--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
GPG Key ID: 852E052F
GPG Key Fingerprint: 77E5 2B51 4907 F08A 7E92  DE80 AFA9 9A8F 852E 052F

Report this thread to moderator Post Follow-up to this message
Old Post
Charles Coldwell
03-31-08 02:14 AM


Re: Rounding off double precision
Charles Coldwell wrote:
(snip, I wrote) 

> There's a little more to it than that.  In C, the literal constant "0.1"
> has type double precision, in Fortran, the literal constant "0.1" has
> type single precision.  So
(snip)

> Actually, now that I look at it, the OP actually had the opposite
> problem, analogous to

> X = 0.1D0

> where X is implicitly typed default real (single precision), but the
> literal constant has type double precision.

Well, the OP had:

double precision Speed, Azimuth, V
Azimuth = 90.
parameter(Pi = 3.141592653589793238d0)
V = Speed * cos(Azimuth * Pi / 180.)

A double precision constant as a single precision PARAMETER
used in a double precision expression.  The C equivalent

#define PI 3.141592653589793238

as you say, the constant is double precision (without an f),
but PI itself is typeless.  You can do things like:

#define ABS(x,y) ((x)>(y)?(x):(y))

as a typeless absolute value in C89.  (It wont' work for complex
types in C99.)

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
03-31-08 02:17 AM


Re: Rounding off double precision
glen herrmannsfeldt wrote:
> Charles Coldwell wrote:
> (snip, I wrote) 
> 
> (snip)
> 
> 
> 
>
> Well, the OP had:
>
>       double precision Speed, Azimuth, V
>       Azimuth = 90.
>       parameter(Pi = 3.141592653589793238d0)
>       V = Speed * cos(Azimuth * Pi / 180.)
>
> A double precision constant as a single precision PARAMETER
> used in a double precision expression.  The C equivalent
>
> #define PI 3.141592653589793238
>
> as you say, the constant is double precision (without an f),
> but PI itself is typeless.  You can do things like:
>
> #define ABS(x,y) ((x)>(y)?(x):(y))
>
> as a typeless absolute value in C89.  (It wont' work for complex
> types in C99.)

I think you mean MIN instead of ABS.  ABS would be something like:

#define ABS(x) ((x) >= 0 ? (x) : -(x))

Unlike a FORTRAN statement function, which this vaguely resembles,
macros that use an argument in more than one place do weird things when
passed an expression with side effects, e.g., ABS(x++).

Louis

Report this thread to moderator Post Follow-up to this message
Old Post
Louis Krupp
03-31-08 10:51 AM


Re: Rounding off double precision
Louis Krupp wrote:
(snip)

> I think you mean MIN instead of ABS.  ABS would be something like:

> #define ABS(x) ((x) >= 0 ? (x) : -(x))

> Unlike a FORTRAN statement function, which this vaguely resembles,
> macros that use an argument in more than one place do weird things when
> passed an expression with side effects, e.g., ABS(x++).

Yes, both are often written as macros in C.  I was thinking
about both and wrote something in between.

The side effects are something to remember, but it doesn't
take too long as long as you know it is a macro.

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
03-31-08 10:52 AM


Re: Rounding off double precision

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
 news:n9idnTScSJC6423anZ2dnUVZ_qninZ2d@co
mcast.com...
> Louis Krupp wrote:
> (snip)
> 
> 
> 
>
> Yes, both are often written as macros in C.  I was thinking
> about both and wrote something in between.
>
> The side effects are something to remember, but it doesn't
> take too long as long as you know it is a macro.

You have ped (sp) my interest here.

PRE00-A. Prefer inline functions to macros

The claim that 'macros are dangerous' can, to a certain extent, be
justified, in much the same way that the claim 'crossing the road is
dangerous' can be justified. Crossing the road is dangerous, even to the
experienced road user, if done carelessly. Likewise, using macros can be
problematic. SECCODE quotes the classic i++ abuse of a macro call, and
suggests that inline functions can eliminate this problem.

This is certainly true where inline functions are available. It is true
that C99 guarantees that inline functions are available, but nowhere is
there any guarantee that a C99 implementation is available! Yes, within
the terms of reference of SECCODE, the suggestion to use inline functions
has obvious merit. But for those of us without access to inline functions,
it is impractical. SECCODE itself recognises this, by pointing out
portability concerns.

For the experienced C programmer, the use of UPPER CASE for macro names is
generally sufficient to act as a warning that macro arguments with side
effects should be avoided.

In the first code fragment, we see a #define that is clearly local to a
function (because the fragment contains executable code). This is
generally considered to be unwise. I can see why the fragment is written
that way, of course - it's to save space! But in a document which purports
to provide a guide to best practice, it's still a curious way to write
code.

The expansion given in the second code fragment is (trivially) incorrect.
Strictly, it should be:


int a = 81 / ((++i) * (++i) * (++i));

The SECCODE version of the expansion omits the extra parentheses that its
previous definition requires.

The third code fragment, which demonstrates the inline version of the code,
is poorly written. When we're cubing a value, even a moderate input can
result in overflow. For example, on 16-bit-int systems, i = 32 will
produce overflow in the call to cube. On 32-bit-int systems, i = 1291
(hardly excessive) will produce overflow. Precisely how one would solve
this problem depends on one's requirements. If it is known that excessive
inputs will never occur, an assertion is appropriate. If they may well
occur, it must be decided whether they constitute an error. If so, the
function needs a way to report that error. Otherwise, an alternative
strategy (e.g. bignums) must be considered. In any event, the function as
written is insecure, because it can produce undefined behaviour.

The fourth fragment illustrates that a clash between a macro parameter name
and a file scope object name can cause incorrect results. It seems to me,
however, that this is not so much a reason not to use macros as a reason
not to use file scope objects!

In the 'SWAP' example, the hoary old XOR trick is used to swap two values.
This is a really bad idea, for two reasons: firstly, it only works on
integer types: SWAP(mydoubleA, mydoubleB) will fail to compile. Secondly,
if you do this: SWAP(myintA, myintA), you don't get a swap - you get 0!
The example, then, is a poor one. Whilst the suggested replacement
sidesteps the first problem neatly (because it suggests a function that
takes int *, so nobody can reasonably expect it to swap doubles), it fails
to address the second problem. Far better to use a temp:


void swap(int *pa, int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}

This is guaranteed to work, provided only that pa and pb point to valid int
objects.

The example where the interaction of two macros and a file scope object
produce incorrect results is rather contrived. It's an argument against
using macros to adjust file scope object values. It's an argument against
file scope object values themselves. It's an argument against tight
coupling. But it's not an argument against macros.

The claim that the execution of functions cannot be interleaved 'so
problematic orderings are not possible' ignores the fact that the order of
evaluation of multiple functions called in the same statement is not
specified. Whilst this doesn't cause a problem in the example given, it
can certainly cause problems in cases where the called functions have
related side effects (e.g. updating the same object, writing to the same
stream, or whatever). Although y = f(x) + g(x); is harmless in the example
given, it is not a recipe for success.

Lest the wrong impression be garnered from the above, let me reiterate that
the danger of side effects being unwittingly duplicated by macros is
significant, and the careful programmer should ensure that (a) macros
don't evaluate arguments more than once if at all possible; (b) macro
names are written in UPPER CASE to draw attention to them; (c) macros are
only used if there is no sensible alternative that meets the project
requirements.

#end excerpt from clc

I think what you are both saying about macros could be surmised in a
paragraph.

--

"I am waiting for them to prove that God is really American."

~~  Lawrence Ferlinghetti



Report this thread to moderator Post Follow-up to this message
Old Post
Gerry Ford
03-31-08 10:53 AM


Re: Rounding off double precision
Louis Krupp wrote:
> glen herrmannsfeldt wrote:
<snip> 
>
> I think you mean MIN instead of ABS.  ABS would be something like:

Oops.  Make that MAX.

Louis

Report this thread to moderator Post Follow-up to this message
Old Post
Louis Krupp
03-31-08 10:53 AM


Re: Rounding off double precision
On Mon, 31 Mar 2008 05:46:41 -0700 (PDT), Bamm <bammster@gmail.com> wrote:

-|> For Fortran 77 define Floor as:
-|> DINT(X)=X-DMOD(X,1.D0)
-|> FLOOR(X)=DINT(X)-DMOD(2.D0+DSIGN(1.D0,X),3.D0)
-|
-|What is DMOD and DINT, and how are they different from MOD and INT?
-|Thanks.
These force Double Precision versions of MOD and  AINT to be used.
-|
-|Btw, the problem has been solved. But I am looking at your suggestion
-|as it might lead to something better.


Report this thread to moderator Post Follow-up to this message
Old Post
Herman D. Knoble
03-31-08 01:50 PM


Re: Rounding off double precision
Louis Krupp wrote:
> Louis Krupp wrote: 
> <snip> 
>
> Oops.  Make that MAX.
>
> Louis
Apparently writing macro code is easy, naming them is the
hard part?  ;) ;) ;)  Sorry, I can't resist temptation
before my morning martini!

Dick Hendrickson

Report this thread to moderator Post Follow-up to this message
Old Post
Dick Hendrickson
03-31-08 01:50 PM


Sponsored Links




Last Thread Next Thread Next
Pages (4): « 1 [2] 3 4 »
Search this forum -> 
Post New Thread

Fortran archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 02:16 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.