का सटीक योग long[]
का सटीक योग प्राप्त करने के लिए मैं निम्न स्निपेट का उपयोग कर रहा हूं।एक लंबी सरणी
public static BigInteger sum(long[] a) {
long low = 0;
long high = 0;
for (final long x : a) {
low += (x & 0xFFFF_FFFFL);
high += (x >> 32);
}
return BigInteger.valueOf(high).shiftLeft(32).add(BigInteger.valueOf(low));
}
यह दो हिस्सों में विभाजित संख्याओं को संसाधित करके अंततः आंशिक रकम को संयोजित करके ठीक काम करता है। हैरानी की बात है, इस विधि भी काम करता है:
public static BigInteger fastestSum(long[] a) {
long low = 0;
long high = 0;
for (final long x : a) {
low += x;
high += (x >> 32);
}
// We know that low has the lowest 64 bits of the exact sum.
// We also know that BigInteger.valueOf(high).shiftLeft(32) differs from the exact sum by less than 2**63.
// So the upper half of high is off by at most one.
high >>= 32;
if (low < 0) ++high; // Surprisingly, this is enough to fix it.
return BigInteger.valueOf(high).shiftLeft(64).add(BigInteger.valueOf(low));
}
मुझे क्या करना का मानना है कि fastestSum
काम करना चाहिए के रूप में है नहीं। मेरा मानना है कि यह काम कर सकता है, लेकिन अंतिम चरण में कुछ और करना है। हालांकि, यह मेरे सभी परीक्षणों (बड़े यादृच्छिक परीक्षण सहित) पास करता है। तो मैं पूछ रहा हूं: क्या कोई साबित कर सकता है कि यह काम करता है या काउंटररेक्स नमूना ढूंढता है?
यह काम करना चाहिए, लेकिन मेरे ज्ञान के लिए, आप अपरिभाषित व्यवहार के आधार पर हैं। सबसे महत्वपूर्ण [** पूर्णांक ऑपरेटर किसी भी तरह से ओवरफ़्लो या अंडरफ़्लो इंगित नहीं करते हैं **] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.2 .2 # jls-4.2.2)। – dhke
@ डीकेके, शायद आप सी के साथ जावा को भ्रमित कर रहे हैं। जेएलएस 15.18.2 कहते हैं, कुछ हिस्सों में, "अगर एक पूर्णांक अतिरिक्त ओवरफ्लो हो जाता है, तो परिणाम गणितीय योग की निम्न-क्रम बिट्स है जो कुछ पर्याप्त बड़े दो में दर्शाया गया है - प्रारूप प्रारूप। अगर अतिप्रवाह होता है, तो परिणाम का संकेत दो ऑपरेंड मानों के गणितीय योग के संकेत के समान नहीं है। " जावा भाषा में कम से कम एकल-थ्रेडेड प्रोग्राम्स के लिए कम से कम, यदि कोई है, अपरिभाषित व्यवहार है। –
@ जॉन बोलिंगर सहमत हुए। जैसा कि ढके लिखते हैं, कोई अतिप्रवाह संकेत नहीं है, लेकिन मैं किसी का उपयोग नहीं कर रहा हूं। और परिणाम सही मोड 2 ** 64 है, इसलिए कम से कम 64 बिट सही हैं। मैं केवल 32 बिट्स के बारे में चिंतित हूं। – maaartinus