Reputation: 51
I have a problem with a PLC (Programmable Logical Controller) which does not handle denormalized floating points.
Here's a few hex representations of the numbers (denormalized) I am receiving from the controller on the oposite side of my PLC: 0x00004180, 0x0000C180, 0x00006FA0
Would anybody be so kind to share a small code example (C++/C# or similar) on how to bitwise normalize a value similar to the above? I cannot use any float operations on the numbers since they are not recognized in the PLC, hence HEX/BIN operations only.
Precision is not a problem.
Upvotes: 4
Views: 2855
Reputation: 41474
If you have bitshifting with sign extension, a simple and branchless approach to flush denormals to zero is as follows (where f
is the integer reinterpretation of the floating point number):
int32_t x = f & 0x7F800000; // mask out sign and mantissa
x += 0x7F700000; // overflows unless exponent is zero; MSB now indicates normalized
x >> 31; // sign-extend the MSB to all bits
f &= x; // flush denormals to zero
Upvotes: 1
Reputation: 1038
As a follow up to the question's comments, if you'd like to go for using fixed-point arithmetic:
Denormalized are less than 2^{-126} and the fraction part has no implicit set leading bit, so basically a denormalized floating-point number is 0.mantissa * 2^{-126}
You could fetch the mask in an int32_t and then have your floating-point value equal to int_val * 2^{-126 - 23} = int_val * 2^{-149}.
The number 23
is because binary32 format has 23 bits of mantissa. Of course you would store the integer value and the exponent value in different variables.
Upvotes: 3