問題タブ [long-double]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
gcc - long double (GCC 固有) および __float128
long double
GCC/x86 に関する詳細な情報を探しています__float128
(実際の問題というよりは好奇心からです)。
おそらくこれらを必要とする人はほとんどいないでしょう (私は初めて本当にを必要としましたdouble
)。
その観点から、私のややオープンな質問を許してください:
- これらのタイプの実装の根拠と意図された使用法を、相互に比較して誰かが説明できますか? たとえば、標準で型が許可されているため、それらは「恥ずかしい実装」であり、 とまったく同じ精度である
double
場合、またはファーストクラスの型として意図されている場合に誰かが文句を言う可能性がありますか? - または、誰かが共有するための優れた使用可能な Web リファレンスを持っていますか? Google で検索し
"long double" site:gcc.gnu.org/onlinedocs
ても、本当に役立つ情報はあまり得られませんでした。 - 「倍精度が必要だと思うなら、おそらく浮動小数点を理解していない」という共通のマントラが当てはまらないと仮定します。燃え尽きました...パフォーマンスに大きな影響を与えることなく、ジャンプしたり、代わりにジャンプしたりできると期待するのは合理的ですか?
float
long double
__float128
double
- Intel CPU の「拡張精度」機能は、歴史的にメモリとレジスタ間で値が移動されたときに厄介な驚きの原因となってきました。実際に 96 ビットが格納されている場合、
long double
型はこの問題を解消するはずです。一方、SSEには「拡張精度」などがないため、long double
タイプが と相互に排他的であることは理解しています。一方、SSE 数学では完全に正常に動作するはずです (ただし、4 倍精度命令がない場合は、1:1 命令ベースではありません)。私はこれらの仮定で正しいですか?-mfpmath=sse
__float128
(3. と 4. は、プロファイリングと逆アセンブルに費やされたいくつかの作業でおそらく把握できますが、他の誰かが以前に同じ考えを持っていて、すでにその作業を行っている可能性があります。)
背景 (これは TL;DR の部分です):で調べていたので
最初につまずきました。偶然にも次の行にいます。「ああ、GCC には実際には 128 ビットの double があります。私がそれらを必要としているわけではありませんが、...クールだ」というのが私の最初の考えでした。驚き、驚き: 12 を返します... 待って、16 のことですか?long double
DBL_MAX
<float.h>
LDBL_MAX
sizeof(long double)
当然のことながら、C および C++ 標準では、型の具体的な定義が示されていません。C99 (6.2.5 10) は、 の数値double
は のサブセットであると述べていますがlong double
、C++03 は (3.9.1 8) とlong double
少なくとも同じ精度を持っていますdouble
(これは同じことですが、言葉遣いが異なるだけです)。long
基本的には、 、int
、と同様に、標準は実装にすべてを任せていますshort
。
ウィキペディアによると、GCC は「使用されている物理ストレージに関係なく、x86 プロセッサで 80 ビットの拡張精度」を使用しています。
GCC のドキュメントには、すべて同じページに、i386 ABI のために型のサイズが 96 ビットであると記載されていますが、どのオプションでも 80 ビットを超える精度は有効にされません (ハァッ? 何?)、Pentium 以降も同様です。プロセッサは、それらを 128 ビットの数値として整列させたいと考えています。これは 64 ビットでのデフォルトであり、32 ビットで手動で有効にすると、32 ビットのゼロ パディングになります。
テストを実行する時間:
を使用すると、出力はlong double
次のようになります。マークされた数字は一定で、数字が大きくなるにつれて他のすべての数字が最終的に変化します。
これは、80 ビットの数値ではないことを示しています。80 ビットの数値には 18 桁の 16 進数があります。22 桁の 16 進数が変更されていることがわかります。これは、96 ビットの数値 (24 桁の 16 進数) のように見えます。また、触れられていないため、128ビットの数値ではありません。これは、 12を返す0xdeadbeef
ことと一致しています。sizeof
の出力は、__int128
実際には 128 ビットの数値のように見えます。すべてのビットが最終的に反転します。
ドキュメントで示されているように、コンパイルは 32 ビットのゼロ パディングで 128 ビットに揃えられ-m128bit-long-double
ません。long double
どちらも使用していません__int128
が、実際には 128 ビットに合わせて、値をパディング0x7ffdd000
(?!) しているようです。
さらに、は との両方でLDBL_MAX
機能するようです。likeまたはto/fromの数値を加算または減算すると、同じビット パターンが生成されます。
これまで、定数は表現可能な最大数を保持するものではないというのが私の信念でした (明らかにそうではありませんか?)。また、80 ビットの数値が 128 ビットの値と同じように機能する可能性があるかどうかもよくわかりません。1 日の終わりに疲れすぎて、何か間違ったことをしただけかもしれません。+inf
long double
__float128
1.0E100
1.0E2000
LDBL_MAX
foo_MAX
+inf
+inf
c++ - C と C++ における long double と double の違い
重複の可能性:
ロング ダブル vs ダブル
私はプログラミングが初めてで、C と C++ の long double と double の違いを理解できません。Googleで検索してみましたが、理解できず混乱しました。誰でも助けてください。
python - 2 つの「np.longdouble」を合計すると、大きな数値エラーが発生します
おはようございます、
FITS ファイル (単一の数値の整数部分と浮動小数点部分を表す) から 2 つの数値を読み取り、それらを long double (私のマシンでは 128 ビット) に変換してから合計しています。
結果は、128 ビット浮動小数点を使用した場合に期待するほど正確ではありません。コードは次のとおりです。
そして、ここに私が得る答えがあります:
結果は、10 進数 11 桁 (合計で有効桁数 16 桁) の後で、私が期待するもの (55197.0007660185200000000195833) とは異なります。128 ビットの浮動小数点数からは、はるかに優れた精度が期待できます。私は何を間違っていますか?
この結果は、Mac マシンと Linux 32 ビット マシンで再現されました (その場合、dtype は float96 でしたが、値はまったく同じでした)。
よろしくお願いします。
マッテオ
c++ - 長い倍精度の加重確率
私はC++でおよそ2000の要素の配列を扱っています。
各要素は、その要素がランダムに選択される確率を表します。
次に、この配列を累積配列に変換しました。これを使用して、サイコロを振ったときに選択する要素を決定することを目的としています。
配列の例:{1,2,3,4,5}
累積配列の例:{1,3,6,10,15}
数字の3、4、または5が出たときに、累積配列で3を選択できるようにしたいと思います。
追加された複雑さは、私の配列が長いdoubleで構成されていることです。いくつかの連続した要素の例を次に示します。
0.96930161525189592646367317541056252139242133125662803649902343750 0.96941377254127855667142910078837303444743156433105468750000000000 0.96944321382974149711383993199831365927821025252342224121093750000 0.96946143938926617454089618153290075497352518141269683837890625000 0.969
これは、このデータセットを使用して加重確率を実行するためのひどい方法である可能性があるため、これを解決するためのより良い方法の提案を受け入れます。
c - sizeof long double と精度が一致しませんか?
次の C コードを検討してください。
gcc 4.8.1
の下でコンパイルするとUbuntu x64 13.04
、次のように出力されます。
これは、long double の重みが 16 バイトであることを示していますが、小数は 20 位までしか問題ないようです。それはどのように可能ですか?16 バイトはクワッドに対応し、クワッドは 33 から 36 の小数を与えます。
c++ - which compilers give longest long double
I may be doing something very stupid here, but i've reached the limit of what double can achieve and on my compiler (i'm using newest xcode on a mac) long double seems no better.
I've read elsewhere that the length of long double depends on the compiler, if so what would you guys recommend i work with to give the longest long doubl1
c - C で unsigned long long の平方根を簡単に計算するにはどうすればよいですか?
x86アセンブリで64ビット整数の平方根を取得する方法を誰かが探していた別の質問(ここ)を見ていました。
これは非常に単純であることがわかります。解決策は、浮動小数点数に変換し、平方根を計算してから元に戻すことです。
Cで非常に似たようなことをする必要がありますが、同等のものを調べると少し行き詰まります。double を取る sqrt 関数しか見つかりません。double には、重大な丸め誤差を導入せずに大きな 64 ビット整数を格納する精度がありません。
long double
sqrt関数を持つ、使用できる一般的な数学ライブラリはありますか?
c - long double ビット表現へのアクセス
TLDR; 次のコードは、未定義 (または未指定) の動作を呼び出しますか?
私の x86-64 マシンでは、出力はコンパイラに渡された特定の最適化フラグ (gcc-4.8.0、-O0 と -O1) によって異なります。
-O0 を使用すると、
-O1を使用している間、私は得る
最後から 2 行目に余分な 1 があることに注意してください。また、memset の後に印刷命令のコメントを外すと、その 1 が消えます。これは、次の 2 つの事実に依存しているようです。
- long double はパディングされます。つまり、sizeof(long double) = 16 ですが、10 バイトしか使用されません。
- memset への呼び出しが最適化される可能性があります
- long double のパディング ビットは予告なしに変更される可能性があります。つまり、value1 と value2 の浮動小数点演算は、パディング ビットをスクランブルするように見えます。
私はコンパイルして-std=c99 -Wall -Wextra -Wpedantic
いて警告が出ないので、これが厳密なエイリアシング違反のケースであるかどうかはわかりません (しかし、そうかもしれません)。通過-fno-strict-aliasing
しても何も変わりません。
コンテキストは、ここで説明されている HDF5 ライブラリで見つかったバグです。HDF5 は、浮動小数点型のネイティブ ビット表現を把握するために多少の調整を行いますが、パディング ビットがゼロのままでないと混乱します。
そう:
- これは未定義の動作ですか?
- これは厳密なエイリアシング違反ですか?
ありがとう。
編集: これは printme のコードです。あまり注意を払わずにどこかからカット&ペーストしたことを認めます。ここに問題がある場合は、ズボンを下ろしたままテーブルを回ります。