Döngü olmayan tamsayılar ile çalışmak için nasıl yapılır

Aşağıdaki kod kolaydır ve beklendiği gibi verilir

KODU:

Option Explicit

Sub Test_loop2()
Dim i As Long
  For i = -3 To 3 Step 1
    Debug.Print i
  Next i
End Sub

ÇIKTI:

enter image description here

Aşağıdaki kod yuvarlama nedeniyle erken çıkılıyor

Option Explicit

Sub Test_loop2()
Dim i As Double
  For i = -0.3 To 0.3 Step 0.1
    Debug.Print i
  Next i
End Sub

ÇIKTI:

enter image description here

Son değerin tamsayı olmayanlar için döngüde çalıştırıldığından emin olmak için For Loop değerini korurken kullanabileceğim en güvenilir yöntem nedir?

Örneğin, i = X - Y arası adım Z - Y'nin Z'nin katı olması durumunda her zaman ulaşılmalıdır

İ = 0 ila 0,3 arası adım 0,1 için 0,3'lük döngüde olacaktır.

İ = 0 ila 0,3 arası adım adım 0,2 için 0,3 döngüde DEĞİL olacaktır

2
-3 ila 3 adım 1, ardından debug.print i/10 için kullanılmaması için herhangi bir sebep var mı?
katma yazar useR, kaynak
Mazeret için programlamada yeniyim, benim fikrim, adım 0.1 ile a'dan b'ye kadar döngü yapmak istiyorsanız, o zaman i/10 yapabilirsiniz, eğer 0.0001 ise i/10000 değil mi?
katma yazar useR, kaynak
Çünkü modellenmekte olan aralık tam sayı değildir ve farklı hassasiyet seviyelerine sahip olabilir. Bir kullanıcı iki rastgele değer arasında 0,1 veya 0,0001 artırmak isteyebilir.
katma yazar pathDongle, kaynak

6 cevap

Floating point arithmetic will eventually screw you if you use a Double (or Single) as counter.

Sayaçlar için tam sayılara sadık kalın. Ardından kayan nokta değerinizi o sayaçtan alın. Örnek:

Dim i As Long
Dim d As Double
For i = 0 To 6
    d = (i - 3) * 0.1 ' or whatever formula needed
    Debug.Print d
Next i
4
katma
Bu sizin için çalıştı mı?
katma yazar Jean-François Corbett, kaynak

Çift olarak döngü sınırları ve sayaç olarak başka bir seçenek

Sub dTest()

    Dim i As Double

    For i = -0.31 To 0.31 Step 0.1

        Debug.Print Round(i, 1)

    Next

End Sub

Sonuç:

-0.3 
-0.2 
-0.1 
 0 
 0.1 
 0.2 
 0.3 
1
katma

Muhtemelen bulduğum en hızlı çözüm Yuvarlak operand'ı kullanmaktı.

Sub Test_loop2()
Dim i As Double
  For i = -0.3 To 0.3 Step 0.1
    Debug.Print Round(i, 1)
  Next i
End Sub
1
katma
Bu işe yaramaz - hala döngü erken çıkar.
katma yazar pathDongle, kaynak

Burada çift eserler yerine ondalık kullanmaya benziyor

Sub Test_loop2()
Dim i As Variant
Dim ffrom As Variant
Dim fto As Variant
Dim fInc As Variant

    ffrom = CDec(-0.3)
    fto = CDec(0.3)
    fInc = CDec(0.1)

  For i = ffrom To fto Step fInc
    Debug.Print i
  Next i
End Sub
0
katma

GD,

Çift (veya Float) değerlerini bir döngüde kullanma problemi, her ikisinin de bir değerin yaklaşık olmasıdır.

Bir mutlak karşılaşmada bir döngü sonunun olması, örneğin:

For i=1 to 5

Döngünün düzgün çalışması için tam olarak 5 olmasını gerektirir, ancak çift veri türü daha sonra For To döngüsünün = 5 gereksinimini karşılamayacak olan 4.999999999 ile 5.000000001 (örneğin) arasında bir şey olabilir. Potansiyel olarak bir seçim yapmayı tercih edebilirsiniz

Do 

'do some code here

Loop Until i>5 

eşik biraz daha belirsiz hale gelirse, bu şamandıra veya çift veri türleri için idealdir.

Normalde @ Jean-François Corbett'in cevabına göre en iyi yöntem, sayaç ve adım değerlerinde yalnızca 'Tamsayı' veya 'Uzun' veri türlerini kullanmak ve kod değişkeniniz için gereken sayma/hesaplama yöntemini ayarlamak için bir formül kullanmaktır.

0
katma

Yukarıda belirtilen kayan noktaların yanlışlık sorununu önlemek için sadece 0,00001 sabit ekledim;

For s = 12 To 19.5 + 0.00001 Step 0.1

Kod, aslen sorunu vurgulayan örnek değerleri gösteriyor, ancak 0.00001 sabiti dışında bunlar değişkenler olabilir. Artışın 0,00001'den az olması durumunda, buna ince ayar yapmanız gerekebilir.

0
katma