Hi Nick, > Does any one know how, of have a good reference for, converting floating > point numbers to and from the 5-byte format used in the FAC and by all the > Kernal routines? The 5-byte format is pretty easy to understand, and is actually quite similar to the IEEE floating-point formats. Just to put things in context, allow me a few paragraphs to explain representation of numbers on a computer. Let's start by writing a number in binary: 0101.0110 (I just made that up), which is 2^2 + 2^0 + 2^-2 + 2^-3 = 5 + 1/4 + 1/8 = 5.375. In a fixed point scheme, the decimal point stays, well, fixed -- in this case, each number might be one byte, with four digits to the left of the decimal point and four to the right. So after, say, multiplying two numbers together, the routine would fix up the result so that there would be four bits to the left and four to the right. In a floating point scheme, the idea is to let the decimal point move around, by using an extra byte for the exponent. That is, numbers are now represented as A * 2^B -- A is the mantissa, B is the exponent. In the example above, you could represent the "floating point" number in a lot of ways -- 0101.0110 * 2^0, 01.010110 * 2^2, 01010110*2^-4, and so on. The first thing to notice is that any leading zeros are wasted bits -- you can always keep shifting the number left until a "1" is hit, and let the exponent keep track of the decimal point. And as long as the first bit is _always_ a 1, there's no reason to waste a bit on it! This will hopefully become clear shortly. So, the C64 represents floating point numbers using five bytes. The first byte is the exponent plus 129. An exponent of zero represents the number zero (Mapping the 64 is wrong in their description). The next four bytes represent the mantissa of the number, in big-endian format (not the usual lo-hi format of the 6510), except for the very first bit. Because the first digit is always assumed to be a "1" -- any nonzero number has to have a "1" in it somewhere -- the very first bit is used to represent the sign of the number, 0 being positive. So let's do an example: 85 00 00 00 00 The exponent is $85 -- subtract 129 to get 4. The first bit is zero, so the number is positive. The mantissa is 1 + .00 00 00 00 = 1. So the final value is 1 * 2^4, or 16. Second example: 84 20 00 00 00 Exponent is 3. Sign is positive. Mantissa is 1.0100000 0000 0000 0000 (leading bit is always 1) Value is 1.01 ^ 2^3 = 1010 = 10. Third example: 80 80 00 00 00 Exponent is -1. Sign is negative. Mantissa is 1. Value is -1 * 2^-1 = -0.5. There are lots of constant floating point numbers in the kernal, if you want to try converting some more (e.g. at $B9D6). Oh, what the heck: 81 35 04 f3 34 Exponent = 0. Number = b5 04 f3 34 * 2^-31 = 181 4 243 52 * 2^-31 = 1.4142136 = sqrt(2). So, an algorithm to convert C64 5-byte floats would look like: - Read first byte. If zero then number is zero, else subtract 129 to get exponent. - Read next four bytes = mantissa. If high bit is 1 then sign=-1, else sign=1. - ORA $80 00 00 00 to mantissa to get leading 1. - Number is sign*mantissa*2^(exponent-31). The -31 is only needed if you represent the mantissa as a positive integer (remember that there's actually a decimal point to the left of the 4-byte mantissa). To convert to a 5-byte fp number, basically you just reverse the steps (but how you do it will depend on how your numbers are represented). One possibility is to convert the numbers to binary and process them in binary; perhaps someone here will offer up a decent algorithm. Hope that helps, -Steve - This message was sent through the cbm-hackers mailing list. To unsubscribe: echo unsubscribe | mail cbm-hackers-request@dot.tml.hut.fi.
Archive generated by hypermail 2.1.1.