Silicomancer
Silicomancer

Reputation: 9216

Create denormalized (subnormal) floating point values in C++

For testing purposes I need to create one positive and one negative denormalized (aka subnormal) float and double number in C++.

How can I write/produce such a number?

Upvotes: 4

Views: 2533

Answers (4)

MNS
MNS

Reputation: 1394

The following is a demonstration of how a denormalized IEEE-754 floating point value can be formed in memory.

const uint32_t denormal_as_int[2] = {0x0000001, 0x00000000};
double denormal;
memcpy(&denormal, &denormal_as_int, sizeof(denormal));

The standard way of doing this is of course the one mentioned by @DietmarKüh

Upvotes: 1

Steve Hollasch
Steve Hollasch

Reputation: 2131

For full flexibility and coverage, create a union with an unsigned integer value and a floating-point value of the same size. Probably unsigned int + float for 32-bit values, and unsigned long + double for 64-bit values. Store your desired denorm value in the integer field, and read out the corresponding floating-point value. If you want to get fancy, specify the integer with bit fields, for the sign, exponent and fraction portions of your floating point number.

32-bit denorms are in the range [0x00000001, 0x007fffff] for positive values, and [0x80000001, 0x807fffff] for negative denorms.

64-bit denorms are in the range [0x0000000000000001, 0x000fffffffffffff] for positive values, and [0x8000000000000001, 0x800fffffffffffff] for negative denorms.

If you use bit fields in your translation union, then the sign bit is arbitrary, exponent is zero, and the fraction can be any value but zero.

Upvotes: 3

Petr
Petr

Reputation: 10007

Another approach is, obviously, take the minimal normalized value DBL_MIN (or, well, std::numeric_limits<double>::min()) and divide it by something; similarly for float. Invert the sign for negative subnormal.

Upvotes: 1

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154045

You could use -std::numeric_limits<T>::denorm_min() and std::numeric_limits<T>::denorm_min(). It is just incidental that the produced denormalized values have a special characteristic. If you don't want that, multiply by some reasonably small integer value.

Upvotes: 4

Related Questions