جافا:مضيفا مزدوجة.MIN_NORMAL إلى مضاعفة لا تغيير عدد
-
21-12-2019 - |
سؤال
ظننت أن MIN_NORMAL كانت القيمة التي يمكن أن تضيفها إلى "طبيعية" مضاعفة عدد تتغير.E. g.إضافة مزدوجة.MIN_NORMAL إلى 0.1 د و يمكنك الحصول على قيمة مختلفة من 0.1 د غير أن فهمي خاطئ:
public static void test(double val) {
if (val == (val - Double.MIN_NORMAL*1e50d))
System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
else
System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}
والتي تنتج:
test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000
test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000
test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000
شخص الرجاء شرح ما هو ضد المنطق بلدي هنا ، أنه حتى في حالة إضافة MIN_NORMAL مرات 1e50d, أنا لا يزال الحصول على نفس العدد.
راجعت ثنائي التمثيل و 1 * ضعف.MIN_NORMAL مختلفة من 2 * ضعف.MIN_NORMAL ، ولكن طرح تلك من أي شيء ما عدا الصفر لا يتغير العدد الأصلي.
المحلول
MIN_NORMAL
كما جافادوك يقول فقط أصغر تطبيع double
القيمة.ولكن هذا لا يعني أنه هو شيء من هذا القبيل 1
بالنسبة int
s:الفاصلة العائمة نقطة قيم ببساطة لا معيار "eps" يمكنك إضافة إلى تغيير التالي قابل للتمثيل القيمة-أي "eps" يعتمد دائما على الأس من إعطاء قيمة نقطة عائمة.هذا هو السبب في انهم يسمى العائمة نقاط في النهاية :)
ومع ذلك, جافا 1.6+ يوفر Math.nextAfter()
والتي ترجع في أي double
, التالي أو السابق قابل للتمثيل double
.
على كبار السن من إصدارات جافا, يمكنك دائما العبث Double.doubleToLongBits()
, وتزايد أو decrementing نتيجة ، وتحويل يعود Double.longBitsToDouble()
;هذا يحصل لك التالي أو السابق قابل للتمثيل double
القيمة -- في معظم الحالات:هناك بعض الحالات الخاصة (نان, لانهائية القيم) لذا لا ينصح بذلك إلى النقطة العائمة نوبي :)
نصائح أخرى
مزدوج لديه دقة محدودة.Min_Normal هو 2E-1022.سيتم إسقاطها ما لم يكن الرقم الذي تضيفه إليه هو أيضا في Ballpark of 2E-1000.