3

0.011124325465476454MATLAB で数値を文字列に変換したいとします。

当たったら

mat2str(0.011124325465476454,100)

0.011124325465476453最後の桁が異なるものを取得します。

当たったらnum2str(0.011124325465476454,'%5.25f')

私は得る0.0111243254654764530000000

望ましくないゼロが埋め込まれており、最後の桁が異なります (3 は 4 のはずです)。

乱数の小数を含む数値を正確な文字列一致に変換する方法が必要です (ゼロが埋め込まれておらず、最後の数字が変更されていません)。

そのような方法はありますか?

編集: Amro と nrz が提供した精度に関する情報を念頭に置いていないので、問題に関する追加情報を追加します。実際に変換する必要がある数値は、それらを txt ファイルに出力する C++ プログラムからのものであり、それらはすべて C++double型です。[注: txt ファイルから MATLAB に数値を入力する部分は、私がコーディングしたものではなく、数値に変換せずに数値を文字列として保持するように変更することは実際には許可されていません。変換したい数値であるこのコードの「出力」にのみアクセスできます]。これまでのところ、小数点以下 17 桁を超える数値は取得していません (注: したがって、上記の例は小数点以下 18 桁であり、あまり参考にはなりません)。

ここで、番号が 15 桁の場合、たとえば 0.280783055069002

その後num2str(0.280783055069002,'%5.17f')またはmat2str(0.280783055069002,17)戻ります

0.28078305506900197

これは正確な数ではありません (最後の数字を参照)。

しかし、私がヒットした場合、私 mat2str(0.280783055069002,15)は得ます

0.280783055069002どちらが正しい!!!

おそらく、問題を「コード化」する方法は無数にあります (たとえば、変換を行うルーチンを作成するなど)。 10 進数 (ただし 17 を超えない);

4

4 に答える 4

4

私のHPFツールボックスでは、MATLABで任意精度の数値を操作することもできます。

MATLABで、これを試してください。

>> format long g
>> x = 0.280783054
x =
               0.280783054

ご覧のとおり、MATLABはあなたが提示した数字でそれを書き出します。しかし、MATLABはその数について実際にどのように「感じ」ているのでしょうか。内部に何を保存しますか?sprintfの言うことを見てください:

>> sprintf('%.60f',x)
ans =
0.280783053999999976380053112734458409249782562255859375000000

そしてこれは、HPFがdoubleからその数を抽出しようとしたときに見られるものです。

>> hpf(x,60)
ans =
0.280783053999999976380053112734458409249782562255859375000000

実際、ほとんどすべての10進数は、浮動小数点演算でdoubleとして正確に表現できるわけではありません。(明らかな理由から、0.5または0.375はその規則の例外です。)

ただし、18桁の10進数形式で格納する場合、HPFは10進数形式の2進近似として数値を格納する必要がないことがわかります。

x = hpf('0.280783054',[18 0])
x =
0.280783054

>> x.mantissa
ans =
  2 8 0 7 8 3 0 5 4 0 0 0 0 0 0 0 0 0

nielsが認めていないのは、10進数がdoubleとして10進数形式で格納されないことです。たとえば、0.1は内部的にどのように見えますか?

>> sprintf('%.60f',0.1)
ans =
0.100000000000000005551115123125782702118158340454101562500000

ご覧のとおり、matlabは0.1として保存しません。実際、matlabは0.1を2進数として格納しますが、ここでは事実上...

1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 + ...

またはあなたが望むなら

2^-4 + 2^-5 + 2^-8 + 2^-9 + 2^-12 + 2^13 + 2^-16 + ...

0.1を正確に表すには、0.1は2進数の繰り返し数であるため、このような用語は無限に多くなります。MATLABは52ビットで停止します。2/3 = 0.6666666666 ...の小数と同様に、0.1は近似値としてのみdoubleとして格納されます。

これが、あなたの問題が本当に完全に精度とdoubleが構成するバイナリ形式に関するものである理由です。

チャット後の最終編集として...

重要なのは、MATLABが数値を表すためにdoubleを使用することです。したがって、小数点以下15桁までの数値を取り込んで、適切なフォーマット設定でそれらを吐き出すことができます。

>> format long g
>> eps 
ans = 
2.22044604925031e-16

たとえば...

>> x = 1.23456789012345
x =
          1.23456789012345

そして、MATLABがそれを正しく理解していることがわかります。ただし、最後にもう1桁追加します。

>> x = 1.234567890123456
x =
          1.23456789012346

MATLABが見ているように、その栄光の中でxを見てください。

>> sprintf('%.60f',x)
ans =
1.234567890123456024298320699017494916915893554687500000000000

したがって、浮動小数点数の最後の桁には常に注意してください。MATLABは物事をインテリジェントに丸めようとしますが、15桁は安全な場所の端にあります。

このような問題を解決するには、HPFやMPなどのツールを使用する必要がありますか?いいえ、ダブルの制限を認識している限り。ただし、任意精度を提供するツールを使用すると、必要なときに柔軟に対応できます。たとえば、HPFは、その地下室の保護桁の使用と制御を提供します。あなたがそれらを必要とするならば、それらはあなたが腐敗からあなたが必要とする数字を救うためにそこにあります。

于 2012-06-05T23:38:42.407 に答える
0

任意精度の数値には、MATLAB File Exchange の Multiple Precision Toolkitを使用できます。浮動小数点数は通常、正確な 10 進数表現を持ちません。

于 2012-06-05T20:12:09.993 に答える
0

That's because your number is beyond the precision of the double numeric type (it gives you between 15 to 17 significant decimal digits). In your case, it is rounded to the nearest representable number as soon as the literal is evaluated.

If you need more precision than what the double-precision floating-points provides, store the numbers in strings, or use arbitrary-precision libraries. For example use the Symbolic Toolbox:

sym('0.0111243254654764549999999')
于 2012-06-05T20:29:08.943 に答える
0

数値は double 型、または long double 型で格納されているため、EXACT 文字列を取得することはできません。保存される数値は、指定した数値よりも多少異なります。

コンピュータは 2 進数の 0 と 1 しか認識していません。ある基数の数値が他の基数で同じように表現されない場合があることを知っておく必要があります。たとえば、数値 1/3、基数 10 は 0.33333333 を生成します... (省略記号 (3 つのドット) は、さらに数字が続くことを示します。ここでは数字 3 です)、0.333333 に切り捨てられます。基数 3 は 0.10000000 を返します。多かれ少なかれ正確な量を参照してください。基数 2 は 0.01010101... を生成するため、コンピューターでは 0.01010101 に切り捨てられる可能性があります。これは 85/256 であり、丸めによって 1/3 未満になり、次に数値をフェッチするときに、必要な数値とは異なります

したがって、最初から数値を浮動小数点型ではなく文字列に格納する必要があります。そうしないと、精度が失われます。

精度の問題を考慮して、MATLAB は任意精度のシンボリック計算を提供します。

于 2012-06-06T05:08:17.563 に答える