यह कोड:
System.out.println(Math.abs(Integer.MIN_VALUE));
रिटर्न -2147483648
क्या इसे पूर्ण मान के रूप में वापस नहीं करना चाहिए 2147483648?
यह कोड:
System.out.println(Math.abs(Integer.MIN_VALUE));
रिटर्न -2147483648
क्या इसे पूर्ण मान के रूप में वापस नहीं करना चाहिए 2147483648?
जवाबों:
Integer.MIN_VALUEहै -2147483648, लेकिन एक 32 बिट पूर्णांक शामिल कर सकते हैं उच्चतम मूल्य है +2147483647। +2147483648प्रभावी ढंग से "रोल ओवर" करने के लिए एक 32 बिट इंट में प्रतिनिधित्व करने का प्रयास किया जाएगा -2147483648। इसका कारण यह है कि जब हस्ताक्षर किए गए पूर्णांक का उपयोग करते हैं, तो दो के पूरक द्विआधारी प्रतिनिधित्व होते हैं +2147483648और -2147483648समान होते हैं। यह एक समस्या नहीं है, हालांकि, जैसा +2147483648कि सीमा से बाहर माना जाता है।
इस मामले पर थोड़ा और पढ़ने के लिए, आप दो के पूरक पर विकिपीडिया लेख देखना चाह सकते हैं ।
आपके द्वारा इंगित किया गया व्यवहार वास्तव में, काउंटर-सहज ज्ञान युक्त है। हालाँकि, यह व्यवहार javadocMath.abs(int) द्वारा निर्दिष्ट एक है :
यदि तर्क नकारात्मक नहीं है, तो तर्क लौटाया जाता है। यदि तर्क नकारात्मक है, तो तर्क का निषेध लौटा दिया जाता है।
अर्थात्, Math.abs(int)निम्न जावा कोड की तरह व्यवहार करना चाहिए:
public static int abs(int x){
if (x >= 0) {
return x;
}
return -x;
}
यही कारण है, नकारात्मक मामले में, है -x।
जेएलएस सेक्शन 15.15.4 के अनुसार , इसके -xबराबर है (~x)+1, जहां ~बिटवाइज़ पूरक ऑपरेटर है।
यह जाँचने के लिए कि क्या यह सही लगता है, आइए उदाहरण के तौर पर -1 लें
पूर्णांक मान -1को 0xFFFFFFFFजावा में हेक्साडेसिमल के रूप में नोट किया जा सकता है (इसे printlnया किसी अन्य विधि से देखें)। -(-1)इस प्रकार लेना देता है:
-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1
तो, यह काम करता है।
आइए अब हम कोशिश करते हैं Integer.MIN_VALUE। यह जानकर कि सबसे कम पूर्णांक का प्रतिनिधित्व किया जा सकता है 0x80000000, अर्थात् , 1 को पहला सेट और 0 को सेट किए गए 31 शेष बिट्स हैं:
-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1
= 0x80000000 = Integer.MIN_VALUE
और यही कारण है कि Math.abs(Integer.MIN_VALUE)रिटर्न Integer.MIN_VALUE। यह भी ध्यान रखें कि 0x7FFFFFFFहै Integer.MAX_VALUE।
उस ने कहा, हम भविष्य में इस प्रति-सहज रिटर्न मूल्य के कारण समस्याओं से कैसे बच सकते हैं?
हम @Bombe द्वारा बताया गया था , हमारे intएस को longपहले कास्ट कर सकते थे। हालांकि, हमें भी होना चाहिए
intएस में डाल दिया , जो काम नहीं करता है क्योंकि
Integer.MIN_VALUE == (int) Math.abs((long)Integer.MIN_VALUE)।longकिसी भी तरह से उम्मीद करना जारी रखें कि हम कभी भी Math.abs(long)एक मूल्य के बराबर कॉल नहीं करेंगे Long.MIN_VALUE, क्योंकि हमारे पास भी है Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE।हम BigIntegerहर जगह एस का उपयोग कर सकते हैं , क्योंकि BigInteger.abs()वास्तव में हमेशा सकारात्मक मूल्य वापस आता है। यह एक अच्छा विकल्प है, हालांकि कच्चे पूर्णांक प्रकारों में हेरफेर करने की तुलना में थोड़ा धीमा है।
हम Math.abs(int)इस तरह के लिए अपने स्वयं के आवरण लिख सकते हैं :
/**
* Fail-fast wrapper for {@link Math#abs(int)}
* @param x
* @return the absolute value of x
* @throws ArithmeticException when a negative value would have been returned by {@link Math#abs(int)}
*/
public static int abs(int x) throws ArithmeticException {
if (x == Integer.MIN_VALUE) {
// fail instead of returning Integer.MAX_VALUE
// to prevent the occurrence of incorrect results in later computations
throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
}
return Math.abs(x);
}
int positive = value & Integer.MAX_VALUE(अनिवार्य रूप से बह निकला Integer.MAX_VALUEकरने 0के बजाय Integer.MIN_VALUE)अंतिम नोट के रूप में, यह समस्या कुछ समय के लिए जानी जाती है। उदाहरण के लिए देखें इसी प्रविष्टि के बारे में खोज नियम ।
नतीजा यह है कि आप उम्मीद कर रहे हैं, कलाकारों को देखने के लिए Integer.MIN_VALUEकरने के लिए long:
System.out.println(Math.abs((long) Integer.MIN_VALUE));
Math.absएक नकारात्मक संख्या को लौटाने के लिए Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE
ArithmeticException? इसके अलावा, व्यवहार एपीआई दस्तावेज में स्पष्ट रूप से प्रलेखित है।
Math.abs(long)। मैं यहां अपनी गलती के लिए माफी मांगता हूं: मैंने कहा था कि आपने Math.abs(long)एक फिक्स के रूप में उपयोग का प्रस्ताव रखा था , जब आपने "यह देखने के लिए एक सरल तरीका के रूप में दिखाया था कि परिणाम पूछने वाला उम्मीद कर रहा है"। माफ़ करना।
इसमें एक निश्चितता है जावा 15 इंट और लॉन्ग की विधि होगी। वे कक्षाओं पर मौजूद रहेंगे
java.lang.Math and java.lang.StrictMath
विधियों।
public static int absExact(int a)
public static long absExact(long a)
अगर तुम पास हो जाओ
Integer.MIN_VALUE
या
Long.MIN_VALUE
एक अपवाद फेंक दिया जाता है।
https://bugs.openjdk.java.net/browse/JDK-8241805
मैं यह देखना चाहूंगा कि क्या Long.MIN_VALUE या Integer.MIN_VALUE पास है या नहीं, एक सकारात्मक मूल्य वापस आएगा और अपवाद नहीं।
Math.abs बड़ी संख्याओं के साथ हर समय काम नहीं करता है मैं इस छोटे कोड तर्क का उपयोग करता हूं जो मैंने सीखा था जब मैं 7 साल का था!
if(Num < 0){
Num = -(Num);
}
sयहाँ क्या है ?
Numबराबरी होती है तो इसका क्या परिणाम होता है Integer.MIN_VALUE?