[comp.sys.cbm] C Power 128 floating point to integer conversion bug

prindle@NADC.ARPA (10/30/87)

From: prindle@nadc.arpa (Frank Prindle)

I have finally figured out what causes C Power 128 to incorrectly convert
floating point values to integers (signed), and this bug could easily explain
all kinds of miscellaneous problems with floating point when using this
compiler.  The problem is in library file "float1.obj".  It revolves around
a BASIC ROM routine used to do the conversion; the library assumes this BASIC
routine returns it's values in the A and Y registers, but it doesn't; rather
it returns them in the floating point accumulator in bank 0.  Furthermore,
even when the return value is fetched from the correct place, the routine
only operates correctly if the floating point number has first had it's
fractional part removed (BASIC INT function) by truncating toward -infinity.
When I get a chance, I will post both the fixed source and the object code
for "float1.obj".  The source can be assembled by the Rinfret/Zarling C Power
assembler.  In any case, once you have replaced "float1.obj" on a copy of your
library, conversions from float to (signed) integer will work much, much
better.

Remember, this relates to C Power *128* only, not the 64 version.  The 64
version works correctly because a different BASIC ROM routine is used.
Sincerely,
Frank Prindle
Prindle@NADC.arpa

howie@pnet02.cts.com (Howard Herman) (11/01/87)

Well one source of the prob may relate to the Upgrade ROM's for the
128.  It was supposed to fix this prob, but it still is in evidence.
Try running this on the 128 (Hope I remember it):
A=8.75:B=INT(A):C=A-B:PRINT C
Now you would expect to get ".75".  However, well I'll let you run it,
and maybe this is where your prob stems from.
Hope it helps.
Howie Herman

UUCP: {hplabs!hp-sdd!crash, ihnp4!scgvaxd!cadovax}!gryphon!pnet02!howie
INET: howie@pnet02.CTS.COM

fred@cbmvax.UUCP (11/02/87)

In article <2119@gryphon.CTS.COM>, howie@pnet02.cts.com (Howard Herman) writes:
> Well one source of the prob may relate to the Upgrade ROM's for the
> 128.  It was supposed to fix this prob, but it still is in evidence.
> A=8.75:B=INT(A):C=A-B:PRINT C
> Now you would expect to get ".75".  However, well I'll let you run it,
> and maybe this is where your prob stems from.

I think you mis-remembered the magic numbers- the ones don't cause a
problem on either ROM set.  If you found some numbers that do not work
on the upgrade ROMs, I'd like to hear about it.

The C Power problem is unrelated to this.  Incidentally, I have fully
described the C128 math routines in the DEVpack manual.  I will announce
when it's available, where to get it, and how much $$$$ just as soon as
this engineer finds out.
--
-- 
Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred
				arpa:	cbmvax!fred@RUTGERS.EDU
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380

dean@hyper.UUCP (Dean Gahlon) (11/02/87)

In article <5365@rutgers.rutgers.edu>, prindle@NADC.ARPA writes:
> 
> I have finally figured out what causes C Power 128 to incorrectly convert
> floating point values to integers (signed), and this bug could easily explain
> all kinds of miscellaneous problems with floating point when using this
> compiler.  The problem is in library file "float1.obj".  It revolves around
> a BASIC ROM routine used to do the conversion; the library assumes this BASIC
> routine returns it's values in the A and Y registers, but it doesn't; rather
> it returns them in the floating point accumulator in bank 0.  Furthermore,
> even when the return value is fetched from the correct place, the routine
> only operates correctly if the floating point number has first had it's
> fractional part removed (BASIC INT function) by truncating toward -infinity.
> In any case, once you have replaced "float1.obj" on a copy of your
> library, conversions from float to (signed) integer will work much, much
> better.

	Are you sure that that's all of the problem? I discovered this
particular problem some time ago (by the way, it's caused, I think, by 
the fact that the name in the C-128 Programmer's Reference refers to the
routine that's called incorrectly as "GIVAYF", leading one to the wrong
impression that it returns its results in the AY pair), but didn't post
any results at that time because I still seem to have problems using floating
point. Granted, it works much better with the change to float1.obj, but
there still seems to be something wrong. Maybe tonight I'll try again; my
earlier problems could have been due in part to some lack of familiarity 
with C. On a different note, has anybody gotten the scanf %x or %o functions
to work correctly with C-power 128?


						Dean C. Gahlon
						...ihnp4!umn-cs!hyper!dean

jay@garfield.UUCP (11/03/87)

In article <2675@cbmvax.UUCP> fred@cbmvax.UUCP (Fred Bowen) writes:
#described the C128 math routines in the DEVpack manual.  I will announce
                                         ^^^^^^^
#when it's available, where to get it, and how much $$$$ just as soon as
#this engineer finds out.
#--
#-- 
#Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred

What is the DEVpack? and what does it consist of?


-- 
J.(Jay) Kumarasingam
UUCP:	{akgua,allegra,cbosgd,ihnp4,seismo,utcsri}!garfield!jay
EAN:	jay@garfield.mun.cdn
CSNET:  jay%garfield.mun.cdn@ubc.csnet

elg@killer.UUCP (11/05/87)

in article <4115@garfield.UUCP>, jay@garfield.UUCP (Jay Kumarasingam) says:
> 
> In article <2675@cbmvax.UUCP> fred@cbmvax.UUCP (Fred Bowen) writes:
> #described the C128 math routines in the DEVpack manual.  I will announce
>                                          ^^^^^^^
> #when it's available, where to get it, and how much $$$$ just as soon as
> #this engineer finds out.
> #--
> #-- 
> #Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred
> 
> What is the DEVpack? and what does it consist of?

I'll let Fred give the gory details when he finds out the status of the
DEVpack and is able to announce its availability, but suffice it to say that
all of us long-suffering C-128 programmers have been slobbering and drooling
all over our keyboards waiting for it. Amongst other things, it has a fast
assembler that produces relocatable object code that's linked with a linker
(so that you can have seperate assembly of object modules -- a Big Win when
you have 15,000 lines of source code), and source code to fastload and RAMdisk
drivers. I am looking forward to it. CASM is still slow even with the speedups
I've done to it, and I really don't prefer cross-development (takes as long to
load up a terminal program and establish connection etc. etc., as to re-link
using the C-Power linker).

--
     Eric Green   elg@usl.CSNET      Snail Mail P.O. Box 92191       
     {cbosgd,ihnp4}!killer!elg       Lafayette, LA 70509             
Hello darkness my old friend, I've come to talk with you again....

howie@pnet02.cts.com (Howard Herman) (11/05/87)

In article, fred@cbmvax.UUCP (Fred Bowen) writes:
>I think you mis-remembered the magic numbers- the ones don't cause a
>problem on either ROM set.  If you found some numbers that do not work
>on the upgrade ROMs, I'd like to hear about it.
>The C Power problem is unrelated to this.

The formula, recalled on the fly was wrong.  The actual one that causes a
prob with the upgrade ROM's for the 128 is: 
A=8.9:B=INT(A):C=A-B:PRINT C

With the new ROM's installed, I have no way of knowing if this is a new prob,
or a carry over from the old ROM's.  I do know that the new ROM's fixed the
trailing decimals when doing multiplication with numbers in the thousands
range.  While I may be the bearer of news of a bug(?), I take no credit for
its discovery.  As far as I know that goes to the illustrous CBM*BOB of
P-Link.

Howie Herman                           howie@pnet02.cts.com
                                       P-LINK: YORK


UUCP: {hplabs!hp-sdd!crash, ihnp4!scgvaxd!cadovax}!gryphon!pnet02!howie
INET: howie@pnet02.CTS.COM

fred@cbmvax.UUCP (Fred Bowen) (11/05/87)

In article <613@hyper.UUCP>, dean@hyper.UUCP (Dean Gahlon) writes:
> In article <5365@rutgers.rutgers.edu>, prindle@NADC.ARPA writes:
> > 
> > I have finally figured out what causes C Power 128 to incorrectly convert
> > floating point values to integers (signed), and this bug could explain
> > all kinds of miscellaneous problems with floating point when using this
> > compiler.  The problem is in library file "float1.obj".  It revolves around
> > a BASIC routine used to do the conversion; the library assumes this BASIC
> > routine returns it's values in the A and Y registers, but it doesn't; rather
> > it returns them in the floating point accumulator in bank 0.
> 
> 	Are you sure that that's all of the problem? I discovered this
> particular problem some time ago (by the way, it's caused, I think, by 
> the fact that the name in the C-128 Programmer's Reference refers to the
> routine that's called incorrectly as "GIVAYF", leading one to the wrong
> impression that it returns its results in the AY pair), but didn't post
> any results at that time because I still seem to have problems using floating
> point.

Frank is correct, and Dean is confused.  There is no problem that I am aware
of with GIVAYF, and the C128 ROM upgrade has no changes here.  The routine is
the same as that of the C64, and refers to passing a signed integer in the
A and Y registers (msb/lsb) and getting the floating point represntation in
the FAC.  The address of GIVAYF, besides being in the C128 BASIC jump table, 
also appears at the RAM vector ADRAY2 ($5 on the C64, $117C on the C128) for
historical compatibility.  GIVAYF is typically used by programmers utilizing
the USR(x) BASIC function to return values.  GIVAYF is documented in many,
many books, dating from the PET days.

This routine is described, along with an example, in the DEVpack manual.  That
doesn't help you now, eh?  Well, for those interested, here's a simple example
for the C128:
		$1800  A9 00    LDA #>int_val
		$1802  A0 46    LDY #<int_val
		$1804  20 03 AF JSR GIVAYF	;FLOAT A,Y -> FAC
		$1807  20 AF 06 JSR FOUT	;FAC -> STRING @ $100
		$18OA  A0 00    LDY #0
		$180C  B9 00 01 LDA $100,Y
		$180F  F0 06    BEQ $1817
		$1811  20 D2 FF JSR BSOUT	;PRINT STRING
		$1814  C8       INY
		$1815  D0 F5    BNE $180C
		$1817  60       RTS

If you call this from the monitor with something like JF1800, it will print
the decimal value of whatever is in A and Y ($46 here, my initial).  (Betcha
didn't think math hacking could be this much fun!  Wanna tackle floating
point multiplication and division, then, um, trig functions next? :-)
--
-- 
Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred
				arpa:	cbmvax!fred@RUTGERS.EDU
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380

fred@cbmvax.UUCP (Fred Bowen) (11/06/87)

In article <2675@cbmvax.UUCP>, fred@cbmvax.UUCP (Fred Bowen) writes:
> In article <2119@gryphon.CTS.COM>, howie@pnet02.cts.com (Howard Herman) writes:
> > Well one source of the prob may relate to the Upgrade ROM's for the
> > 128.  It was supposed to fix this prob, but it still is in evidence.
> > A=8.75:B=INT(A):C=A-B:PRINT C
> > Now you would expect to get ".75".  However, well I'll let you run it,
> > and maybe this is where your prob stems from.
> 
> I think you mis-remembered the magic numbers- the ones don't cause a
> problem on either ROM set.  If you found some numbers that do not work
> on the upgrade ROMs, I'd like to hear about it.
> 

Just found out what you are referring to from Bob Umfer of Plink.  The
problem was   A=8.65 : B=INT(A) : C=A-B : PRINT C  and you get .649999999
and not .65 like you'd expect.

This is not a bug- it's typical floating point rounding error (.000000001
error is not all that bad, now is it? :-)  Actually, most machines will
do likewise- the VAX FORTAN compiler, using REAL*4, is actually worse,
returning something like .6499996.  Now, .65 looks kinda simple to you, but
to a computer with a mere 24 bits of precision for the mantissa, it's
ugly as hell.

For most calculations, this is no big deal.  Now, if you want dollars and
cents output, use PRINT USING "###.##";C and you will get 0.65, since the
formatted output of PRINT USING *rounds* the result to fit your format. If
you are using a C64, you'll hafta add a fraction,  multiply by 100
and integerize, then divide by 100.  Or you could get a C128.  Whichever
seems easiest...
--
-- 
Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred
				arpa:	cbmvax!fred@RUTGERS.EDU
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380

fred@cbmvax.UUCP (Fred Bowen) (11/06/87)

In article <1994@killer.UUCP>, elg@killer.UUCP (Eric Green) writes:
>  [regarding C128 DEVpack...]   Amongst other things, it has a fast
> assembler that produces relocatable object code that's linked with a linker
> (so that you can have seperate assembly of object modules -- a Big Win when

Urp!  Where did you get the idea it produces relocatable code and uses a
linker?  I'm afraid you'll be disappointed in this respect.  The source
code can be spread across several disk drives, but the assembly produces
one monolithic, absolute chuck of MOS hex format object code.  

The DEVpack is done & approved.  We're waiting for the manual to come back
from the printer I believe.  I'll post the contents sometime soon (like when
my fingers warm up and I can type again).
--
-- 
Fred Bowen			uucp:	{ihnp4|rutgers|caip}!cbmvax!fred
				arpa:	cbmvax!fred@RUTGERS.EDU
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380