Hatalar, hatalar, sorular - sayfa 711

 
sergeev :
sınıfları kullanın.

Evet kesinlikle. Fark etmedim. Ben bile zaten hatırlıyorum, bir kez istendi.

İşte böyle oldu:

 struct Buff { double b[]; };
//---
Buff lbuff[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   int i= 2 ,j= 1000 ;
//---
   ArrayResize (lbuff,i);
   ArrayResize (lbuff[ 0 ].b,j);
   ArrayResize (lbuff[ 1 ].b,j);
  }
Roş :
CMatrix sınıfı için bir örnek için Aşırı Yükleme İşlemleri bölümüne bakın, belki bu size uyacaktır.
Teşekkürler, çalışacağım.
 
Rosh :

Gerçek şu ki, gerçek bir sayı , 17'den fazla anlamlı basamak olmadan bellekte saklanır.

Farkı hissetmek için bu örneği deneyin:

Kılavuzdaki açıklama düzeltilecektir.

Evet, Renat yukarıda, Print() 'in çift tipteki verileri noktadan sonra 16 ondalık basamağa kadar değil, 4 doğrulukla yazdırdığını zaten açıklamıştı. Bu, kullanıcının bakış açısından tüm engeldi.

 
Yedelkin :

Evet, Renat yukarıda, Print() 'in çift tipteki verileri noktadan sonra 16 ondalık basamağa kadar değil, 4 doğrulukla yazdırdığını zaten açıklamıştı. Bu, kullanıcının bakış açısından tüm engeldi.

Hayır, Print() çıktısı %.16G biçimindedir; bu, noktalı ve 16 anlamlı basamaklı bir sayıyı yazdırmaya çalışılacağı anlamına gelir. Bu durumda, 17 anlamlı sayı (ondalık noktasından önce 3 basamak + ondalık noktasından sonra 14) olan 199,999999999999997 sayısı kaydedilir. 16 hane görüntülemeye çalıştığınızda yuvarlama başlar, 7 10'a yuvarlanır, birim daha yüksek bir haneye gider ve orada 9 olur. Ve domino ilkesi başlar - çıktı sayısı 200'e yuvarlanır.

İşte bir örnek deneyin:

 void OnStart ()
  {
   double a,b;

   a= 7.0 / 200.0 ;
   b= 7.0 /a;
   Print ( "Print(b)=" ,b);
   Print ( "Print(DoubleToString(b,16))=" , DoubleToString (b, 16 ));
   double epsilon= MathPow ( 10 ,- 13 );
   Print ( "-------- После вычитания " ,epsilon, "---------" );
   b=b-epsilon;
   Print ( "Print(b)=" ,b);
   Print ( "Print(DoubleToString(b,16))=" , DoubleToString (b, 16 ));

   
  }

PrintFormat()'a bakın.

 
Rosh :

Hayır, Print() çıktısı %.16G biçimindedir; bu, noktalı ve 16 anlamlı basamaklı bir sayıyı yazdırmaya çalışılacağı anlamına gelir. Bu durumda, 17 anlamlı sayı (ondalık noktasından önce 3 basamak + ondalık noktasından sonra 14) olan 199,999999999999997 sayısı kaydedilir. 16 hane görüntülemeye çalıştığınızda yuvarlama başlar, 7 10'a yuvarlanır, birim daha yüksek bir haneye gider ve orada 9 olur. Ve domino ilkesi başlar - çıktı sayısı 200'e yuvarlanır.

PrintFormat()'a bakın.

Şimdi, vurgunun neden depolanan önemli sayıların sayısı üzerinde olduğu açıktır.

... Ancak, bellekte 17'den fazla olmayan anlamlı basamakla (bizim durumumuzda, 199,99999999999999997 sayısı) gerçek bir sayı saklanıyorsa , bu dönüşümle anlamlı basamaklar nereden geliyor:

MP 0 victorg2 (EURUSD,M1) 11:04:42 Print(DoubleToString(b,16))= 199,99999999999997 16

? (19 bit sayıldı)
 

"Savaş koşullarında pi sayısı dörde ulaşabilir"

DoubleToString, baskıda biçimlendirmeden biraz farklı çalışır (burada CRT'nin insafına kalmıştır)

DoubleToString'de, tamsayı ve kesirli kısımlar ayrı ayrı ve standart biçimlendirmeden biraz daha hızlı bir algoritma kullanılarak dizelere dönüştürülür.

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo :

DoubleToString'de, tamsayı ve kesirli kısımlar ayrı ayrı ve standart biçimlendirmeden biraz daha hızlı bir algoritma kullanılarak dizelere dönüştürülür.

Ama sonra , bellekte 17 anlamlı basamağın biraz daha fazlasının saklandığı ortaya çıktı. Aksi takdirde, dizelere dönüştürme için tamsayı ve kesirli kısımlar nereden gelecek? Yani, Print() veya DoubleToString() olsun, verilerini bir yerden alırlar ("bellekte 17'den fazla olmayan anlamlı basamakla" depolamaktan bahsediyorsak).

... "Belki de "bellekte saklama" tabirine takılmış olabilirim ve gerçek sayıları saklamanın doğası hakkında bilgi sahibi olmadığım için tam olarak doğru anlamıyorum.

 
Yedelkin :

Ama sonra , bellekte 17 anlamlı basamağın biraz daha fazlasının saklandığı ortaya çıktı. Aksi takdirde, dizelere dönüştürme için tamsayı ve kesirli kısımlar nereden gelecek? Yani, Print() veya DoubleToString() olsun, verilerini bir yerden alırlar ("bellekte 17'den fazla olmayan anlamlı basamakla" depolamaktan bahsediyorsak).

... "Belki de "bellekte saklama" tabirine takılmış olabilirim ve gerçek sayıları saklamanın doğası hakkında bilgi sahibi olmadığım için tam olarak doğru anlamıyorum.

20 önemli basamağa kadar saklanır, ancak garanti edilmez. Ve genel olarak, tamsayı kısmındaki sayı ne kadar büyükse, kesirli kısımda o kadar az doğrudur.

Neden 16 ondalık basamağa ihtiyacınız var? Akademik ilgi?

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo :

20 önemli basamağa kadar saklanır, ancak garanti edilmez. Ve genel olarak, tamsayı kısmındaki sayı ne kadar büyükse, kesirli kısımda o kadar az doğrudur.

Neden 16 ondalık basamağa ihtiyacınız var? Akademik ilgi?

:) Hasarlı bir telefonu oynatmamak için arka plana bir bakalım.

Burada victorg , Print() fonksiyonunun çalışması ve ürettiği beklenmeyen değerler ile ilgili bir soru sordu .

İşte ona nedenini gösterdim .

Print() fonksiyonunun söveleri ile uğraşmak istemediği için ,

Print() işlevinin açıklamasının " Çift veri, noktadan sonra 16 ondalık basamak doğruluğuyla yazdırılır" dediğini belirtme özgürlüğünü kullandım. Aslında, Print() işlevinin somut bir örnek eklenmiş olarak biraz yuvarlatılmış veri çıktısı verdiği ortaya çıktı.

Sonra hararetli bir tartışma başladı, sonuç olarak kimse benim örneğimi çürütemedi ve Renat ilk versiyonu özetledi ve referans kitabının düzeltileceğini söyledi .

Birkaç gün sonra Rosch, 17 sayısından bahsedildiğinin ortaya çıktığı ikinci versiyonu dile getirdi ve burada devam etti .

Tartışmaya katılarak üçüncü bir sürüm önerdiniz, yani: " DoubleToString'de tamsayı ve kesirli kısımlar ayrı ayrı dizgelere dönüştürülür ve standart biçimlendirmeden biraz daha hızlı bir algoritma kullanılarak " yani. mesele zaten algoritma hızında çıktı.

Ardından, genel olarak, Roche'un ikinci versiyonundan saklanan numaranın boyutuyla ilgili olduğuna dikkatinizi çektim.

dize :

Neden 16 ondalık basamağa ihtiyacınız var? Akademik ilgi?

Şimdi bu soruları cevaplayabiliriz. Print() fonksiyonu yuvarlak veri verdiğinde bir örnek verdim. Bu tür davranışların nedenlerini sormadım. Örneğim reddedilmedi, sadece başka bir işlev kullanmamı tavsiye ettiler ve nedenlerini açıklamaya başladılar. Bu açıklamalar arasında 16 (17) ondalık basamaktan bahsedilmiştir. Bu açıklamalardaki her şeyi anlamadığım için yol boyunca sorular sordum. - Yani bu benim açımdan akademik bir ilgi bile değil, sadece bana hangi fikri iletmeye çalıştıklarını anlama arzusu.

 
Yedelkin :

. . . Yani bu benim açımdan akademik bir ilgi bile değil, sadece bana hangi fikri iletmeye çalıştıklarını anlama arzusu.

Tamamen katılıyorum. Akademik ilginin bununla hiçbir ilgisi yoktur.

" gerçek sayı " belgelerinde okuduk. IEEE 754 standardı, çift kişilik tabloda – 15 önemli rakam. Bunu akılda tutarak, dört seçenek zaten birikmiştir - 15, 16, 17 anlamlı basamak ve tamsayı kısmı ve kesirli ayrı ayrı depolandığındaki seçenek. Ama bu olmaz! Buradaki akademik ilgi nedir? Burada, bu arada, bu programlama dilinin dayandığı temel biçimsel mantık.

Bana öyle geliyor ki bir programcı program yazmalı, derleyici araştırmamalı.

not

Bu fırsatı açıklığa kavuşturmak için kullanmak istiyorum:

ArrayResize () işleviyle dinamik bir dizinin boyutunu artırırsanız, daha önce içine yerleştirilen verilerin kaydedileceği garanti edilir mi? Muhtemelen, bu nokta belgelere açıkça yansıtılmalıdır (ArrayResize() işlevinin açıklamasında). Eger birisi biliyorsa lutfen bana soylesin.

 
victorg :

ArrayResize () işleviyle dinamik bir dizinin boyutunu artırırsanız, daha önce içine yerleştirilen verilerin kaydedileceği garanti edilir mi? Muhtemelen, bu nokta belgelere açıkça yansıtılmalıdır (ArrayResize() işlevinin açıklamasında). Eger birisi biliyorsa lutfen bana soylesin.

Boyutu arttırırken olacaktır, aksi takdirde böyle bir işlevin anlamı yoktur.