Fiyat != Fiyat ?

 

Gelecekte daha iyi kodlayabilmek için gördüğüm garip bir şeyi anlamaya çalışıyorum. . .

Göstergelerimden birinde garip bir şey olduğunu fark ettim, olması gerekeni yapmıyordu, bu yüzden kodu kontrol ettim ve doğru görünüyordu. Bu yüzden küçük bir araştırma yaptım ve küçük bir test Göstergesi oluşturdum.

Esasen bu doğru gibi görünüyor. . .

 double TestValue = iClose ( NULL , 0 , 0 );
   
if (TestValue != NormalizeDouble (TestValue, Digits ) )

. . . bunun nasıl olduğu hakkında bir fikrin var mı?

 
Daha önce soruldu ve cevaplandı
 
RaptorUK :

. . . bunun nasıl olduğu hakkında bir fikrin var mı?

NormalizeDouble()'ın iç işleyişine bağlıdır. Örneğin...

   double TestValue = 1.57373 ;
   if (TestValue != NormalizeDouble (TestValue, 5 )) MessageBox ( "WTF?" );

Aşağıdakileri yaparsanız, tesadüfen aynı sonuçlar:

   double TestValue = StrToDouble ( "1.57373" );
   if (TestValue != NormalizeDouble (TestValue, 5 )) MessageBox ( "WTF?" );

İlk atamadan sonra TestValue = 1.5737300000000000 1 . NormalizeDouble(..., 5) bunun üzerinde 1.57372999999999999 üretir.

 
WHRoeder :
Daha önce soruldu ve cevaplandı
Saygılarımla, bu gönderinin bu konudaki sorunumu yanıtladığını düşünmüyorum.
Bunu yapmanın NormalizeDouble dışında başka yolları olduğunu biliyorum. . . anlamadığım şey, iClose'un neden zaten Normalized olmayan bir değer döndürdüğü. .
 
jjc :

NormalizeDouble()'ın iç işleyişine bağlıdır. Örneğin...

Aşağıdakileri yaparsanız, tesadüfen aynı sonuçlar:

İlk atamadan sonra TestValue = 1.5737300000000000 1 . NormalizeDouble(..., 5) bunun üzerinde 1.57372999999999999 üretir.


Öyleyse TestValue'nin 1.57373 değil > veya < değerine eşit olmasını nasıl sağlayabilirim?
 
RaptorUK :

Öyleyse TestValue'nin 1.57373 değil > veya < değerine eşit olmasını nasıl sağlayabilirim?
Bunun henüz net olmaması durumunda, 1.57373 tam olarak bir kayan nokta değeri olarak temsil edilemez. Aynısı 0.1 gibi değerler için de geçerlidir. Tek tuhaflık, NormalizeDouble() öğesinin MQ4 dilinin diğer bölümlerine farklı bir yaklaşım kullanmasıdır.
 
jjc :
Bunun henüz net olmaması durumunda, 1.57373 tam olarak bir kayan nokta değeri olarak temsil edilemez. Aynısı 0.1 gibi değerler için de geçerlidir. Tek tuhaflık, NormalizeDouble() öğesinin MQ4 dilinin diğer bölümlerine farklı bir yaklaşım kullanmasıdır.

Ah. . hayır net değildi. . Bunu bilmiyordum. Teşekkürler, araştıracağım.
 
RaptorUK :
Ah. . hayır net değildi. . Bunu bilmiyordum. Teşekkürler, araştıracağım.

Kayan nokta değerleri ve aritmetik hızlıdır, çünkü bunlar için doğrudan bilgisayarın işlemcisine yerleşik destek vardır, ancak bazı değerlerin bir kayan nokta değişkeninde tam olarak temsil edilememesi gibi bir ödünleşim vardır. (Hız etkilerinin bir örneği için bkz. https://www.mql5.com/en/forum/116228/page2#156859 ).

Aslında, çiftleri içeren herhangi bir şey bir tür yuvarlama hatasına neden olabilir. Bu, her türlü eğlenceli tuhaflığa yol açar. Örneğin 0.1 * 10 = 1.0, ancak 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 != 1.0

Bunun sonucu, NormalizeDouble(x, y)'nin Round(x, y) ile tam olarak eşanlamlı olmamasıdır. NormalizeDouble(), yuvarlanmış değere mümkün olan en yakın kayan nokta yaklaşımını döndürür. NormalizeDouble(a, n) == NormalizeDouble(b, n) yaparsanız, temelde "a ve b eşittir, kayan nokta aritmetiğinin n'den fazla ondalık basamakta yuvarlama farklılıkları getirebileceği gerçeğine izin verir misiniz?" diyorsunuz.

Birçok kişinin söylediği gibi, NormalizeDouble(a, 5) == NormalizeDouble(b, 5) bu nedenle gerçekte MathAbs(a - b) < 0.00001'e eşdeğerdir ve ikincisi biraz daha hızlı yürütülür. İkincisi de yaygındır çünkü NormalizeDouble() işlevine kullanışlı bir eşdeğer sağlamayan dillerde/platformlarda yaygın olarak kullanılır. Ancak performans farkı o kadar küçük ki, kodunuzu daha okunabilir hale getirdiğini düşünüyorsanız, NormalizeDouble() ile devam edeceğim.

Bütün bunlar, çift veri tipine sahip diller için tamamen normaldir. Bazı tescilli ve tipik MQ4 tuhaflığını tanıtan bit, 1.57373 != NormalizeDouble(1.57373, 5) olmasıdır. NormalizeDouble() kullanmaya karşı 1.57373 sabitini bildirmenin, değerin farklı en iyi-durum kayan nokta yaklaşımlarını seçmesi sapkındır.

 

Teşekkür ederim. :-)

Sorunun farkındaydım ama nedeninin tam olarak farkında değildim ve bu nedenle olası sonuçların tam olarak farkında değildim.

 
sıfır hariç asla çiftleri eşitlik için karşılaştırma
 if (a > b)
 if (a - b > Point / 2 .)
 if (a >= b)
 if (a - b > - Point )
 if (a != b)
 if ( MathAbs (a - b) > Point / 2 .)
 
WHRoeder :
sıfır hariç asla çiftleri eşitlik için karşılaştırma


Tam olarak bunu yaptığım yüzün üzerinde kod satırım var. . . ve NormalizeDouble'ı güvenilir bir şekilde çalışması için görünürdeki hemen hemen her şeyde kullandık . Önerilerinizin arkasındaki fikri anlıyorum, teşekkür ederim, ancak kodumun okunabilirliği ve dolayısıyla gelecekte değişiklik kolaylığı üzerinde olumsuz etkileri olabileceğini düşünüyorum.

Üzerinde çalıştığı grafiğin zaman çerçevesi dışındaki zaman dilimleriyle çalışmasını sağlamak için bu kod bloğunu çok uzak olmayan bir gelecekte değiştireceğim. Bunu yapmaya geldiğimde NormalizeDoubles'ı ortadan kaldırmayı ve başka bir şeyle değiştirmeyi planlıyorum. . . Henüz %100 emin değil, belki karşılaştırmadan önce tamsayılara bir dönüşüm . .

Her zamanki gibi yardımın için teşekkürler :-)