Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

String Number to COMP-2 Conversion Problem

93 views
Skip to first unread message

Alan Lloyd

unread,
May 13, 1997, 3:00:00 AM5/13/97
to

I need to write a routine to convert a string representation of a
number to floating point (COMP-2) with NO loss of accuracy. The
string is PIC X(30), and the number can be positive, negative,
decimal or integer. I've come up with the following code, which works
in the most part, but in some cases the accuracy is not quite there,
for example:

3.091412 becomes .30914120000000000E 01 (correct)
24.692964 becomes .24692964000000000E 02 (correct)
but
1.297632 becomes .12976319999999999E 01 (wrong)
and
46.239713 becomes .46239712999999998E 02 (wrong).

Can anyone help, and, if possible, explain why the loss of accuracy
occurs. Why is it seemingly so difficult to convert a string to a
number even when the length of the 'string' number is known?

01 WXX-CHAR-COUNT PIC S9(4) COMP (Length of the string number
including any sign)
01 WXX-TEXT-NUMBER PIC X(30)
01 WXX-FLOAT COMP-2
01 WXX-POINT-COUNT PIC S9(4) COMP (No. of decimal points)
01 WXX-NUM-X-LEFT-PART PIC X(9) JUSTIFIED RIGHT
(Figures left of any decimal point)
01 WXX-NUM-LEFT-PART REDEFINES WXX-NUM-X-LEFT-PART
PIC S9(9).
01 WXX-NUM-X-RIGHT-PART PIC X(9).
(Figures right of any decimal point)
01 WXX-NUM-RIGHT-PART REDEFINES WXX-NUM-X-RIGHT-PART
PIC 9(9).
01 WXX-S99V99-A.
03 WXX-S99 PIC S9(9).
03 WXX-V99 PIC 9(9).
01 WXX-S99V99 PIC S9(9)V9(9).


INITIALIZE WXX-POINT-COUNT
WXX-NUM-X-LEFT-PART
WXX-NUM-X-RIGHT-PART
WXX-S99V99-A
WXX-S99V99

* CHECK IF THE NUMBER IS NEGATIVE

IF WXX-TEXT-NUMBER (1:1) = '-'
SET NEG-VALUE TO TRUE
MOVE WXX-TEXT-NUMBER (2:) TO WXX-TEXT-NUMBER
END-IF

* CHECK IF THERE IS A DECIMAL POINT IN THE STRING

INSPECT WXX-TEXT-NUMBER
TALLYING WXX-POINT-COUNT FOR ALL '.'

EVALUATE WXX-POINT-COUNT
WHEN 0
IF NEG-VALUE
MOVE WXX-TEXT-NUMBER (1:WXX-CHAR-COUNT - 1)
TO WXX-NUM-X-LEFT-PART
MOVE 0 TO WXX-NUM-X-RIGHT-PART
ELSE
MOVE WXX-TEXT-NUMBER (1:WXX-CHAR-COUNT)
TO WXX-NUM-X-LEFT-PART
MOVE 0 TO WXX-NUM-X-RIGHT-PART
END-IF
WHEN 1
UNSTRING WXX-TEXT-NUMBER DELIMITED BY '.'
INTO WXX-NUM-X-LEFT-PART
WXX-NUM-X-RIGHT-PART
INSPECT WXX-NUM-X-LEFT-PART
REPLACING ALL ' ' BY '0'
INSPECT WXX-NUM--X-RIGHT-PART
REPLACING ALL ' ' BY '0'
END-EVALUATE

MOVE WXX-NUM-LEFT-PART TO WXX-S99
MOVE WXX-NUM-RIGHT-PART TO WXX-V99

MOVE WXX-S99V99-A TO WXX-S99V99

IF NEG-VALUE
COMPUTE WXX-S99V99 = WXX-S99V99 * -1
END-IF

COMPUTE WXX-FLOAT ROUNDED = WXX-S99V99


Alan Lloyd.


Joseph Kohler

unread,
May 13, 1997, 3:00:00 AM5/13/97
to

Alan,
Why don't you just try formatting the string representation of the
number to the form: 999.E+99 and move it to the comp-2 field. This
should work as the string representation of floating point numbers
allows this. Also be careful when moving back to integer fields; in
order to maintain accuracy the integer must be 18 bytes.

Joe.

Alan Russell

unread,
May 13, 1997, 3:00:00 AM5/13/97
to

Of course!!! Don't you know that it is impossible to ensure no loss of
accuracy when representing numbers in floating point? COMP-2 is by
definition a number expressed as some power of 2. But since all numbers
cannot be expressed evenly as a power of 2 the answers you have are the
best that ANY computer can do.
--
Alan Russell, PhD
AHRu...@aol.com
http://members.aol.com/AHRussell
-----------------------------------------------------------
The opinions expressed are mine alone and not those of the company I work
for.


Alan Lloyd <al...@inter-co.demon.co.uk> wrote in article
<863541655.8665.0...@news.demon.co.uk>...

nospam...@erols.com

unread,
May 14, 1997, 3:00:00 AM5/14/97
to

On Tue, 13 May 1997 16:37:09 GMT, al...@inter-co.demon.co.uk (Alan
Lloyd) wrote:

<snip>

>
>3.091412 becomes .30914120000000000E 01 (correct)
>24.692964 becomes .24692964000000000E 02 (correct)
>but
>1.297632 becomes .12976319999999999E 01 (wrong)
>and
>46.239713 becomes .46239712999999998E 02 (wrong).
>

<snip>

I've had similar strangeness when working with reals and found that it
was all with the IEEE standard and the loss of precision was
acceptable to them.

Needless to say I never wrote another payroll system using reals <g>

Boris

David

unread,
May 14, 1997, 3:00:00 AM5/14/97
to

okay, color me clueless... why would you use real precision for a
payroll program? if we jump back a generation, people didn't use
sliderules to balance their checkbook. using real precision for
routine decimal tasks is certainly similar.
david

David d.s....@ix.netcom.com
____________________________________

Keith Brown

unread,
May 15, 1997, 3:00:00 AM5/15/97
to

I can tell you why, but I can't help you. The internal representation
of a floating point (COMP-2) number is a binary fraction rather than a
decimal fraction. Rather than decimal place values of one tenth, one
hundredth, on thousandth, etc. you have one half, one fourth, one
eighth, one sixteenth, and so on. So three fourths is 0.75 in decimal
(7 tenths + 5 hundredths) and is 0.11 in binary (1 half + 1 fourth).

Some numbers cannot be exactly expressed in a finite number of digits
in a particular base. In decimal, one eleventh is 0.09090909...
repeating forever. The problem happens when an exact decimal number
such as one tenth (0.1 decimal) has no exact representation in binary.
A decimal 0.1 is a repeating fraction in binary:
0.00011001100110011001100... Eventually the COMP-2 format uses all of
its fraction bits and has to stop, and that is the limit of the
precision.

Even if you just directly move a decimal number to a floating point
number you can observe the inexact conversion. Sometimes you get
lucky and the result rounds to the exact value when the compiler
converts it back to decimal in order to display the result, but
sometimes it doesn't. The problem is not in your conversion
algorithm, but rather in the diferent bases of the two numeric
formats. No algorithm in the world can fix it. You are getting as
close as possible in COMP-2.

On Tue, 13 May 1997 16:37:09 GMT, al...@inter-co.demon.co.uk (Alan
Lloyd) wrote:

>I need to write a routine to convert a string representation of a
>number to floating point (COMP-2) with NO loss of accuracy. The
>string is PIC X(30), and the number can be positive, negative,
>decimal or integer. I've come up with the following code, which works
>in the most part, but in some cases the accuracy is not quite there,
>for example:
>

>3.091412 becomes .30914120000000000E 01 (correct)
>24.692964 becomes .24692964000000000E 02 (correct)
>but
>1.297632 becomes .12976319999999999E 01 (wrong)
>and
>46.239713 becomes .46239712999999998E 02 (wrong).
>

Boris

unread,
May 15, 1997, 3:00:00 AM5/15/97
to

On Wed, 14 May 1997 23:27:44 GMT, d.s....@ix.netcom.com (David)
wrote:

>
>okay, color me clueless... why would you use real precision for a
>payroll program? if we jump back a generation, people didn't use
>sliderules to balance their checkbook. using real precision for
>routine decimal tasks is certainly similar.
>david
>
>David d.s....@ix.netcom.com
>____________________________________


Because I needed to keep track of large numbers and was very
inexperienced. But I learned that leason wuick <g>.

Boris

Joseph Cote

unread,
May 15, 1997, 3:00:00 AM5/15/97
to

On Thu, 15 May 1997 00:19:21 GMT, kbr...@arlington.net (Keith Brown)
wrote:

>I can tell you why, but I can't help you. The internal representation
>of a floating point (COMP-2) number is a binary fraction rather than a
>decimal fraction. Rather than decimal place values of one tenth, one
>hundredth, on thousandth, etc. you have one half, one fourth, one
>eighth, one sixteenth, and so on. So three fourths is 0.75 in decimal
>(7 tenths + 5 hundredths) and is 0.11 in binary (1 half + 1 fourth).
>
>Some numbers cannot be exactly expressed in a finite number of digits
>in a particular base. In decimal, one eleventh is 0.09090909...
>repeating forever. The problem happens when an exact decimal number
>such as one tenth (0.1 decimal) has no exact representation in binary.
>A decimal 0.1 is a repeating fraction in binary:
>0.00011001100110011001100... Eventually the COMP-2 format uses all of
>its fraction bits and has to stop, and that is the limit of the
>precision.

Good explanation


==========================================
*** Beware the man with only one book. ***
***************Joseph Cote****************
***********jose...@ix.netcom.com*********
==========================================

Charles F Hankel

unread,
May 17, 1997, 3:00:00 AM5/17/97
to


David <d.s....@ix.netcom.com> wrote in article
<337e49f1...@nntp.ix.netcom.com>...


> On Wed, 14 May 1997 14:38:15 GMT, nospam...@erols.com wrote:
>

> >On Tue, 13 May 1997 16:37:09 GMT, al...@inter-co.demon.co.uk (Alan
> >Lloyd) wrote:
> >

> ><snip>


> >Needless to say I never wrote another payroll system using reals <g>
> >
>

> okay, color me clueless... why would you use real precision for a
> payroll program? if we jump back a generation, people didn't use
> sliderules to balance their checkbook. using real precision for
> routine decimal tasks is certainly similar.

Hello Clueless,

I think Boris was only joking. If he was serious, though, tell me and I'll
throw my clues away as well.

--
Charles F Hankel, Freedom Bird Ltd

An opinion is only an opinion
and this opinion is mine.

Eugene A. Pallat

unread,
May 19, 1997, 3:00:00 AM5/19/97
to

This is what happens when you need to convert floating point numbers from
base 10 to base 16 and back. An error of 2 in the 17th decimal place is
insignificant, since real world equipment to measure this doesn't exist.

Most people don't know the difference between accuracy and precision.

pi = 27.7893874839 very precise, but inaccurate.
pi = 3.14 not very precise, but more accurate than the above.

If you round off .46239712999999998E 02 you get .462397123000000 and
that's to SIXTEEN decimal places!

Business application don't need that kind of floating point precision.
Real world business apps use LARGE numbers. That's an error of .01 cents
in a trillion dollars! Put it in perspective.

If you need that sort of precision, don't use floating point! Let me
repeat. If you need that sort of precision, don't use floating point!

You know, a billion dollars here, a billion dollars there. Pretty soon it
adds up to real money!
:-)

Remove the '-' from orion-data for sending email to me.

Gene eapa...@orion-data.com

Orion Data Systems

Solicitations to me must be pre-approved in writing
by me after soliciitor pays $1,000 US per incident.
Solicitations sent to me are proof you accept this
notice and will send a certified check forthwith.


Joseph Kohler <76260...@compuserve.com> wrote in article
<3378B9...@compuserve.com>...

0 new messages