flat assembler
Message board for the users of flat assembler.

 Index > Main > How convert 16 bit integer number to float
Author
Roman

Joined: 21 Apr 2012
Posts: 1123
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
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 18609
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

Joined: 21 Apr 2012
Posts: 1123
Roman
23 Dec 2014, 11:37
tthsqe

Joined: 20 May 2009
Posts: 739
tthsqe
Code:
```; SSE 2 - data is UNSIGNED words (a,b) (packed as 2-vector)

movd   xmm0, [data]     ; lower two words are (a,b)
pxor   xmm1, xmm1       ; zeros
punpcklwd   xmm0, xmm1       ; lower two dwords are (a,b) zero extended
cvtdq2ps   xmm0, xmm0       ; lower 2 floats are (a,b)

; SSE 4.1 - data is SIGNED words (a,b) (packed as 2-vector)

movd   xmm0, [data]     ; lower two words are (a,b)
pmovsxwd   xmm0, xmm0       ; lower two dwords are (a,b) sign extended
cvtdq2ps   xmm0, xmm0       ; lower 2 floats are (a,b)

; SSE 2 - data is SIGNED words (a,b) (packed as 2-vector) might be a better way

movd   xmm0, [data]     ; lower two words are (a,b)
movdqa   xmm1, xmm0
psraw   xmm1, 15         ; get sign bits
punpcklwd   xmm0, xmm1       ; lower two dwords are (a,b) zero extended
cvtdq2ps   xmm0, xmm0       ; lower 2 floats are (a,b)       ```
23 Dec 2014, 13:26
Roman

Joined: 21 Apr 2012
Posts: 1123
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

Joined: 27 Dec 2004
Posts: 805
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/Half-precision_floating-point_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

Joined: 21 Apr 2012
Posts: 1123
Roman
You right r22.
Sorry.
23 Dec 2014, 17:00
Roman

Joined: 21 Apr 2012
Posts: 1123
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_denorm times 4 dd 0x38000000
FP16_exp_shifted times 4 dd 0x0F800000

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
movdqa xmm1, xmm0
; Check for NaNs, inf
pand xmm1, [FP16_exp_shifted]
pcmpeqd xmm1, [FP16_exp_shifted]
por xmm0, xmm1
; 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, [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]
; Get the zeros back
movdqa xmm2, xmm0
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

Joined: 21 Apr 2012
Posts: 1123
Roman
Work good but sometimes wrong sign
Sometimes right sign.
23 Dec 2014, 19:31
Roman

Joined: 21 Apr 2012
Posts: 1123
Roman
How work VCVTPH2PS ?
And how version fasm support VCVTPH2PS ?
23 Dec 2014, 20:21
Roman

Joined: 21 Apr 2012
Posts: 1123
Roman
23 Dec 2014, 21:02
r22

Joined: 27 Dec 2004
Posts: 805
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___

Joined: 30 Dec 2014
Posts: 123
Location: Russian Federation, Irkutsk
Mikl___
1. integer to float32
Code:
```section .data
x dw 1ABCh
y dd 0
section .text
mov ax,[x]
or ax,ax
jz exit
jns @f
mov byte [y+3],80h
neg ax
@@:     mov cl,16
bsr bx,ax
sub cl,bl
shl ax,cl
shr ax,1
shl bx,7
or word [y+2],bx
or word [y+1],ax
exit:    ```
2. integer to float64
Code:
```section .data
x dw -7935
y dq 0
section .text
mov ax,[x]
or ax,ax
jz exit
jns @f
mov byte [y+7],80h
neg ax
@@:     mov cl,16
bsr bx,ax
sub cl,bl
shl ax,cl
shld bx,ax,4
shl ax,4
or word [y+6],bx
mov word [y+4],ax
exit:       ```
3. integer to float80
Code:
```section .data
x dw 1EFFh
y dt 0
section .text
mov ax,[x]
or ax,ax
jz exit
jns @f
mov byte [y+9],80h
neg ax
@@:     mov cl,15
bsr bx,ax
sub cl,bl
shl ax,cl
or word [y+8],bx
mov word [y+6],ax
exit:       ```
08 Jan 2015, 09:16
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 18609
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___

Joined: 30 Dec 2014
Posts: 123
Location: Russian Federation, Irkutsk
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
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 18609
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
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum