何がインターネットには想像もつかなに変換するfloatのint x86
-
09-06-2019 - |
質問
何がインターネットには想像もつかないに変換するには浮動小数点数をintにx86CPUを搭載しています。Preferrably Cまたは組成をとることができる並C)のための任意の組み合わせの
- 32/64/80ビットのfloat>32/64ビット整数
話を楽しめるように設定しました技術がより速くようにコンパイラです。
解決
でに依存したい場合は、切り捨変換または四捨五入のつどこでどのような精度。デフォルトでは、Cを切り捨変換ができますfloat値のint.がありFPUの指示がなくなANSI Cでの変換が重要な注意を用いなどを知ることFPUの丸めます。以降の回答の問題は非常に複雑に依存して変数ていなかったとしたら、おすすめの記号:
他のヒント
満載の変換を用いSSEが最速の方法にすることができるので変換複数の値と同じ。 gparted 多くの組み立てることはほとんど変換の復号化された出力のオーディオの整数サンプル数);チェックしたいくつかの例を示します。
使用するトリック平x86/x87コードは、仮数部のfloat値を表すint.32ビット版おります。
64-bitバージョンが類推.のLua版を掲載し上記は速くなり、頼りにして前方一致のdoubleを32ビットの結果ることができますが、そのためにx87ユニットをすることができるソフトをdouble精度な予測を算出するのに使用した、ダブル64ビットのintに変換します。
にフォーカスをこのコードで完全に携帯用のためのすべてのプラットフォームに適合したIEEE754の前提は、浮動小数点の丸めモードに設定します。注意:携帯の意味で統開発にも取り組んでいます。ム以外のx86通常は利益がないにも関わらずっとからこの技術による場合にはtrueを返します。
static const float Snapper=3<<22;
union UFloatInt {
int i;
float f;
};
/** by Vlad Kaipetsky
portable assuming FP24 set to nearest rounding mode
efficient on x86 platform
*/
inline int toInt( float fval )
{
Assert( fabs(fval)<=0x003fffff ); // only 23 bit values handled
UFloatInt &fi = *(UFloatInt *)&fval;
fi.f += Snapper;
return ( (fi.i)&0x007fffff ) - 0x00400000;
}
できる保証は、CPUの実行コードは、SSE3対応もPentium5、JBBでき、コンパイラを使用すFISTTP指導(-msse3gcc).そうでないものとなるように常について:
ご注意FISTTPとは異なFISTP(とその課題が遅).その一環としてSSE3が実際にのみ)X87側エンス解析により評価を行った。
その他そのX86CPUのであろうが、変換、イブレア城、イブレア?:)
あの指示に変換するには浮動小数点のint組立:利用のFISTP。でpopsの値を浮動小数点のスタックに変換して整数、店舗でのアドレスを指定します。ないと思うがより早い方を使用しない限り延長命令セットのようなMMXはSSEっている場合は、それに合わせた慣れていない。
別の指導、握り拳、葉の価値のFPスタックがなんなのかでquad語サイズの目的地です。
のユーザコードベースのスニペットをこのチェックsrc/luaconf.hからwww.lua.org).ば(いつ)により、速く、確かないワクワクできました。
ああ、 lua_Number
を意味しまいます。:)
/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/
/* On a Pentium, resort to a trick */
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
(defined(__i386) || defined (_M_IX86) || defined(__i386__))
/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)
#define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n)
/* the next trick should work on any Pentium, but sometimes clashes
with a DirectX idiosyncrasy */
#else
union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
#endif
/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
#endif
そして前方一致が必要なと同じ場合に書き込みます i = (int)f
の"C"
まSSE3を使用でき
int convert(float x)
{
int n;
__asm {
fld x
fisttp n // the extra 't' means truncate
}
return n;
}
交互に、SSE2(x64がインラインで組み立てご利用頂けない場合がござ)を使用してい高速:
#include <xmmintrin.h>
int convert(float x)
{
return _mm_cvtt_ss2si(_mm_load_ss(&x)); // extra 't' means truncate
}
古いコンピュータがオプションの設定を丸めモードを手動で行う変換を利用経常 fistp
ました。それだけに配列した浮、そうでないため、充分な注意を払う必要があな使用を構築するということは、コンパイラの変更の丸めモード(鋳造).このようになります:
void Set_Trunc()
{
// cw is a 16-bit register [_ _ _ ic rc1 rc0 pc1 pc0 iem _ pm um om zm dm im]
__asm {
push ax // use stack to store the control word
fnstcw word ptr [esp]
fwait // needed to make sure the control word is there
mov ax, word ptr [esp] // or pop ax ...
or ax, 0xc00 // set both rc bits (alternately "or ah, 0xc")
mov word ptr [esp], ax // ... and push ax
fldcw word ptr [esp]
pop ax
}
}
void convertArray(int *dest, const float *src, int n)
{
Set_Trunc();
__asm {
mov eax, src
mov edx, dest
mov ecx, n // load loop variables
cmp ecx, 0
je bottom // handle zero-length arrays
top:
fld dword ptr [eax]
fistp dword ptr [edx]
loop top // decrement ecx, jump to top
bottom:
}
}
なお、インライン組立のみの作品とMicrosoft Visual Studioのコンパイラ(およびそBorland)、そして書き換えられるGNU組み立てるためにgccコンパイル.のSSE2液intrinsicsできます。
その他の丸めモードによって可能になSSE2intrinsicsまたは手動による設定のFPUの制御言葉を別の丸めモードになります。
なので、しばらく日本にこれだコンパイラ生成の拳ました。にはMSVCってこんな風にしてできるんだ/QIfist, このMSDN概要
また利用をお考えのSSE intrinsicsので、この記事はインテル: http://softwarecommunity.intel.com/articles/eng/2076.htm
以降、MS scews米国のインラインで組み立てにX64力使用intrinsicsんに利用します。 MSDN doc 与 _mm_cvtsd_si64x
例です。
例の作品が決非効率を用いて、unaligned荷重の2倍に、また単一の負荷なく、追加の配置に必要です。そして多くのも負荷の固が生産されており、その除去することができる。て
#include <intrin.h>
#pragma intrinsic(_mm_cvtsd_si64x)
long long _inline double2int(const double &d)
{
return _mm_cvtsd_si64x(*(__m128d*)&d);
}
結果:
i=double2int(d);
000000013F651085 cvtsd2si rax,mmword ptr [rsp+38h]
000000013F65108C mov qword ptr [rsp+28h],rax
の丸めモードの設定可能なインライン組立など
_control87(_RC_NEAR,_MCW_RC);
が四捨五入のための最寄りはデフォルトとにかく).
はるかどうかの質問にセットの丸めモードの各電話とで復元します(第三者lib)についての回答をさせていただき、経験によるものだと考えられます。まを作成してください float.h
のための _control87()
関数.
と、してはいけないので作業が32ビットを用いておこないようにしても、FISTP指導:
_asm fld d
_asm fistp i
一般的には、信頼できる、コンパイラを効率的にするものとする。あなたの圧延により独自の機能も与えられているような気分になるコンパイラです。