Hi All
I have a sensor here that spits out four bytes in IEEE 754 floating point format. I remembered Kyle muttering that he didn’t use this particulate floating point format and with zero examples of float variables in the sample files, I wrote my own procedures. Both work. Both have obvious errors, which I don’t understand. Question: Is input as 1 dword preferred over 45 bytes? Sources: https://www.h-schmidt.net/FloatConverter/IEEE754.html https://www.youtube.com/watch?v=8afbTaA-gOQ Problems: Floating point mantissa is a number between 1 and 2, where the 1 before the decimal point is conveniently removed. The bits store the 1/2, 1/4, 1/8.. values. I needed to go to decimal, so I used 5_000_000 and shifted that to the right (2_500_000, 1_250_000, etc) which should add up to 1e7 max if all mantissa bits are 1. I forgot the 1e8 😀 In my opinion 1.5xxx * 2^y is very different from 0.5xxx * 2^y, but the result is correct? Also, when divided by 1e7, this doesn’t work? For some reason my value is 10x too small. Easy fix. I also used the 23rd bit of the mantissa, counting from 1. Jal counts from 0, so this should be bit 22. Yet, it works. For the dword variant I corrected the 23 to 22 (the mantissa formally needs no mask from the fp input value, since I only use one bit) but this gave a result that was 4 times too large. Easy fix, but even less understandable. Any ideas about the sample that I should make for this? Are there typical IEEE 754 numbers that I should use as an example? I am also a bit worried about the limited exponent range in my code. For larger exponents I could shift leftward one bit and a time and catch the overflow in a separate byte, so I can cover the full dword range. I’m also not sure about the way how the conversion works the other way. After all, 1/2 * 2^1, 1/4 * 2^2 and 1/8 * 2^3 are all 1. There must be a preferred format. -- ------------------------------------------------------------------- -- IEE 754 floating point conversion: 1 sign bit, 8 exponent bits, 23 mantissa bits -- max 4 digits after decimal point -- source: https://www.h-schmidt.net/FloatConverter/IEEE754.html -- source: https://www.youtube.com/watch?v=8afbTaA-gOQ -- Original: Eur van Andel -- ------------------------------------------------------------------- function ieee754_to_sdword(byte in fp3, byte in fp2, byte in fp1, byte in fp0, byte in digits) return sdword is var bit sign at fp3:7 -- 1 bit sign var byte exponent -- 8 bits exponent var dword mantissa -- 23 bits mantissa, 32 bits here var bit sig_bit at mantissa:23 -- most significant bit var dword value = 0 var dword fraction = 5_000_000 -- 7 digits exponent = (fp3 << 1) + (fp2 >> 7) mantissa = dword(fp2 & 0b0111_1111) mantissa = mantissa << 15 -- only 7 bits, 8th is for exponent mantissa = mantissa + (word(fp1) << 8) + fp0 exponent = exponent - 127 -- exponent bias, fake sbyte for 22 loop if sig_bit then value = value + fraction end if mantissa = mantissa << 1 fraction = fraction >> 1 -- add 1/2, 1/4, etc of 10^7 end loop value = value << exponent -- exponent max 8 here, not that much if digits == 0 then value = value / 1_000_000 -- should be 10^7? this works, dunno why elsif digits == 1 then value = value / 100_000 elsif digits == 2 then value = value / 10_000 elsif digits == 3 then value = value / 1_000 elsif digits == 4 then value = value / 100 end if -- more digits too slow if sign then return - sdword(value) else return sdword(value) end if end function -- ------------------------------------------------------------------- -- IEE 754 floating point conversion: 1 sign bit, 8 exponent bits, 23 mantissa bits -- max 4 digits after decimal point -- source: https://www.h-schmidt.net/FloatConverter/IEEE754.html -- source: https://www.youtube.com/watch?v=8afbTaA-gOQ -- Original: Eur van Andel -- ------------------------------------------------------------------- function ieee754_to_sdword2(dword in fp, byte in digits) return sdword is var bit sign at fp:31 -- 1 bit sign var byte exponent = byte((fp & 0x7F_80_00_00) >> 23) -- 8 bits exponent var dword mantissa = fp & 0x00_7F_FF_FF -- 23 bits mantissa var bit sig_bit at mantissa:22 -- most significant bit var dword value = 0 var dword fraction = 5_000_000 -- 7 digits exponent = exponent - 127 -- exponent bias, fake sbyte for 22 loop if sig_bit then value = value + fraction end if mantissa = mantissa << 1 fraction = fraction >> 1 -- add 1/2, 1/4, etc of 10^7 end loop if exponent > 2 then exponent = exponent -2 -- dafuq? value = value << exponent -- exponent max 8 here, not that much else value = value << exponent value = value >> 2 end if if digits == 0 then value = value / 1_000_000 -- should be 10^7? this works, dunno why elsif digits == 1 then value = value / 100_000 elsif digits == 2 then value = value / 10_000 elsif digits == 3 then value = value / 1_000 elsif digits == 4 then value = value / 100 end if -- more digits too slow if sign then return - sdword(value) else return sdword(value) end if end function --- ir EE van Andel [email protected] <mailto:[email protected]> http://www.fiwihex.nl <http://www.fiwihex.nl/> Fiwihex B.V. Wierdensestraat 74, NL7604BK Almelo, Netherlands tel+31-653-286573 -- You received this message because you are subscribed to the Google Groups "jallib" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/6A4EB9D7-24B3-4C6B-A7F1-30261C58B8ED%40fiwihex.nl.
