using_2016-bit_20floating_20point_20values

*by Richard Russell, August 2007*

*BBC BASIC for Windows* stores floating point numbers in 40-bit and 64-bit resolutions and has no built-in support for 16-bit (half precision) floating point numbers. Half precision floats are sometimes used in graphics applications, including OpenGL and Direct3D, because they are an efficient method of representing luminance and chrominance levels with a high dynamic range.

The following three functions may be used to perform the necessary conversions:

**FN_ConvertToHalf**converts a number to a half-precision floating point value**FN_ConvertToHalfRounded**converts a number to half precision with rounding**FN_ConvertFromHalf**converts a number from a half-precision floating point value

The difference between **FN_ConvertToHalf** and **FN_ConvertToHalfRounded** is that the former truncates towards zero, but is slightly faster, whereas the latter generates the half-precision number which is nearest to the supplied value, but is slightly slower. Use **FN_ConvertToHalf** if you know that the value can be converted exactly into half precision (for example it was returned from **FN_ConvertFromHalf**) or if you are not too concerned about accuracy. Use **FN_ConvertToHalfRounded** otherwise.

DEF FN_ConvertFromHalf(A%) LOCAL A# IF (A% AND &7C00) = 0 THEN = SGN(A% << 16) * (A% AND &3FF) * 2^-24 !(^A#+4) = ((A% AND &8000) << 16) + ((A% AND &7FFF) << 10) + &3F000000 = A# DEF FN_ConvertToHalf(A#) LOCAL A% IF ABSA# < 2^-14 THEN = (A# < 0 AND &8000) OR (ABSA# / 2^-24) A# /= 65536.0# : A% = !(^A#+4) = ((A% >> 16) AND &8000) + ((A% >> 10) AND &7FFF) DEF FN_ConvertToHalfRounded(A#) LOCAL A% IF ABSA# < 2^-14 THEN = (A# < 0 AND &8000) OR (ABSA# / 2^-24 + 0.5) A# /= 65536.0# : A% = !(^A#+4) = ((A% >> 16) AND &8000) + ((A% >> 10) AND &7FFF) + ((A% >> 9) AND 1)

Note that **FN_ConvertToHalf** and **FN_ConvertToHalfRounded** perform *no range checking* to ensure that the value you pass can be represented as a valid half-precision number. If this is important you can add a check as follows:

DEF FN_ConvertToHalf(A#) LOCAL A% IF ABSA# >= 2^16 THEN ERROR 20, "Number too big" IF ABSA# < 2^-14 THEN = (A# < 0 AND &8000) OR (ABSA# / 2^-24) A# /= 65536.0# : A% = !(^A#+4) = ((A% >> 16) AND &8000) + ((A% >> 10) AND &7FFF) DEF FN_ConvertToHalfRounded(A#) LOCAL A% IF ABSA# >= &FFF0 THEN ERROR 20, "Number too big" IF ABSA# < 2^-14 THEN = (A# < 0 AND &8000) OR (ABSA# / 2^-24 + 0.5) A# /= 65536.0# : A% = !(^A#+4) = ((A% >> 16) AND &8000) + ((A% >> 10) AND &7FFF) + ((A% >> 9) AND 1)

In all cases the 16-bit half-precision value is passed in the least-significant 16-bits of a 32-bit integer.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

using_2016-bit_20floating_20point_20values.txt · Last modified: 2018/04/17 19:23 by tbest3112