Results 1 to 4 of 4

Thread: IEEE 754 floating point conversion

  1. #1

    Thread Starter
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    998

    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]
    Last edited by 2kaud; Feb 10th, 2024 at 07:18 AM.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,028

    Re: IEEE 754 floating point conversion

    Why is this in General PC? It seems that it would be better suited to General Developer.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    998

    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
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4

    Thread Starter
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    998

    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;
    	}
    }
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

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



Click Here to Expand Forum to Full Width