Floating Point Arithmetic
I personally had very few encounters with floating points in ABAP, usually only in regards to calculating back and forth some values. I never paid any attention to the format of a floating point within or without ABAP. However recently we had a business requirement to provide calculated floating points in a Floating Point encoding of “IEEE-754 single precision” for a third party legacy system.
It was the first time (shame) I learned how floating points are represented by a machine. Just like Character encoding or Integer “encoding” the floating point number needs to be put in a machine readable binary format of a certain length. There are various formats to represent floats, the most common and widely used standard is the IEEE-754 dating from the year 1986 with a revision in 2008.
This standard describes the byte representation of a floating point in several byte length. Most interesting to me was the so called single precision format which uses 32 bits in total, which are split in the segments of
- 1 sign bit
- 8 bits for the exponent
- 23 bits for the mantissa/fraction/significand
As a side note, the double precision uses 64 bits with 11 bits exponent and 52 bits mantissa which enables the machine to calculate more precise.
As an example we can take a decimal of 1742.5
IEEE-754 Single Precision:
0 10001001 10110011101000000000000
IEEE-754 Double Precision:
0 10000001001 1011001110100000000000000000000000000000000000000000
Floating Points in SAP ABAP
Disclaiming right away that I am no expert on ABAP data types, please let me know if the following statements are incorrect – I’d really like to be called out for a mistake.
My expectations regarding Floating Point data type in SAP ABAP have unfortunately been disappointed during research. I found the data type description in the help sites only mentioning the predefined data types
|Decfloat16||IEEE-754-2008||Double Precision with 16 decimal places|
|Decfloat34||IEEE-754-2008||Quad Precision with 34 decimal places|
|f||IEEE-754 (not sure 1986/2008)||Double Precision|
There is no hint given as to why single precision is not supported and I can only assume it is dismissed as double precision is sufficient for business requirements in SAP, however I wonder whether I am one of a few who deals with a legacy system and the requirement of storing floats in this specific byte representation.
Coming back to the example of decimal 1742.5. SAP ABAP represents a f type as
Mind that the endian is different, if I shuffle the bytes it is: 0x409B3A0000… like above
Scaling down attempts
In a first attempt I naively tried to set the length to the data types defined; of course to no avail. I tried to find any conversion based on function modules etc. to scale down the precision to 32 bits. But of course it doesn’t make too much sense, one could probably do it; but how to handle large exponents? Rounding is a huge topic concerning infinite fractions (1/3, π etc.), too.
Again, note that if I make wrong assumptions, please let me know if I didn’t clearly grasp how to deal with the datatypes or if there are any conversions I didn’t find.
Converting human readable decimals to IEEE-754 single precision
I was only able to figure two alternatives at hand: Either do the math on a decimal number to shuffle the 32 bits into the correct encoding or to use a third party conversion library.
Both approaches have pros and cons. The Mathematical solution would be a custom solution which would be under our control and we’d be able to tackle any issues. However as this would be custom code (significant amount of lines) it would definitely take effort time wise to complete that task and it would take several iterations of testing and bug fixing and would require a good documentation and hand over. I also never quite tried to shuffle bits in ABAP so the learning curve needs to be taken.
The 3rd party conversion library came to my mind as I did online researching on the topic and found diverse tools to do online float conversions between different formats, for example:
https://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html (including double precision)
All set and done?
Polyfilling the engine
I found a suitable polyfill at github called typedarray (https://github.com/inexorabletash/polyfill/blob/master/typedarray.js) which offers the missing Datatype of Float32. This finally enabled the conversion to execute successfully. Now I may pass a decimal value (currently as String) to be converted into a 32 bit IEEE-754 single precision hexadecimal.
The solution is there but it is undoubtedly not trivial and comes at a price. Mainly it is the maintenance and complexity I dislike. Yet, it enables us to unit-test the conversion to confirm the conversion result and a potential system update deviation. We may further use it in two independent systems without depending on client side conversion.
I cannot stress enough that I have doubts about the approach – that is why I intend to share this approach here to a critical audience. I didn’t find a quicker or more robust solution as of today. I would be very happy to get your thoughts and challenges on it. Maybe a built in process, code based on C? a web service?
If there is a ABAP kernel developer reading this piece – Might it be possible to have such a conversion or primitive data type available by any chance?