Java'da kayan nokta aritmetiği ve hassasiyeti ile ilgili bir sorum var. Araştırmamı burada ve google üzerinden yaptım ve bazı çözümlere rastladım ama onları tasarımımda uygulamakta zorluk çektim. Yani Java'da hesaplamalarımın doğru olmasını sağlamak için BigDecimal sınıfını kullanıyorum. Değişkenlerin çift olduğunu ve değerlerin hesaplamalar yapılırken sağa doğru 8 ondalık basamağa kadar hassas olabileceğini unutmayın. Gösterilecek sonuç (kesinlik) biliniyor ve şu anki değer olarak saklayacağım şey. Ayrıca, tüm değerler dinamik olarak (bir yöntemle) gelir. Aktarılan argüman currentValue + adım büyüklüğü olmalıdır.Java Kayan Nokta Hassas Sayı
public void newValue(float value) {
//Clip to valid range, can't go over minimum/max value
value = Math.max(minimumValue, Math.min(maximumValue, value));
// TODO Implement better Floating Point Arithmetic precision
MathContext mcI = new MathContext(0, RoundingMode.HALF_UP);
MathContext mcF = new MathContext(8, RoundingMode.HALF_UP);
BigDecimal valueBD = new BigDecimal(value, mcF);
BigDecimal minimumBD = new BigDecimal(minimumValue, mcF);
BigDecimal stepBD = new BigDecimal(step, mcF);
BigDecimal currentValueBD = new BigDecimal(currentValue, mcF);
BigDecimal totalStepsBD = valueBD.subtract(minimumBD, mcF);
//Ensure value is divisible by stepsize
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
valueBD = stepBD.multiply(totalStepsBD, mcF);
valueBD = valueBD.add(minimumBD, mcF);
// arithmetic without using BigDecimal (old)
//int totalSteps = (int) ((value- minimumValue)/ step);
//value = totalSteps * step + minimumValue;
if(!(valueBD.equals(currentValueBD))) {
valueBD = valueBD.setScale(displayPrecision, RoundingMode.HALF_UP);
currentValue = valueBD.floatValue();
dispatch();
}
}
Şimdi, bazı değerlerin hepsi değil çalışır. Özellikle adım büyüklüğü ile uğraştığımda. Yani adım = 0.1 ise iyiydi. Ben 0,005 yapılmış olsa beni AirthmeticException almak istiyorum - olmayan sonlandırma ondalık genişleme
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
.005 bir BigDeciaml (stepBD) yaptıktan sonra, adım değişken için ayarlanmış adım o kadar çıkar üzerine. 0049999999 ... Bunun yardımcı olup olmadığından emin değilsiniz, ancak herhangi bir fikriniz varsa lütfen bana bildirin. Teşekkür ederim.
Sana tanımlayan 'yerde step' görmüyorum kullanmak, bu yüzden tahmin ediyorum o için üye değişkeni var sınıf. Eğer bir "float" tipi ise ve 0.005 olarak atanırsa, .0049999999 veya benzeri bir şey olarak kaydedilir. Daha sonra 'step' değeri olan stepBD'yi atadığınızda, 0.00599 değerini değil, 0.005 değerini kullanır. Bu sorun olup olmadığından emin değil, ancak yardımcı olabilir. – Grice
Not: 'BigDecimal's öğesini karşılaştırmak için' .equals() işlevini kullanmayın; örneğin, '0' ve '0.00' eşit değildir. '.compareTo() işlevini kullanın ve bunun yerine' == 0' seçeneğini işaretleyin. – fge