التحقق من صحة نطاق القيمة المزدوجة والخطوة
-
20-09-2019 - |
سؤال
أحاول إنشاء خوارزمية تؤدي إلى صحة أن القيمة المزدوجة هي عضو في نطاق محدد بقيم Min و Max و Step. المشكلة هي التحقق من أن القيمة تطيع قاعدة الخطوة. بالنسبة للأعداد الصحيحة ، يمكن القيام بذلك بسهولة:
boolean validate(int value, int min, int step, int max){
return value >= min &&
value <= max &&
//Step should be relative to the min value not to 0.
(value-min) % step == 0;
}
هذا ولكن هذا لا يعمل لقيم مزدوجة. أعلم أن هذا جزئيًا على الأقل هو لأسباب دقيقة وحاولت اختراق حل عن طريق ضرب جميع القيم برقم مرتفع للغاية وتحويلها إلى Longs. هذا لم ينجح من أجل كل القيم ، ولم يسمح بانحراف صغير من 0 عند التحقق من الباقي. هل واجه أي شخص هذه المشكلة وتوصل إلى حل جيد؟ فيما يلي مثال واختبار يضم طريقة التحقق من عدم العمل.
تتمثل إحدى طرق القيام بذلك في البدء بقيمة MIN وزيادةها بخطوة حتى تساوي أو أكبر قيمة الإدخال ، ولكن بصرف النظر عن الحل القبيح ، قد يكون هذا عنق الزجاجة المحتملة في تطبيقي ، لذلك أنا حقا تريد تجنب ذلك.
أنا ممتن لأي مؤشرات ...
التحيات / هنريك
public class ValidationExample {
public static void main(String[] args) {
/*Range:
min -10.5
step .3
max -5
*/
//Invalid values
double[] a = {-11,-10.6,-10.4,-10.3,-10.1,-10.0,-9.8,-9.7,
-9.5,-9.4,-9.2,-9.1,-8.9,-8.8,-8.6,-8.5,-8.3,
-8.2,-8,-7.9,-7.7,-7.6,-7.4,-7.3,-7.1,-7.0,
-6.8,-6.7,-6.5,-6.4,-6.2,-6.1,-5.9,-5.8,-5.6,
-5.5,-5.3,-5.2,-5.0,-4.9,-4.8,2};
//Valid values
double[] b = {-10.5,-10.2,-9.9,-9.6,-9.3,-9.0,-8.7,-8.4,
-8.1,-7.8,-7.5,-7.2,-6.9,-6.6,-6.3,-6.0,-5.7,
-5.4,-5.1};
for(double d : a){
if(validate(d,-10.5,.3,-5))
System.err.println(d + " was considered valid.");
}
for(double d : b){
if(!validate(d, -10.5,.3,-5))
System.err.println(d + " was considered invalid");
}
/*
* Range
* min 2
* step .05
* max 3
*/
//Invalid values
double[] c = {1.09,2.055,2.06,2.14,2.16,2.56,2.97,3.05};
//Valid values
double[] e = {2.0,2.05,2.1,2.15,2.2,2.25,2.5,2.75,2.95,3.0};
for(double d : c){
if(validate(d,2,.05,3))
System.err.println(d + " was considered valid.");
}
for(double d : e){
if(!validate(d,2,.05,3))
System.err.println(d + " was considered invalid.");
}
}
private static boolean
validate(double value, double min, double step, double max){
return value >= min &&
value <= max &&
(value - min) % step == 0;
}
}
المحلول
لو value
يتبع قاعدة الخطوة ، ثم (value - min)/step
يجب أن يكون عدد صحيح. لذلك يمكنك التحقق من مدى قربه من أقرب عدد صحيح ، وتحديد ما إذا كانت المسافة مهمة أم لا.
double ratio = (value-min)/step;
double distance = Math.Abs(ratio - Math.Round(ratio,0));
return distance < treshold;
نصائح أخرى
بصرف النظر عن كونك غير أنيق للغاية ، وربما بطيئة ، إضافة step
بشكل مستمر للاقتراب من العدد الذي يتم فحصه سيؤدي إلى حسابات أقل دقة لأن أخطاء النقطة العائمة تميل إلى التراكم.
لا أعرف جافا جيدًا ، لكن الخوارزمية للقيام بذلك هي أن تأخذ النسبة: (value-min)/step
, ، حوله إلى أقرب عدد صحيح n
, ثم احسب v = min+step*n
. لو v
و value
"قريبة بما فيه الكفاية" ، ثم يمكنك وضع علامة value
كما ساري المفعول.
لاختبار قيم "إغلاق بما فيه الكفاية" ، يجب على المرء استخدام تسامح قريب ومطلق. على سبيل المثال ، الحزمة FCMP ينفذ خوارزمية جيدة إلى حد ما لمقارنة قيم الفاصلة العائمة.