comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Specify the degree of accuracy of a floating point number
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Specify the degree of accuracy of a floating point number [message #52591] Fri, 23 February 2007 02:01 Go to next message
tochaf is currently offline  tochaf
Messages: 6
Registered: February 2007
Junior Member
> thank you,
> all of you for the great suggestions.
> Loknath


so, can I know about your result? Now you have 0.268954 in 0.27 in
float format to make some aritmetics operations??? . My question is...
HOW?


thank you...
Re: Specify the degree of accuracy of a floating point number [message #52594 is a reply to message #52591] Thu, 22 February 2007 13:18 Go to previous messageGo to next message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
Brian Larsen writes:

> I bet you are in a better position to understand this than I am
> however...

Well, what I know about it is that formatting numbers in
a sensible way for display (in widget programs, for example)
is EXTREMELY annoying. And double precision numbers are
perverse. (Although not usually as perverse as with your
ROUND_OFF program. I find it amusing, however, that it barfed
so convincingly on my very first try!)

NUMBER_FORMATTER is not too bad, but even there I have
to look at it cross-eyed occasionally to maintain the
fiction that it is a beautiful program. :-)

There are a couple of articles on my web page addressing
the issue for the more curious among you.

Cheers,

David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
Re: Specify the degree of accuracy of a floating point number [message #52595 is a reply to message #52594] Thu, 22 February 2007 12:43 Go to previous messageGo to next message
Brian Larsen is currently offline  Brian Larsen
Messages: 270
Registered: June 2006
Senior Member
David,

hmmm...


>
> IDL> a = 432.49584738273845D
> IDL> print, round_off(a, 0.0000001)
> 2.9991178
>
> Huh!? What did I do wrong?

This is what it does for me (and I do have datatype)

IDL> a = 432.49584738273845D
IDL> print, round_off(a, 0.0000001)
% Compiled module: ROUND_OFF.
-214.74836
% Program caused arithmetic error: Floating illegal operand
IDL> print, round_off(a, 0.0000001d)
-214.74836
% Program caused arithmetic error: Floating illegal operand
IDL> help, a
A DOUBLE = 432.49585
IDL> print, round_off(a, 0.0001)
432.49580

I think the answer is in the warning (% Program caused arithmetic
error: Floating illegal operand)
look at this chunk of the code:
num = abs(num)
if acc lt 1.0 then begin
factor = round(1.0/acc)
x = long((num+0.5*acc)*factor)/double(factor)
endif else begin
x = long((long((num+acc/2.)/acc))*acc)
endelse
;; and add in a help statement
HELP, x, acc

I then get:
IDL> a = 432.49584738273845D
IDL> print, round_off(a, 0.0000001)
X DOUBLE = -214.74836
ACC FLOAT = 1.00000e-07
-214.74836
% Program caused arithmetic error: Floating illegal operand


Is it something to do with dividing a long by a double??
x = long((num+0.5*acc)*factor)/double(factor)

Or something to do with?
http://www.dfanning.com/math_tips/sky_is_falling.html

Odd that it works with smaller number of digits...
IDL> print, round_off(a, 0.000001)
X DOUBLE = 432.49585
ACC FLOAT = 1.00000e-06
432.49585
IDL> print, round_off(a, 0.0000001)
X DOUBLE = -214.74836
ACC FLOAT = 1.00000e-07
-214.74836


I bet you are in a better position to understand this than I am
however...


Brian



------------------------------------------------------------ ---------
Brian A. Larsen
Dept. of Physics
Space Science and Engineering Lab (SSEL)
Montana State University - Bozeman
Bozeman, MT 59717
Re: Specify the degree of accuracy of a floating point number [message #52596 is a reply to message #52595] Thu, 22 February 2007 10:57 Go to previous messageGo to next message
loknath is currently offline  loknath
Messages: 11
Registered: May 2006
Junior Member
On Feb 22, 11:28 am, David Fanning <n...@dfanning.com> wrote:
> Brian Larsen writes:
>> Just to add more to the mix here:
>
>> I use the solarsoft routine round_off.pro (I will put it inline as its
>> short) to do this, seems to work well and its already written, which I
>> always like.
>
> To get this to work (I don't have the DATATYPE function), I changed
> this case statement:
>
>> case datatype(num) of
>> 'BYT': x = byte(x)
>> 'INT': x = fix(x)
>> 'LON': x = long(x)
>> 'DOU': x = double(x)
>> 'FLO': x = float(x)
>> endcase
>
> To this:
>
> case Size(num, /TName) of
> 'BYTE': x = byte(x)
> 'INT': x = fix(x)
> 'LONG': x = long(x)
> 'DOUBLE': x = double(x)
> 'FLOAT': x = float(x)
> endcase
>
> A pretty harmless change, it seems to me. Then I tried the
> program:
>
> IDL> a = 432.49584738273845D
> IDL> print, round_off(a, 0.0000001)
> 2.9991178
>
> Huh!? What did I do wrong?
>
> Cheers,
>
> David
> --
> David Fanning, Ph.D.
> Fanning Software Consulting, Inc.
> Coyote's Guide to IDL Programming:http://www.dfanning.com/
> Sepore ma de ni thui. ("Perhaps thou speakest truth.")

thank you,
all of you for the great suggestions.
Loknath
Re: Specify the degree of accuracy of a floating point number [message #52597 is a reply to message #52596] Thu, 22 February 2007 10:28 Go to previous messageGo to next message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
Brian Larsen writes:

> Just to add more to the mix here:
>
> I use the solarsoft routine round_off.pro (I will put it inline as its
> short) to do this, seems to work well and its already written, which I
> always like.

To get this to work (I don't have the DATATYPE function), I changed
this case statement:

> case datatype(num) of
> 'BYT': x = byte(x)
> 'INT': x = fix(x)
> 'LON': x = long(x)
> 'DOU': x = double(x)
> 'FLO': x = float(x)
> endcase

To this:

case Size(num, /TName) of
'BYTE': x = byte(x)
'INT': x = fix(x)
'LONG': x = long(x)
'DOUBLE': x = double(x)
'FLOAT': x = float(x)
endcase

A pretty harmless change, it seems to me. Then I tried the
program:

IDL> a = 432.49584738273845D
IDL> print, round_off(a, 0.0000001)
2.9991178

Huh!? What did I do wrong?

Cheers,

David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
Re: Specify the degree of accuracy of a floating point number [message #52598 is a reply to message #52597] Thu, 22 February 2007 09:58 Go to previous messageGo to next message
Brian Larsen is currently offline  Brian Larsen
Messages: 270
Registered: June 2006
Senior Member
Just to add more to the mix here:

I use the solarsoft routine round_off.pro (I will put it inline as its
short) to do this, seems to work well and its already written, which I
always like.

Brian


;+
; Project : SOHO - CDS
;
; Name : ROUND_OFF()
;
; Purpose : To round a number to a specified accuracy
;
; Explanation : Rounds the input number to the accuracy specified.
;
; Use : IDL> out = round_off(x,acc)
; IDL> out = round_off(12.278,0.01) ==> out = 12.28
;
; Inputs : x - the number to be operated on
; acc - the numerical accuracy required
;
; Opt. Inputs : None
;
; Outputs : The function value is the input rounded to the desired
accuracy
;
; Opt. Outputs: None
;
; Keywords : None
;
; Calls : NINT
;
; Restrictions: None
;
; Side effects: None
;
; Category : Util, Numerical
;
; Prev. Hist. : None
;
; Written : C D Pike, RAL, 17-May-1993
;
; Modified : Replace calls to NINT by ROUND. CDP, 17-Jun-95
;
; Version : Version 2, 17-Jun-95
;-

function round_off,num,acc

;
; check enough parameters
;
if n_params() lt 2 then begin
bell
print,'Use: num = round_off(input, accuracy)'
return,0.0
endif

;
; check for negative input
;
if num lt 0.0 then neg=1 else neg=0

;
; round off according to the accuracy required
;
num = abs(num)
if acc lt 1.0 then begin
factor = round(1.0/acc)
x = long((num+0.5*acc)*factor)/double(factor)
endif else begin
x = long((long((num+acc/2.)/acc))*acc)
endelse

;
; return in same form received
;
case datatype(num) of
'BYT': x = byte(x)
'INT': x = fix(x)
'LON': x = long(x)
'DOU': x = double(x)
'FLO': x = float(x)
endcase

if neg then return,-x else return,x

end









------------------------------------------------------------ ---------
Brian A. Larsen
Dept. of Physics
Space Science and Engineering Lab (SSEL)
Montana State University - Bozeman
Bozeman, MT 59717
Re: Specify the degree of accuracy of a floating point number [message #52603 is a reply to message #52598] Thu, 22 February 2007 05:05 Go to previous messageGo to next message
Allan Whiteford is currently offline  Allan Whiteford
Messages: 117
Registered: June 2006
Senior Member
loknath wrote:
> Hi
> Is there a way to convert a single precision or double precision
> floating point number to an accuracy of specified decimal places? In
> other words, if I want to write 0.268954 or 233.256 to an accuracy of
> 2 decimal places, i.e. 0.27 and 233.26, is there a way to do it?
> Thanks
>

Loknath,

As well as David's suggestion you could look at the format keyword of
string() and print.

e.g.

IDL> number=0.268954
IDL> str=string(number,format='(F0.2)')
IDL> print,str
0.27
IDL> print,number,format='(F0.2)'
0.27

similarly:

IDL> number=233.256
IDL> str=string(number,format='(F0.2)')
IDL> print,str
233.26
IDL> print,number,format='(F0.2)'
233.26

Note that support for F0.N is fairly recent (doesn't work in 6.0, does
work in 6.2 - don't have 6.1 handy to test).

Thanks,

Allan
Re: Specify the degree of accuracy of a floating point number [message #52606 is a reply to message #52603] Wed, 21 February 2007 22:22 Go to previous messageGo to next message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
loknath writes:

> Is there a way to convert a single precision or double precision
> floating point number to an accuracy of specified decimal places? In
> other words, if I want to write 0.268954 or 233.256 to an accuracy of
> 2 decimal places, i.e. 0.27 and 233.26, is there a way to do it?

You could try NUMBER_FORMATTER:

http://www.dfanning.com/programs/number_formatter.pro

Cheers,

David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
Re: Specify the degree of accuracy of a floating point number [message #52730 is a reply to message #52597] Fri, 23 February 2007 08:43 Go to previous message
Kenneth Bowman is currently offline  Kenneth Bowman
Messages: 86
Registered: November 2006
Member
In article <MPG.20478eaa542e4575989e91@news.frii.com>,
David Fanning <news@dfanning.com> wrote:

> A pretty harmless change, it seems to me. Then I tried the
> program:
>
> IDL> a = 432.49584738273845D
> IDL> print, round_off(a, 0.0000001)
> 2.9991178
>
> Huh!? What did I do wrong?

This is a round-off error issue. The function works by multiplying the
input by a factor, rounding to a LONG, and then dividing by the same factor
to convert back to a floating-point type.

When you are trying to preserve a lot of precision (digits), you get round-off
issues with the LONG. This can be avoided (in most cases), by rounding to
a LONG64.

See examples below

IDL> a = 432.49584738273845D

This works for small precision
IDL> print, DOUBLE(ROUND(100.0D0*a))/100.0
432.50000

This fails for large precision
IDL> print, DOUBLE(ROUND(100000000.0D0*a))/100000000.0
21.474836
% Program caused arithmetic error: Floating illegal operand

But works if 64-bit integers are used
IDL> print, DOUBLE(ROUND(100000000.0D0*a, /L64))/100000000.0
432.49585


Cheers, Ken
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: Displaying slices using same scaling
Next Topic: READ issue

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 13:49:18 PDT 2025

Total time taken to generate the page: 0.00749 seconds