Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to truncate float values in XMM register

Tags:

c++

c

assembly

sse

How to get only the integer part of float? So, I have a float array: x[4] = {5.0, 13.0, 25.0, 41.0}; I'm putting it in xmm0 and then I'm making sqrt of it. I need one more command which will help to take only int part of this sqrt. For example sqrt of 5 will be 2.236068 and I need just 2.0 in an answer
Code:

__asm 
        {
            movups xmm0, x
            sqrtps xmm0, xmm0
            //here need some command
            movups x, xmm0
        }
like image 996
Alex Avatar asked Dec 04 '15 09:12

Alex


2 Answers

Using roundps is the easiest. The rounding mode table is somewhere else but you need rounding mode 3 (towards zero).

Converting to an integer and back only works if the input is guaranteed to be in some range (about 0 to 4.6e18 because of the square root). You could do this with cvttps2dq and cvtdq2ps. That will only require SSE2, roundps requires SSE4.1. You can use cvtps2dq only if the rounding mode is set to truncate, which it usually isn't, so you'd have to change+restore it.

like image 156
harold Avatar answered Oct 19 '22 01:10

harold


There is an SO question some of whose answers address the topic:

  • fmodf (fp modulo) function;
  • float to int (also mentions intrinsics, see below);

There also is a paper discussing the float to int conversion issue, specifically mentioning the second answer ( no plagiarism implied ).

The major Windows compilers (at least) come with so-called intrinsics ( highly optimized inlined functions ) that might be of interest, eg. MSVC and Intel (float to int: p. 42; float floor(float) function and likes: p. 135).

Caveat

This is a researched answer. I have not personally used the referenced techniques.

like image 25
collapsar Avatar answered Oct 19 '22 03:10

collapsar