मुझे लगता है कि बिट्स का निरीक्षण करने के लिए एक बेहतर दृष्टिकोण होगा। सामान्यीकृत या denormalized बाइनरी प्रतिनिधित्व की विशेषता है, मूल्य के नहीं। इसलिए, आप इसे इस तरह से अधिक विश्वसनीय रूप से पहचानने में सक्षम होंगे और आप बिना किसी संभावित और संभावित रूप से खतरनाक फ़्लोटिंग पॉइंट तुलना कर सकते हैं।
मैंने आपके लिए कुछ रननेबल कोड रखा है, ताकि आप इसे काम देख सकें। मैंने इस कोड को युगल के बारे में एक समान प्रश्न से अनुकूलित किया। Denormal का पता लगाने एक्सपोनेंट और महत्व को पूरी तरह से उत्साहित करने से कहीं अधिक सरल है, इसलिए मैं कोड को सरल बनाने में सक्षम था।
यह क्यों काम करता है ... एक्सपोनेंट ऑफसेट नोटेशन में संग्रहीत किया जाता है। एक्सपोनेंट के 8 बिट्स मान 1 से 254 (0 और 255 विशेष मामलों के लिए आरक्षित हैं) ले सकते हैं, फिर उन्हें -127 द्वारा समायोजित ऑफसेट किया जाता है -126 (1-127) से 127 (254-127) की सामान्यीकृत रेंज)। एक्सपोनेंट को असामान्य मामले में 0 पर सेट किया गया है। मुझे लगता है कि यह केवल इसलिए आवश्यक है क्योंकि .NET महत्व पर अग्रणी बिट को स्टोर नहीं करता है। आईईईई 754 के अनुसार, इसे किसी भी तरह से संग्रहीत किया जा सकता है। ऐसा प्रतीत होता है कि सी # ने इसे साइन बिट के पक्ष में छोड़ने का विकल्प चुना है, हालांकि मेरे पास उस अवलोकन को वापस करने के लिए कोई ठोस विवरण नहीं है।
किसी भी मामले में, वास्तविक कोड काफी सरल है। जो कुछ आवश्यक है वह एक्सपोनेंट और 0 के लिए परीक्षण 8 बिट्स को उत्पादित करना है। 0 के आसपास एक विशेष मामला है, जिसे नीचे संभाला जाता है।
नोट: टिप्पणी चर्चा के अनुसार, यह कोड मंच विशिष्ट कार्यान्वयन विवरण (x86_64 इस परीक्षण मामले में) पर निर्भर करता है। जैसा कि @ चेन्यून सुगिहारा ने बताया, सीएलआई इस व्यवहार को सुनिश्चित नहीं करता है और यह एआरएम जैसे अन्य प्लेटफार्मों पर भिन्न हो सकता है।
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("-120, denormal? " + IsDenormal((float)Math.Pow(2, -120)));
Console.WriteLine("-126, denormal? " + IsDenormal((float)Math.Pow(2, -126)));
Console.WriteLine("-127, denormal? " + IsDenormal((float)Math.Pow(2, -127)));
Console.WriteLine("-149, denormal? " + IsDenormal((float)Math.Pow(2, -149)));
Console.ReadKey();
}
public static bool IsDenormal(float f)
{
// when 0, the exponent will also be 0 and will break
// the rest of this algorithm, so we should check for
// this first
if (f == 0f)
{
return false;
}
// Get the bits
byte[] buffer = BitConverter.GetBytes(f);
int bits = BitConverter.ToInt32(buffer, 0);
// extract the exponent, 8 bits in the upper registers,
// above the 23 bit significand
int exponent = (bits >> 23) & 0xff;
// check and see if anything is there!
return exponent == 0;
}
}
}
उत्पादन होता है:
-120, denormal? False
-126, denormal? False
-127, denormal? True
-149, denormal? True
सूत्रों का कहना है:
extracting mantissa and exponent from double in c#
https://en.wikipedia.org/wiki/IEEE_floating_point
https://en.wikipedia.org/wiki/Denormal_number
http://csharpindepth.com/Articles/General/FloatingPoint.aspx
कोड से अनुकूलित:
+०१२३५१६४१०६extracting mantissa and exponent from double in c#
इसे देखने का सही तरीका लगता है। हालांकि, आपके सूत्र परिभाषा से मेल नहीं खाते हैं: 'वापसी Math.Pow (2, -149) <= संख्या और संख्या <= ((1-Math.Pow (2, -23)) * Math.Pow (2, - 126)) || Math.Pow (-2, -149)> = संख्या और संख्या> = - ((1 - Math.Pow (2, -23)) * Math.Pow (2, -126)) ' – Rob
यह मेरे लिए गलत लगता है कि आप तुलना करने के लिए 'डबल' गणना और '<=' ऑपरेटर का उपयोग कर रहे हैं। मुझे लगता है कि मछली पकड़ने के कार्निवल की तुलना में अधिक कास्टिंग चल रहा है और इससे इनमें से कोई भी तुलना खत्म हो सकती है। – Enigmativity
तो, क्या आपको लगता है कि मुझे डबल और फ्लोट के साथ मिल रहे विभिन्न प्रारूपों के कारण गलत तुलना मिल रही है? – Nandhi