Thread: IEEE 754 floating point conversion

1. IEEE 754 floating point conversion

I have 32 bit floating point numbers stored as (little endian):
(first 16 bits)
1 bit Mantissa sign (bit 15)
15 bit High Mantissa
(second 16 bits)
8 bit Low Mantissa
7 bit Exponent
1 bit Exponent sign (bit 0)

which gives 23 bit mantissa

eg 1 is encoded as (hex):
0x400000 mantissa 0 sign
1 exponent 0 sign

2 is encoded as:
0x400000 mantissa 0 sign
2 exponent 0 sign

3 is encoded as:
0x600000 mantissa 0 sign
2 exponent 0 sign

12 is encoded as:
0x600000 0 sign
4 exponent 0 sign

I need to turn numbers stored in this encoding into standard IEEE 754 floating point numbers (as recognised by c).

Can anyone assist with the process please. I'm using c but I'd be grateful for any guidance.

[Note this info has been updated as further info has been obtained]

2. Re: IEEE 754 floating point conversion

Why is this in General PC? It seems that it would be better suited to General Developer.

3. Re: IEEE 754 floating point conversion

I thought General PC was the most appropriate - but feel free to move as there's been no replies

4. Re: IEEE 754 floating point conversion

Well we contracted that well known programming company Acme Corporation to produce the code. They put their best 3 programmers on it (Daffy Duck, Goofy and Porky Pig) and produced this below. It actually seems to work! But if anyone can 'improve' on the code that would be just great. Note that speed isn't particularly an issue.

Code:
```// hmant high 16 bits of 24 bit mantissa with bit 15 mantissa sign
// lwexp bits 15 - 8 low 8 bits mantissa, bits 7 - 0 exponent with bit 0 exponent sign
// Both mantissa and exponent 2's complement
float doNum(uint16_t hmant, uint16_t lwexp) {
try {
const uint8_t expsgn { (uint8_t)(lwexp & 1u) };
const uint8_t expon {(uint8_t)( (uint8_t)((lwexp & 0xfeu) >> 1) | (uint8_t)(expsgn << 7))};					// 8 bits - bit 0 exp sign
uint8_t expon1 { expsgn ? uint8_t(~expon + 1) : expon };

const uint8_t sgn { (uint8_t)((hmant & 0x8000u) >> 15) };
const uint32_t mants { ((uint32_t)(hmant & 0xffffu) << 8) | ((lwexp & 0xff00u) >> 8) };
const uint32_t mant { sgn ? uint32_t((~mants & 0x00ffffffu) + 1) : mants};

const std::bitset<23> bmant {mant};

auto smant { bmant.to_string() };

if (mant & 0x800000u) {
smant = '1' + smant;
++expon1;
}

float dec {};
std::string rhs;

if (expsgn == 0) {
if (expon1 > smant.size())
smant += std::string(expon1 - smant.size(), '0');

rhs = smant.substr(expon1);
} else {
rhs = std::string(expon1, '0') + smant;
smant = std::string(expon1, '0');
}

for (float d { 0.5 }; const auto ch : rhs) {
if (ch == '1')
dec += d;

d /= 2.0;
}

std::string out {std::to_string(std::bitset<23> {smant.substr(0, expon1)}.to_ulong())};

if (dec)
out += std::format("{}", dec).substr(1);

if (sgn)
out = '-' + out;

return std::stof(out);
}

catch (...) {
std::cout << "<noexp> ";
std::cin.get();
return 0;
}
}```

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•