आप Long.MIN_VALUE
और Long.MAX_VALUE
के साथ तुलना कर सकते हैं:
public static boolean fitsLong(double d) {
return d >= Long.MIN_VALUE && d < Long.MAX_VALUE;
}
कुछ अधिक sofisticated दृष्टिकोण BigDecimal
उपयोग करने के लिए है:
double value = 1234567.9;
long l = BigDecimal.valueOf(value)
.setScale(0, RoundingMode.HALF_EVEN)
.longValueExact(); // 1234568
double value = 99999999999999999999999999999999.9;
long l = BigDecimal.valueOf(value)
.setScale(0, RoundingMode.HALF_EVEN)
.longValueExact(); // ArithmeticException
इस तरह से आप कैसे राउंडिंग किया जाता है नियंत्रित कर सकते हैं।
आप पूछ सकते हैं, fitsLong
: d < Long.MAX_VALUE
में सख्त असमानता क्यों है। दरअसल ऐसा इसलिए है क्योंकि Long.MAX_VALUE
को स्वयं को डबल नंबर के रूप में प्रदर्शित नहीं किया जा सकता है। जब आप (double)Long.MAX_VALUE
डालते हैं, तो इसका प्रतिनिधित्व करने के लिए double
प्रकार में पर्याप्त सटीकता नहीं है, इसलिए निकटतम प्रतिनिधित्व योग्य मान चुना गया है जो 9223372036854775808.0
(Long_MAX_VALUE+1.0
) है। तो यह d <= Long.MAX_VALUE
था यह true
संख्या के लिए वापस आ जाएगा जो वास्तव में इस तुलना में थोड़ा बड़ा है Long.MAX_VALUE
निरंतर डबल प्रकार के लिए प्रचारित किया जाता है। दूसरी तरफ को double
प्रकार में बिल्कुल दर्शाया जा सकता है, इस प्रकार हमारे पास >=
है।
इसके अलावा यह दिलचस्प है क्यों निम्नलिखित काम करता है:
double value = -9223372036854775809.9; // Long.MIN_VALUE-1.9
System.out.println(fitsLong(value)); // returns true
क्योंकि आप वास्तव में Long.MIN_VALUE
से कुछ भी घटाना नहीं था कि। देखें:
double d1 = Long.MIN_VALUE;
double d2 = -9223372036854775809.9;
System.out.println(d1 == d2); // true
डबल परिशुद्धता -9223372036854775808
और -9223372036854775809.9
के बीच अंतर करने के लिए पर्याप्त नहीं है, इसलिए यह वास्तव में एक ही डबल संख्या है। संकलन के दौरान इसे बाइनरी रूप में परिवर्तित कर दिया जाता है, और इन दो संख्याओं के लिए बाइनरी रूप समान होता है। इस प्रकार संकलित प्रोग्राम होने पर आप इस बात को अलग नहीं कर सकते कि -9223372036854775808
या -9223372036854775809.9
स्रोत कोड में था या नहीं।
अगर आपको लगता है कि यह अभी भी मुद्दा है, String
से BigDecimal
का निर्माण:
long l = new BigDecimal("-9223372036854775808.2")
.setScale(0, RoundingMode.HALF_EVEN)
.longValueExact(); // ok, -9223372036854775808
long l = new BigDecimal("-9223372036854775808.9")
.setScale(0, RoundingMode.HALF_EVEN)
.longValueExact(); // ArithmeticException
पहले समाधान के लिए) वास्तव में आप नहीं कर सकते। मैंने कोशिश की और यह काम नहीं करेगा। उदाहरण के लिए 922337203685477580 9.9 मान का प्रयास करें जो 2.9 तक Long.MAX_VALUE बढ़ाया गया है। यह सफल हो जाएगा। – arenaq
आप सही हैं, लेकिन जब मैं दोनों समाधानों के लिए 9 223372036854775807.0 का उपयोग करता हूं। FitsLong मुझे सच देता है और BigDecimal एक अपवाद फेंकता है। वह डबल मान अपरिवर्तित हो सकता है, लेकिन कम से कम समाधानों में से एक गलत होना चाहिए। – arenaq
@arenaq डबल में 53 बिट्स मंथिसा है और यह केवल 15-17 अंकों के लिए सटीक हो सकता है। 9223372036854775809.9 और 9 223372036854775807 http://stackoverflow.com/q/588004/995714 –