Talk:Number Conversion in BASIC

From BeebWiki

Jump to: navigation, search

Contents

Solution to bugs

May I offer a solution to your conversion code to address the problems where the number exceeds &7FFFFFFF. The problem is simply in the formatting of the number after the repeat loop.

Using FNb0 for example, when the number &80000000 is used A% becomes 0 after the logical AND &7FFFFFFF. This means it falls out of the loop straight away with A$ equally "0". However when you format the number using the RIGHT$(STRING$(N%,B$)+A$,N%) command you are creating a string which is n% long and contains B$ only. In this case it will contain "1111111111111111111111111111111". With some minor adjustments we can take into account when B$ equals "1" and format the result differently to get the correct value.

I have adjusted the FNb0 function to solve the problem. Also I have used B% rather than B$ since it should use less resources.

DEFFNb0(A%,N%):LOCAL A$,B%:IFA%<0:B%=1:A%=A% AND &7FFFFFFF
REPEAT:A$=STR$(A% AND 1)+A$:A%=A% DIV 2:UNTILA%=0
IFB%:A$="1"+RIGHT$(STRING$(31,"0")+A$,31)
=RIGHT$(STRING$(N%,"0")+A$,N%)

On line 3 I have tested whether the original value was negative and formatted the value so sign bit is ON (1) and the remaining number is right padded with 31 zeros. I can assume I can pad this to 32 digits as the following line will truncate the value if required.

On line 4 I simply return the number based on the length argument in N%. Of course if the original value was not negative it can ignore B% and format the number normally.

I have tested this and &80000000 gives the correct value of 10000000000000000000000000000000. &FFFFFFFF gives 11111111111111111111111111111111 and so on.

Quickly looking at the other conversion routines that have a similar problem I believe the same problem exists and the above solution would also address those.

I hope this helps.

Darren 11:00, 4 January 2009 (UTC)

Another way...

For binary print outs I've always gone for something along the lines of

value% = 99
FOR bit% = 7 TO 0 STEP -1
  VDU 48+SGN(value% AND(2^bit%))
NEXT

the use of AND means it doesn't suffer from signedness as the proposed FNb() does, and there's no use of DIV so it should be quite quick. Obviously it can be adapted to do numbers up to 32 bits if needed.Rps102 22:32, 4 January 2009 (UTC)

Problem with 32 bit numbers

Yeah I originally tried it that way but got an error 'Too Big' when checking for the sign bit of a 32-bit number as in.

PRINT 2 AND (2^31)

even though the answer in this example is 0. The code PRINT 2^31 works fine so I assume the error is being cause by the AND' operation in the way its implemented.

I would prefer your way for many reasons but concluded that because of the Too Big error, we needed to use another way and therefore the DIV was used. Of course this is only a problem when someone is working with 32 bit values. Darren 02:48, 5 January 2009 (UTC)

Floating point cast

Curses, I guess the 2^31 is being expanded as a floating point number because of the ^ then being truncated to an integer for AND and overflowing.

Nevermind special casing the top bit just means taking it out of the FOR loop, like

value% = &80000099
VDU48 - (value% < 0)
FOR bit% = 30 TO 0 STEP -1
  VDU 48+SGN(value% AND(2^bit%))
NEXT

Which works here (BASIC IV). Rps102 23:25, 5 January 2009 (UTC)

Personal tools