flat assembler
Message board for the users of flat assembler.
Index
> Main > How convert 16 bit integer number to float 
Author 

Roman
I have 16 bit data.
For example: 0xC100,0x3C00 How convert 0xC100 to 32 bit float and 0x3C00 convert to 32 bit float ? 

23 Dec 2014, 10:26 

revolution
Use FILD:
Code: my_data dw 0xC100,0x3C00 fild [my_data+0] fild [my_data+2] ;st0=15360.0, st1=16128.0 

23 Dec 2014, 10:36 

Roman
how about SSE ?


23 Dec 2014, 11:37 

Roman
Thanks tthsqe !
In 3d max i get 7.086182 float value from 16 bit int 0x2C89 * 0x64. But fild word 0x2C89 get me another float value ?! 

23 Dec 2014, 15:05 

r22
@Roman you have to give more details when you ask for help.
I think you are talking about the 16bit half precision floating point values not integers. Just because you are representing the value in binary format 0xABCD doesn't make it an integer. http://en.wikipedia.org/wiki/Halfprecision_floatingpoint_format If this is the case then you would need the CVTPH2PS opcode. PH = packed half precision and PS = packed signle precision 

23 Dec 2014, 16:15 

Roman
You right r22.
Sorry. 

23 Dec 2014, 17:00 

Roman
Code: ; input: 4x F16 in XMM0 (low words of each DWord) ; original idea+implementation by Dean Macri ; WARNING: copy & pasted together from other code, this ver is untested!! ; though the original version was definitely correct. bits 32 section .data FP32_no_sign times 4 dd 0x7FFFFFFF FP32_sign_bit times 4 dd 0x80000000 FP16_FP32_sgn_adj times 4 dd 0x70000000 FP16_FP32_sgn_adj2 times 4 dd 0x8FFFFFFF FP16_FP32_denorm times 4 dd 0x38000000 FP16_FP32_denorm_adj times 4 dd 0x00800000 FP16_FP32_exp_adj times 4 dd 0x38000000 FP16_exp_shifted times 4 dd 0x0F800000 FP16_exp_adjust_for_NaN times 4 dd 0x7F800000 FP16_exp_adjust_for_Zero times 4 dd 0x7F800000 FP16_FP32_exp_adj_for_Zero dd 0x38000000, 0x38000000, 0x38000000, 0x38000000 dd 0xB8000000, 0x38000000, 0x38000000, 0x38000000 dd 0x38000000, 0xB8000000, 0x38000000, 0x38000000 dd 0xB8000000, 0xB8000000, 0x38000000, 0x38000000 dd 0x38000000, 0x38000000, 0xB8000000, 0x38000000 dd 0xB8000000, 0x38000000, 0xB8000000, 0x38000000 dd 0x38000000, 0xB8000000, 0xB8000000, 0x38000000 dd 0xB8000000, 0xB8000000, 0xB8000000, 0x38000000 dd 0x38000000, 0x38000000, 0x38000000, 0xB8000000 dd 0xB8000000, 0x38000000, 0x38000000, 0xB8000000 dd 0x38000000, 0xB8000000, 0x38000000, 0xB8000000 dd 0xB8000000, 0xB8000000, 0x38000000, 0xB8000000 dd 0x38000000, 0x38000000, 0xB8000000, 0xB8000000 dd 0xB8000000, 0x38000000, 0xB8000000, 0xB8000000 dd 0x38000000, 0xB8000000, 0xB8000000, 0xB8000000 dd 0xB8000000, 0xB8000000, 0xB8000000, 0xB8000000 section .text f16tof32: ; Shift the mantissa to the correct place (bit 23 in F32 from bit 10 in F16) pslld xmm0, 13 ; Get the sign bit set appropriately paddd xmm0, [FP16_FP32_sgn_adj] pand xmm0, [FP16_FP32_sgn_adj2] ; Save copy, adjust exponent movdqa xmm1, xmm0 paddd xmm0, [FP16_FP32_exp_adj] ; Check for NaNs, inf pand xmm1, [FP16_exp_shifted] pcmpeqd xmm1, [FP16_exp_shifted] pand xmm1, [FP16_exp_adjust_for_NaN] por xmm0, xmm1 lea edx, [FP16_FP32_exp_adj_for_Zero] ; Check for zeros/denorms. This is a pain. We need to ; figure out which FP16 values had a zero value for the biased ; exponent. THEN, we have to subtract away the new exponent, ; so that if we had a denorm orginally, we'll get rid of the ; implicit one we created in the FP32 format. ; movmskps eax, xmm0 movdqa xmm1, xmm0 shl eax, 4 pand xmm1, [FP16_exp_adjust_for_Zero] pcmpeqd xmm1, [FP16_FP32_exp_adj] pand xmm1, [edx + eax] ; Subtract off the implicit 1 if we had a denorm, make the value ; zero if it should be zero. Unfortunately, negative zero become positive ; so we have to put the sign back. ; subps xmm0, xmm1 ; Find the values < 2^(15) (Denorms) movaps xmm2, [FP32_no_sign] andps xmm2, xmm0 cmpleps xmm2, [FP16_FP32_denorm] andps xmm2, [FP16_FP32_denorm_adj] paddd xmm0, xmm2 ; Get the zeros back movdqa xmm2, xmm0 pcmpeqd xmm0, [FP16_FP32_denorm_adj] andnps xmm0, xmm2 ; Put the sign bits back pand xmm1, [FP32_sign_bit] por xmm0, xmm1 ; All done! ret 

23 Dec 2014, 18:39 

Roman
Work good but sometimes wrong sign
Sometimes right sign. 

23 Dec 2014, 19:31 

Roman
How work VCVTPH2PS ?
And how version fasm support VCVTPH2PS ? 

23 Dec 2014, 20:21 

Roman
c++ how convert half to float
https://github.com/codingdude/vetools/blob/master/half.h 

23 Dec 2014, 21:02 

r22
All the CVT opcodes should work the same, I don't know which processor version introduced it though I think only the most recent CPUs would have it.
Code: value dd 0x2c89 movd xmm0, [value] ;; xmm0 = ?, ?, ?, 0x00002c89 cvtph2ps xmm0, xmm0 ;; xmm0 = ?, ?, ?, answer 

24 Dec 2014, 00:34 

Mikl___


08 Jan 2015, 09:16 

revolution
So I guess if your FPU is faulty you can use the all integer code to prepare a float value. fasm does this also for float values.


08 Jan 2015, 10:19 

Mikl___
Hi, revolution!
I thought it would be interesting for all translations integer to real, you offered fild/fstp, tthsqe suggested used SSE2, I suggested using integer instructions. Possible that this will be faster than the first two methods 

08 Jan 2015, 13:11 

revolution
Mikl___: Yes, it is interesting to see such code. Some might find it instructive to see how floats are constructed.
As for the execution speed, well that is probably system dependant, but I feel that in almost all cases using the native FPU would give more performance. But performance would not be the only reason someone might use such code. I already gave the example of fasm using the integer core to construct floats. The FPU can only operate on certain fixed sized values and precision loss might be a factor for some cases. 

08 Jan 2015, 13:38 

< Last Thread  Next Thread > 
Forum Rules:

Copyright © 19992020, Tomasz Grysztar.
Powered by rwasa.