डबल का आधार


12

पृष्ठभूमि

IEEE 754 डबल-सटीक फ़्लोटिंग-पॉइंट प्रारूप 64 बिट्स के साथ वास्तविक संख्याओं का प्रतिनिधित्व करने का एक तरीका है। यह निम्नलिखित की तरह दिखता है:

एक वास्तविक संख्या nको doubleनिम्नलिखित तरीके से परिवर्तित किया जाता है:

  1. संकेत बिट s0 है यदि संख्या सकारात्मक है, 1 अन्यथा।
  2. निरपेक्ष मान का nनिरूपण प्रपत्र में किया जाता है 2**y * 1.xxx, अर्थात आधार का 2 गुना ।
  3. प्रतिपादक eहै y(2 की शक्ति) शून्य से 1023।
  4. अंश fहै xxxहिस्सा (आधार के आंशिक भाग), सबसे महत्वपूर्ण 52 बिट्स लेने।

इसके विपरीत, एक बिट पैटर्न (संकेत s, प्रतिपादक eऔर अंश द्वारा परिभाषित f, प्रत्येक पूर्णांक) संख्या का प्रतिनिधित्व करता है:

(s ? -1 : 1) * 2 ** (e - 1023) * (1 + f / (2 ** 52))

चुनौती

एक वास्तविक संख्या को देखते हुए n, इसके पूर्णांक doubleके nरूप में प्रतिनिधित्व के 52-बिट अंश का उत्पादन ।

परीक्षण के मामलों

0.0        =>                0
1.2        =>  900719925474099 (hex 3333333333333)
3.1        => 2476979795053773 (hex 8cccccccccccd)
3.5        => 3377699720527872 (hex c000000000000)
10.0       => 1125899906842624 (hex 4000000000000)
1234567.0  =>  798825262350336 (hex 2d68700000000)
1e-256     => 2258570371166019 (hex 8062864ac6f43)
1e+256     => 1495187628212028 (hex 54fdd7f73bf3c)

-0.0       =>                0
-1.2       =>  900719925474099 (hex 3333333333333)
-3.1       => 2476979795053773 (hex 8cccccccccccd)
-3.5       => 3377699720527872 (hex c000000000000)
-10.0      => 1125899906842624 (hex 4000000000000)
-1234567.0 =>  798825262350336 (hex 2d68700000000)
-1e-256    => 2258570371166019 (hex 8062864ac6f43)
-1e+256    => 1495187628212028 (hex 54fdd7f73bf3c)

आप इस सी संदर्भ का उपयोग करके अन्य संख्याओं की जांच कर सकते हैं जो बिट फ़ील्ड और एक यूनियन का उपयोग करता है।

ध्यान दें कि अपेक्षित उत्तर किसी भी संख्या के लिए +nऔर उसके -nलिए समान है n

इनपुट और आउटपुट

मानक नियम लागू होते हैं।

स्वीकृत इनपुट प्रारूप:

  • एक फ्लोटिंग-पॉइंट नंबर, कम से कम doubleआंतरिक रूप से सटीक होने के कारण
  • दशमलव में संख्या का एक स्ट्रिंग प्रतिनिधित्व (आपको वैज्ञानिक संकेतन का समर्थन करने की आवश्यकता नहीं है, क्योंकि आप इनपुट के रूप में 1000...00या उपयोग कर सकते हैं 0.0000...01)

आउटपुट के लिए, कम से कम महत्वपूर्ण बिट पर एक गोल त्रुटि सहनीय है।

जीतने की स्थिति

यह , इसलिए प्रत्येक भाषा में सबसे कम बाइट्स जीतता है।



1
परीक्षण के मामलों में केवल गैर-नकारात्मक संख्याएं शामिल हैं। क्या इनपुट नकारात्मक हो सकता है?
डेनिस

@ डेनिस हां। मैं कुछ और परीक्षण मामले जोड़ूंगा।
बुबलर

3
IEEE फ़्लोटिंग पॉइंट फॉर्मेट के आपके विवरण में असामान्य संख्याओं का उल्लेख नहीं किया गया है, जिनकी व्याख्या थोड़े अलग तरीके से की गई है (कोई निहित प्रमुख 1)। क्या निंदा को सही तरीके से संभाला जाना चाहिए?
nwellnhof

1
@nwellnhof आपको मानदंड, NaN और अनंत पर विचार करने की आवश्यकता नहीं है।
बुबलर

जवाबों:


8

सी (जीसीसी) , 42 30 बाइट्स

long f(long*p){p=*p&~0UL>>12;}

एक संकेतक को तर्क के रूप में एक डबल में ले जाता है और एक लंबा रिटर्न देता है ।

64-बिट लॉन्ग और gcc (अपरिभाषित व्यवहार) की आवश्यकता है।

-2 बाइट्स के लिए @nwellnhof को धन्यवाद!

इसे ऑनलाइन आज़माएं!


&~0UL>>12दो बाइट्स कम है। मैक्रो केवल lvalues ​​के साथ काम करता है, हालांकि।
nwellnhof

मैक्रो का उपयोग करें -Df(x)=*(long *)&x&~0UL>>12, 3 बाइट्स सहेजें। टीआईओ
जीपीएस

6

हास्केल, 27 31 बाइट्स

(`mod`2^52).abs.fst.decodeFloat

decodeFloatमहत्व और प्रतिपादक लौटाता है, लेकिन किसी कारण से पूर्व हास्केल में 53 बिट है, इसलिए हमें एक बिट को काट देना होगा।

इसे ऑनलाइन आज़माएं!


5

पायथन 3 , 54 50 बाइट्स

f=lambda x:int(x.hex().split('.')[1].split('p')[0],16)

इसे ऑनलाइन आज़माएं!

किरिल के सुझाव के साथ:

f=lambda x:int(x.hex()[4+(x<0):].split('p')[0],16)

इसे ऑनलाइन आज़माएं!


मैं गलत हो सकता हूं, लेकिन मुझे लगता है कि पायथन hex()सामान्यीकृत अंकन देता है जो हमेशा से शुरू होता है 0x1.। यदि हां, तो आप इसे केवल 44 बाइट्स के लिए उपयोग कर सकते हैं ।
किरिल एल।

1
खैर, मैं नकारात्मक संख्याओं के बारे में भूल गया, इसलिए यह सब के बाद 50 बाइट्स जैसा दिखता है ।
किरिल एल।

@ kirill-l यह हमेशा "1." से शुरू नहीं होता है (उदाहरण के लिए देखें (२ ** - १०२ 2)) लेकिन ओपी सबनॉर्मल के बारे में कुछ नहीं कहता है, इसलिए मुझे लगता है कि आपका दूसरा सुझाव स्वीकार्य है। कृपया संपादित करने के लिए स्वतंत्र महसूस करें।
लुका सिटी

वास्तव में एक हालिया टिप्पणी में ओपी स्पष्ट रूप से कहता है कि हम सुरक्षित रूप से सबमर्मल की उपेक्षा कर सकते हैं।
लुका सिटी

5

लिनक्स के लिए x86_64 मशीन भाषा, 14 बाइट्स

0:       66 48 0f 7e c0          movq   %xmm0,%rax
5:       48 c1 e0 0c             shl    $0xc,%rax
9:       48 c1 e8 0c             shr    $0xc,%rax
d:       c3                      retq

इसे ऑनलाइन आज़माएं!


कोशिश करें और मानक ABI के बजाय अपने स्वयं के CC का उपयोग करें। आवश्यकता है कि डबल रक्स में हो, आप आसानी से xmm0 से पूरी चाल को छोड़ सकते हैं। इसके लिए केवल बदलाव की आवश्यकता है, सी (जब तक जीसीसी अतिरिक्त स्मार्ट नहीं है) के बजाय एएसएम में परीक्षण रूपरेखा तैयार करना है।
चंद्रहाट ०


4

जावास्क्रिप्ट (ईएस 7), 52 50 बाइट्स

f=n=>n?n<0?f(-n):n<1?f(n*2):n<2?--n*2**52:f(n/2):0
<input oninput=o.textContent=f(this.value)><pre id=o>0

उपयोग नहीं किया जा रहा है Math.floor(Math.log2(n))क्योंकि यह सटीक होने की गारंटी नहीं है। संपादित करें: @DanielIndie के लिए 2 बाइट्स सहेजे गए।


क्यों नहीं
--n

@ डैनियलइंडी क्योंकि मैं भूल गया था कि वह गोल्फ झांकियों के साथ काम करता है ...
नील

3

पर्ल 5 -pl , 28 बाइट्स

$_=-1>>12&unpack Q,pack d,$_

इसे ऑनलाइन आज़माएं!

1e-256 और 1e256 परीक्षण मामले बंद हैं, लेकिन ऐसा इसलिए है क्योंकि पर्ल 5 विशाल या छोटे फ्लोटिंग पॉइंट स्ट्रिंग्स को सटीक रूप से परिवर्तित करता है।




2

हून , 25 बाइट्स

|*(* (mod +< (pow 2 52)))

एक सामान्य फ़ंक्शन बनाएँ जो इनपुट मॉड लौटाता है 2^52

इसे कॉल करना:

> %.  .~1e256
  |*(* (mod +< (pow 2 52)))
1.495.187.628.212.028

मैंने कभी नहीं सोचा था कि मैं यहां हूं। मैंने कुछ साल पहले urbit को समझने की कोशिश की, लेकिन वह वास्तव में सिर या पूंछ नहीं बना सका।
पुनरावर्ती

2

जावास्क्रिप्ट (ईएस 7), 98 76 बाइट्स

सहेजे गए 22 (!) @Neil को धन्यवाद बाइट्स

नील के उत्तर से अधिक क्रिया , लेकिन मैं इसे टाइप किए गए सरणियों के साथ आजमाना चाहता था ।

(n,[l,h]=new Uint32Array(new Float64Array([n]).buffer))=>(h&-1>>>12)*2**32+l

इसे ऑनलाइन आज़माएं!


ES7 + UInt32Array22 बाइट्स बचाता है:(n,[l,h]=new Uint32Array(new Float64Array([n]).buffer))=>(h&-1>>>12)*2**32+l
नील

क्या कोई दुभाषिया है जो BigInt64Arrayपहले से ही लागू था ?
टीश


1

स्टैक्स , 19 14 बाइट्स

üâïc-Hò~÷]ó┬ó♪

इसे चलाएं और डीबग करें

अनपैक्ड, अनगॉल्फ्ड, और टिप्पणी की गई, कोड इस तरह दिखता है।

|a      absolute value
{HcDw   double until there's no fractional part
@       convert to integer type
:B      convert to binary digits
D52(    drop the first digit, then pad to 52
:b      convert back number

इसको चलाओ





0

लिनक्स के लिए Aarch64 मशीन भाषा, 12 बाइट्स

0:   9e660000        fmov x0, d0
4:   9240cc00        and  x0, x0, #0xfffffffffffff
8:   d65f03c0        ret

इसे आज़माने के लिए, किसी भी Aarch64 Linux मशीन या (Aarch64) एंड्रॉइड डिवाइस रनिंग टर्मिनल पर निम्नलिखित C प्रोग्राम को संकलित करें और चलाएं

#include<stdio.h>
const char f[]="\0\0f\x9e\0\xcc@\x92\xc0\3_\xd6";
int main(){
  double io[] = { 0.0,
                  1.2,
                  3.1,
                  3.5,
                 10.0,
            1234567.0,
               1e-256,
               1e+256,
                 -0.0,
                 -1.2,
                 -3.1,
                 -3.5,
                -10.0,
           -1234567.0,
              -1e-256,
              -1e+256 };

  for (int i = 0; i < sizeof io / sizeof*io; i++) {
    double input = io[i];
    long output = ((long(*)(double))f)(io[i]);

    printf("%-8.7g => %16lu (hex %1$013lx)\n", input, output);
  }
}


0

फोर्थ (gforth) , 42 बाइट्स

मान लें कि फ्लोट डिफ़ॉल्ट रूप से दोगुना है और कोशिकाएं लंबाई में 8 बाइट्स हैं (जैसा कि मेरे कंप्यूटर और TIO पर मामला है)

: f f, here float - @ $fffffffffffff and ;

इसे ऑनलाइन आज़माएं!

व्याख्या

f,             \ take the top of the floating point stack and store it in memory
here float -   \ subtract the size of a float from the top of the dictionary
@              \ grab the value at the address calculated above and stick it on the stack
$fffffffffffff \ place the bitmask (equivalent to 52 1's in binary) on the stack
and            \ apply the bitmask to discard the first 12 bits

फोर्थ (gforth) 4-बाइट सेल उत्तर, 40 बाइट्स

कुछ पुराने आगे की स्थापना 4-बाइट कोशिकाओं के बजाय डिफ़ॉल्ट रूप से होती है

: f f, here float - 2@ swap $FFFFF and ;

व्याख्या

f,             \ take the top of the floating point stack and store it in memory
here float -   \ subtract the size of a float from the top of the dictionary
2@             \ grab the value at the address above and put it in the top two stack cells
swap           \ swap the top two cells put the number in double-cell order
$fffff         \ place the bitmask (equivalent to 20 1's in binary) on the stack
and            \ apply the bitmask to discard the first 12 bits of the higher-order cell
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.