問題タブ [strtod]
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.
c++ - C++ は文字列を倍精度で倍精度に変換します
文字列を最大 15 桁の精度で double に変換する必要があります
私は多くの記事や同様の質問を読みましたが、数値を画面に出力するときに setprecision(15) を使用することを提案しました。
例えば:
私が書くなら
34.9438553 ではなく 34.9439 のみが出力されます。
私は書くことができた
それは機能しますが、変数を画面に出力するときだけでなく、変数内の数値全体が必要なため、変数 lon1 自体に 15 桁の精度が必要です。
誰もそれを行う方法を知っていますか?
c - GNU C: atof()、strtof()、および strtod() が失敗する (BeagleBoard の Debian)
strtod(...) を使用して ASCII 文字列を double に変換する C コードがあります。このプログラムは、x86 (デバッグ)、ARM、および PowerPC (組み込みターゲット システム) 用にコンパイルされます。ARM ボードは、実際には利用可能な Debian を実行する BeagleBoard xM です。
strtod() が ARM/Debian システムで値を正しく変換しないことを発見しました。実際、私が試したすべての値は 0.000 でした。
実証するために、次の非常に単純なテスト プログラムを作成しました。
すべては、Ubuntu を実行している x86 PC (実際には仮想マシン内) でコンパイルされました。PowerPC および ARM コンパイル用のクロスコンパイラ ツールチェーンがあります。
x86 および PowerPC システムでは、出力は期待どおりです。つまり、次のようになります。
ただし、BeagleBoard で実行すると、次のようになります。
は???私は愚かなことを見逃しましたか?「myEnd」ポインターは、strtod() と strtof() が最初の非数値文字を検出したこと、つまり数値の末尾を検出したことを示すためにあることに注意してください。どちらの場合も数値の正しい文字数を報告しますが (3)、変換された値は間違っています。混乱する小数点がないので、ロケールの問題ではないと思います。
編集:
オプション「-static」を使用してテストプログラムを再コンパイルしました。もちろん、これによりバイナリははるかに大きくなりましたが、ターゲットの ARM プラットフォームで正しく動作するようになりました。
ライブラリの仕組みについて、私は少しぼんやりしています。また、クロス コンパイラ ツールチェーンをどのように構築したかを正確に思い出せません。おそらく、ターゲット ボードに実際にインストールされている Debian Linux と同じソースからビルドされたものではありません。
では、atof() などの不可解な動作は、動的にリンクされた実行可能ファイルによって「期待される」ライブラリが、システム上の実際のライブラリと同じではないことを意味しますか? これがより悪い問題を引き起こさなかったことに驚いています。このシステムを 1 年間運用してきましたが、これまでに遭遇した奇妙なバグはこれだけです。
c - `strtod("3ex", &end)` の結果はどうなる? sscanf は?
私の実験では、この表現
で初期化d
し、入力文字列内の文字にポインターを3.0
置きます。これはまさに私が期待する動作と同じです。文字は指数部の先頭に見えるかもしれませんが、実際の指数値 (6.4.4.2 で必要) がないため、完全に独立した文字として扱う必要があります。end
'e'
'e'
'e'
しかし、私がするとき
フォーマット指定子のとのsscanf
両方を消費していることに気付きました。変数は値を受け取ります。変数はその中で終わります。これは、2 つの理由から私には奇妙に見えます。'3'
'e'
%lf
d
3.0
c
'x'
まず、言語仕様は書式指定子strtod
の振る舞いを記述するときに参照するので、%f
直感的%lf
に入力を同じように扱うstrtod
(つまり、終点と同じ位置を選ぶ) ことを期待しました。scanf
ただし、歴史的には、入力ストリームに返される文字は 1 つだけであると想定されていたことを知っています。scanf
これにより、1 文字で実行できる先読みの距離が制限されます。上記の例では、少なくとも 2 文字の先読みが必要です。したがって、入力ストリームからと の両方を%lf
消費したという事実を受け入れるとしましょう。'3'
'e'
しかし、次に 2 番目の問題に直面します。それを typesscanf
に変換する必要があります。浮動小数点定数の有効な表現ではありません (6.4.4.2 によれば、指数値はオプションではありません)。私はこの入力を間違ったものとして扱うことを期待しています:変換中に終了し、戻ってそのままにし、 変更しません。ただし、上記は正常に完了します ( を返します)。"3e"
double
"3e"
sscanf
%lf
0
d
c
sscanf
2
この動作は、標準ライブラリの GCC 実装と MSVC 実装の間で一貫しています。
したがって、私の質問は、C 言語標準ドキュメントのどこでsscanf
、上記の 2 つの点を参照して、上記のように動作することが許可さstrtod
れている"3e"
かということです。
私の実験結果を見ると、おそらくsscanf
の動作を「リバース エンジニアリング」することができstrtod
ます。そのようにして、'e'
によって消費され%lf
、無視されstrtod
ます。しかし、言語仕様にはそれだけでしたか?
c - 文字列がゼロの場合の strtod() の戻り値
MSDN によると:
strtod
変換を実行できない場合、またはアンダーフローが発生した場合は 0 を返します。
文字列がゼロ (つまり 0.0000) の場合はどうなりますか? 変換にエラーがないことを確認するにはどうすればよいですか?
OK、次のコードを使用してアイデアを検証します。
MyNum = 0 であることがわかりますが、Y の内容が MyEnPtr にコピーされたり、この強制エラーで errno = 0 になったりすることはありません。何か案が?
c++ - strtod 0 がエラーか適切な値かを確認する方法
string を double に変換したいと思います。私はこのようにします:
値が0の場合、結果が正常かどうかを確認するにはどうすればよいですか? たとえば、string("0") を送信すると 0 が返されますが、これはエラーではありません。しかし、他の文字列、つまり数値を送信することもできますが、変換されず、0 (エラー) も返されます ( *end == 0 の場合について話しています)。