kaare_t
kaare_t

Reputation: 51

Normalize a floating point

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

Answers (2)

Sneftel
Sneftel

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

hdl
hdl

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

Related Questions