MQL4およびMQL5でDigits()をバイパスして任意の数値(引用符だけでなく)の小数点以下桁数を取得 - ページ 22

 
Andrey Khatimlianskii:

必要ない

口が達者なんですね...?

ここに10000個の要素を持つ配列があります。完全にランダム化され、各ソートサイクルの前にランダム化されます。各方法を1000回繰り返した場合の総時間(ms)。

内蔵のArraySort、数日前に書いた私のメソッド(それ以前はソートアルゴリズムは 全くやっていなかった)、そしてあなたのライブラリから6つのベストメソッド(残りはもっと悪かった)、一方で私はそこからグラフィックスに関連するものを全て削除しました...。

#include <Sort\GSort.mqh>
#define    ttt                 template<typename T>
#define    test(M,S,EX)        {uint mss=GetTickCount();int nn=(int)pow(10,M);for(int tst=0;tst<nn&&!_StopFlag;tst++){EX;} \
                                printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}


ttt void a_rand(T&ar[]){for(int i=0;i<ArraySize(ar);i++)ar[i]=T(rand()*rand());}

ttt int TreePop(T&t[],T&ar[],int i=0,int b=0)
 {
  if(t[b+1]>=0)i=TreePop(t,ar,i,(int)t[b+1]);
  ar[i++]=t[b];
  if(t[b+2]>=0)i=TreePop(t,ar,i,(int)t[b+2]);
  return i;
 }

ttt void TreeSort(T&ar[])
 {
  int sz=ArrayRange(ar,0);
  T t[];ArrayResize(t,sz*3);ArrayInitialize(t,-1);
  for(int i=0;i<ArraySize(ar);i++){t[i*3]=ar[i];
    if(!i)continue;
    int b=0;
    while(1)
      if(ar[i]<=t[b])
        if(t[b+1]>=0)b=(int)t[b+1];
        else{t[b+1]=i*3;break;}
      else
        if(t[b+2]>=0)b=(int)t[b+2];
        else{t[b+2]=i*3;break;}}
  TreePop(t,ar);
 }


void OnStart(){
  double ar[];
  int N=10000,k=3;
  ArrayResize(ar,N);

  test(k,"ArraySort(MQL5)",a_rand(ar);ArraySort(ar))
  test(k,"TreeSort(AntFX)",a_rand(ar);TreeSort(ar))
  test(k,"Merge(GSort)",a_rand(ar);GMergesort(ar,0,N-1))
  test(k,"QTernaryLL(GSort)",a_rand(ar);GQSortTernaryLL(ar,0,N-1))
  test(k,"QSortLL(GSort)",a_rand(ar);GQSortTernaryLL(ar,0,N-1))
  test(k,"QSort(GSort)",a_rand(ar);GQSortTernaryLR(ar,0,N-1))
  test(k,"QTernaryLR(GSort)",a_rand(ar);GQSortTernaryLR(ar,0,N-1))
  test(k,"Comb(GSort)",a_rand(ar);GComb(ar))
}
 
Ilya Malev:

口が達者なんですね...?

ここに10000個の要素を持つ配列があります。完全にランダム化され、各ソートサイクルの前にランダム化されます。各方法を1000回繰り返した場合の総時間(ms)。

内蔵のArraySort、数日前に書いた私のメソッド(それ以前はソートアルゴリズムは全くやっていなかった)、そしてあなたのライブラリから6つのベストメソッド(残りはもっと悪かった)、一方私はそこからグラフィックスに関連するものを全て削除しました...。

記事の動画から判断すると、速いのは伯爵、LSD、MSDです。

 
Andrey Khatimlianskii:

記事中の動画から判断すると、速いのは伯爵、LSD、MSDです。

これらのパスが完成するのを待つことはなかった。

 
Alexandr Sokolov:

小数点以下の桁数を取得する必要があり、Digits()関数が 引用符でしか動作せず、しかもどこにも情報がない(少なくともこの記事を書いている時点では、今まで見つけられなかったので、どんな解決策があるかを紹介したい)という珍しい状況に陥ったのは、私だけではないと思うんです。


それは、判明したように、平凡な単純な本質が、まだ1つの欠点を持っている - それらの後に他の数字がない場合、この関数は、ゼロを認識しません。例えば、この関数は0.01が続くと2を返しますが、0.0000が続くと0を返します(これは4つのゼロを見ることができないことを意味します)。だから、この欠点を考慮して開発を進めてください。


MQL4でのコード


MQL5でのコード

MQL5ではdouble型の変数は整数であろうとなかろうと、最後に自動的に0が代入されるらしいので、このコードを少し改良する必要があった。そして、このような理由から、この関数は0を返したことがないのです。

このトピックが関連するのであれば、私の例を紹介します。

int kol_Z(double zzz) { // 小数点以下の桁数を計算する。

文字列 a、d。
int b, c;
a=StringFormat("%g", zzz)とする。
b=StringFind(a,".",0)とする。
c=StringLen(a)とする。
if (b==-1) return(0);
d=StringSubstr(a,b+1)とする。
return(StringLen(d))とする。
}
 
NomadSoul:

という話題であれば、以下のように考えて います。

void OnStart()
{
    Print(kol_Z(1.001234));
}

結果:5、6となるべきところ

 
A100:

結果:6であるべきところを5とした。

小数点以下の数を 数える一番簡単な方法は?」というテーマと同じです。コンピュータに、仮数の長さに切り捨てるよう要求された数字を与えたとき、その無限周期分数の終わりはどこかと尋ねると、どうなるのだろう。

0.00011001100110011(0011)は2進数表現で10進数の0.1です。無限小数の周期部分は括弧内にある。では、無限の数の最初の有効数字52桁だけを2重に記憶している場合、コンピュータはどう答えるべきなのだろうか。

非常に短い3進数の0.1を10進数で表現すると(0.33333...)、小数点以下の有効桁数が無限になることに驚く人はいないでしょう。2進法0.1は、幸せな事故によって桁数の有限な10進法0.5と等しく、表記システム2と10の2つのベースに共通の約数を発見し、削減、それは2である。0.5 => 0.1; 0.05 => 0.01 ; 0.025 => 0.001 ; 0.0125 => 0.0001 と、どちらの表現でも半分の度合いも良い感じです。しかし、分数の分母に5が登場したとたん、それこそ有効数字がたくさん出てきてしまうのです。

分数部の有効桁数は、数値の値だけでなく、表現に使用する文字数にも関係する。

Самый простой способ посчитать количество знаков после запятой?
Самый простой способ посчитать количество знаков после запятой?
  • 2021.01.18
  • www.mql5.com
Есть переменная. Например: double а=0.02; Нужно написать функцию, которая считала бы количество знаков после запятой...
 

1

3回ほど実行しました。リーダーの息がかかっている...。もし必要な人がいたら、ここの関数はhttps://www.mql5.com/ru/code/904、 関数名はSortHoareUpです。

 
Dmitry Fedoseev:

3回ほど実行しました。リーダーの息がかかっている...。必要な人がいれば、ここの関数はhttps://www.mql5.com/ru/code/904、 関数名はSortHoareUpです。

また、ライブラリ(#include <MathStatMath.mqh>)からMathQuickSort() を利用することも可能です。非常に高速なライブラリだと書いている記事があったように記憶しています)。

スピードは測っていませんが、主にソース配列のインデックスを配列で保存できるため使っています。

 
Vladimir:

小数点以下の数を 数える一番簡単な方法は?」と本質的に同じトピックです。コンピュータに、仮数の長さに切り捨てなければならない数字を与えたとき、その無限周期分数の終わりはどこかと、どうして聞けるのだろう。

0.00011001100110011(0011)は2進数表現で10進数の0.1です。無限小数の周期部分は括弧内にある。では、無限の数の最初の有効数字52桁だけを2重に記憶している場合、コンピュータはどう答えるべきなのだろうか。

非常に短い3進数の0.1を10進数で表現すると(0.33333...)、小数点以下の有効桁数が無限になることに驚く人はいないでしょう。2進法0.1は、幸せな事故によって桁数の有限な10進法0.5と等しく、表記システム2と10の2つのベースに共通の約数を発見し、削減、それは2である。0.5 => 0.1; 0.05 => 0.01 ; 0.025 => 0.001 ; 0.0125 => 0.0001 と、どちらの表現でも半分の度合いも良い感じです。しかし、分数の分母に5が登場したとたん、それこそ有効数字がたくさん出てきてしまうのです。

分数部の有効桁数は、数値の値だけでなく、表現に使用する桁数にも関係する。

まず、解決すべき問題の条件を定義しておくとよいでしょう。もし、コンピュータにおける数表記の理論的研究のようなものを言うのであれば、この研究の目的をさらに明確にする必要がある。

もし、NormalizeDouble()関数の第2引数にどの整数を与えるかという質問であれば、同じ関数を使って答えを見つけなければなりません。正規化された数値がソース数値と等しくなる、0から8までの最小の整数になります。そのような整数が見つからない場合は、ソース番号が正しくありません。ここでは、最小音量ステップの桁数をカウントするコード 例を示します。