एंडपन को स्वैप करें


20

जैसा कि आप में से अधिकांश शायद जानते हैं, (बाइट-पता करने योग्य) हार्डवेयर यादों को दो श्रेणियों में विभाजित किया जा सकता है - थोड़ा-एंडियन और बड़ा-एंडियन । छोटी-एंडियन यादों में बाइट्स को 0 से शुरू करके छोटे (सबसे महत्वपूर्ण) छोर पर और बड़े-एंडियन में दूसरे तरीके से गोल किया जाता है।

मजेदार तथ्य : ये शब्द जोनाथन स्विफ्ट की पुस्तक गुलिवर्स ट्रेवल्स पर आधारित हैं, जहां लिलिपुटियन राजा ने अपने नागरिकों को अपने अंडे छोटे छोर (इस तरह छोटे-एंडियन) पर तोड़ने का आदेश दिया था और विद्रोही उनके बड़े अंत को तोड़ देंगे।

स्वैपिंग कैसे काम करती है

मान लीजिए कि हमारे पास 12648430मेमोरी में एक अहस्ताक्षरित पूर्णांक (32 बिट) है, एक बड़ी-एंडियन मशीन में जो निम्नानुसार दिख सकती है:

  addr: 0  1  2  3
memory: 00 C0 FF EE

बाइट-ऑर्डर को प्राप्त करने से हमें हेक्साडेसिमल पूर्णांक मिलता है 0xEEFFC000जो 4009738240दशमलव में है।

आपका कार्य

एक प्रोग्राम / फ़ंक्शन लिखें जो दशमलव में एक अहस्ताक्षरित 32 बिट पूर्णांक प्राप्त करता है और परिणामी पूर्णांक को आउटपुट करता है जब ऊपर वर्णित अंतरण को स्वैप किया जाता है।

नियम

  • इनपुट हमेशा रेंज में हो जाएगा 0करने के लिए4294967295
  • आउटपुट को STDOUT में प्रिंट किया जा सकता है
  • इनपुट और आउटपुट दशमलव में हैं
  • अमान्य इनपुट पर व्यवहार को अपरिभाषित छोड़ दिया जाता है

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

0 -> 0
1 -> 16777216
42 -> 704643072
128 -> 2147483648
12648430 -> 4009738240
16885952 -> 3232235777
704643072 -> 42
3735928559 -> 4022250974
4009738240 -> 12648430
4026531839 -> 4294967279
4294967295 -> 4294967295

एक फ़ंक्शन जवाब के लिए, "इनपुट और आउटपुट दशमलव में हैं" या तो अंक वर्णों की एक स्ट्रिंग या अंकों के मान की आवश्यकता है? या एक फ़ंक्शन उत्तर अपनी भाषा के प्राकृतिक पूर्णांक मान प्रतिनिधित्व का उपयोग कर सकता है, जो कि ज्यादातर मामलों में "दशमलव" के साथ कुछ भी नहीं है?
aschepler

1
@aschepler भाषा का पूर्णांक मान, उदा। 42दशमलव में दिया गया है, लेकिन तकनीकी रूप से यह उदाहरण के लिए C में बाइनरी है। आप निश्चित रूप से टाइप कर सकते हैं 0x2a, जो मैं रोकना चाहता था वह इनपुट को स्ट्रिंग की तरह "2a"या जैसे ले रहा है।

संबंधित (जैसा कि यह चुनौती केवल 32 बिट्स को पैड करने के लिए सुनिश्चित कर रही है)
FlipTack

जवाबों:


25

x86_32 मशीन भाषा, 3 बाइट्स

endian_swap:        # to be called with PASCAL REGISTER calling convention
0f c8    bswap eax
c3       ret

यह थोड़ा धोखा है। पास्कल रजिस्टर कॉलिंग कन्वेंशन ( विकिपीडिया देखें ) __fastcall की तरह एक सा है, सिवाय इसके कि यह ईएक्सएक्स में पहला पैरामीटर पास करता है, और ईएक्सएक्स में रिटर्न वैल्यू भी शामिल है। यह कैली-क्लीनअप भी है, लेकिन चूंकि हम रिटर्न पॉइंटर के अलावा किसी अन्य चीज के लिए स्टैक का उपयोग नहीं करते हैं इसलिए हमें कुछ भी करने की आवश्यकता नहीं है। यह हमें एक mov या xchg से बचने और सीधे bswap का उपयोग करने की अनुमति देता है।


मई यह नोट करना चाहते हैं कि bswapइसके लिए 80486 या उससे अधिक की आवश्यकता है :)
छत

@ceilingcat बहुत सच है, हालांकि मुझे यकीन है कि संकलक या टूलकिन प्रतिबंधों के कारण यहां कई अन्य समाधानों के लिए मामला है!
बहुपद

10

x86_64 मशीन भाषा लिनक्स, 5 4 बाइट्स

0:       0f cf                   bswap  %edi
2:       97                      xchg   %eax,%edi
3:       c3                      retq 

इसके लिए @peter ferrie को -1 से धन्यवाद ।

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


यह एक दशमलव वापसी मान नहीं है। मुझे नहीं लगता कि वह मायने रखता है। इसके अलावा, आप 4 बाइट्स के लिए ईएक्सएक्स ईजी, एक्सएक्सएक्स कर सकते हैं।
पीटर फेर्री

@peterferrie वाह मैं सिर्फ पीई हेडर के बारे में आपकी वेबसाइट को पढ़ रहा था!
सीलिंग


6

जाप , 10 14 बाइट्स

sG ùT8 ò w ¬nG

कोशिश करो


व्याख्या

इनपुट पूर्णांक को आधार -16 स्ट्रिंग में परिवर्तित करें ( sG), 08 से शुरू होने वाली लंबाई को पैड करने के लिए उपयोग करें ( ùT8), 2 वर्ण स्ट्रिंग्स ( ò), रिवर्स ( w), एक स्ट्रिंग में फिर से जुड़ने के लिए ( ) में विभाजित करें ¬और वापस बेस में कनवर्ट करें 10 ( nG)।


आप जानते हैं कि एक आसान विशेषता क्या हो सकती yहै, जैसे कि एक फ़ंक्शन दिया जाता है, जब कोई फ़ंक्शन दिया जाता है, तो अपना सामान्य परिवर्तन लागू करें, फ़ंक्शन चलाएं और फिर परिवर्तन को उल्टा करें। इस मामले में मुझे लगता है कि यह sG_ò w ¬8 बाइट्स के लिए छोटा करने की अनुमति देगा । या अगर òवह भी किया, यह sG_ò2_w7 के लिए भी हो सकता है ...
ETHproductions

@ETHproductions मैं इसका समर्थन करता हूं; के तहत &.जम्मू में क्रिया विशेषण यह करता है और यह कभी कभी वास्तव में गोल्फ में उपयोगी है। हालांकि सभी आक्रमणों में कोडिंग थकाऊ हो सकता है।
कोल

@ETHproductions: अधिक "ओवरलोडिंग", बेहतर :) मैंने पिन अप करते समय इसे लिखा था और मूल रूप से sG_òw..., मेरे जीवन के लिए, यह नहीं जान सका कि यह काम क्यों नहीं करेगा! मुझे अपनी गलती का एहसास हुआ!
झबरा

2 से कम इनपुट के लिए काम करने के लिए प्रतीत नहीं होता है << 24 ...
नील

धन्यवाद, @ नील; बाद में तय हो जाएगा। ऐसा लगता है कि यह मुझे 4 बाइट खर्च होंगे।
झबरा



5

एपीएल + विन 14 बाइट्स

256⊥⌽(4⍴256)⊤⎕

व्याख्या

⎕ prompt for screen input
(4⍴256)⊤ 4 byte representation in base 256
⌽ reverse bytes
256⊥ bytes from base 256 to integer

1
256⊥⌽⎕⊤⍨4⍴256-1 बाइट के लिए काम करेगा ?
निकोलगर्फ़

So ऑपरेटर APL + विन में उपलब्ध नहीं है, इसलिए उत्तर नहीं है, लेकिन यह अच्छी तरह से Dyalog APL
ग्राहम

5

सी # , 70 68 बाइट्स

यह शायद इष्टतम नहीं है।

68:

Func<uint,uint>f=n=>((n=n>>16|n<<16)&0xFF00FF00)>>8|(n&0xFF00FF)<<8;

70:

uint e(uint n){n=n>>16|n<<16;return(n&0xFF00FF00)>>8|(n&0xFF00FF)<<8;}

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


आप असाइनमेंट को returnएक्सप्रेशन में ले जा सकते हैं और फिर एक्सप्रेशन-बॉडीड मेंबर सिंटैक्स का उपयोग कर सकते हैं : uint e(uint n)=>((n=n>>16|n<<16)&0xFF00FF00)>>8|(n&0xFF00FF)<<8;64 बाइट्स के लिए।
hvd

@hvd यह मेरे लिए मान्य अभिव्यक्ति-बद्ध वाक्य रचना के रूप में नहीं दिख रहा है। मैं हालांकि 2 बाइट्स को शेव करने के लिए शिफ्ट रीक्रेंजमेंट ट्रिक का उपयोग करने में सक्षम था।
बहुपत्नी

मैंने यह सुनिश्चित करने के लिए अपने TIO लिंक में अपनी टिप्पणी से कॉपी और पेस्ट किया कि कोई टाइपोस या ऐसा कुछ भी नहीं था और ठीक उसी तरह जैसे कि यह मेरी टिप्पणी में है, यह काम करता है: TIO लिंक
hvd

मैंने देखा कि 0xFF00FF00 0xFF00FF का पूरक है और आश्चर्य है कि क्या आप इसका लाभ उठा सकते हैं? लेकिन इसे एक चर घोषित करते हुए बहुत सारे पात्र लगते हैं
प्रिंसपोलका

ओह! अच्छा स्थिरांक की जाँच करने के वास्तव में: आप उपयोग कर सकते हैं 0xFF00FFद्वारा दो बार >>से पहले ing &ing, और आप तो छोटा कर सकते हैं 0xFF00FFकरने के लिए ~0u/257: uint e(uint n)=>((n=n>>16|n<<16)>>8&~0u/257)|(n&~0u/257)<<8;60 के लिए TIO लिंक
HVD


4

05AB1E , 12 10 बाइट्स

3F₁‰R`})₁β

इसे ऑनलाइन आज़माएं! स्पष्टीकरण:

  ₁         Integer constant 256
   ‰        [Div, Mod]
    R       Reverse
     `      Flatten to stack
3F    }     Repeat 3 times
       )    Collect results
        ₁β  Convert from base 256

1
यह एक मान्य समाधान नहीं लगता है। "पैडिंग" तुम क्या वास्तव में लंबाई 4. करने के लिए बाइट्स की सूची दोहरा है
Outgolfer एरिक

@EriktheOutgolfer बाह, मैं चाहता हूं कि दस्तावेज वास्तव में कहेंगे कि ...
नील

3

जावास्क्रिप्ट (ईएस 6), 45 43 बाइट्स

f=(n,p=0,t=4)=>t?f(n>>>8,p*256+n%256,t-1):p

1
शुरुआत t=02 बाइट्स से होती है:f=(n,p=t=0)=>t++<4?f(n>>>8,p*256+n%256):p
अर्नुलड


3

MATL , 12 10 बाइट्स

7Y%1Z%P7Z%

इसे ऑनलाइन आज़माएं! या सभी परीक्षण मामलों को सत्यापित करें

व्याख्या

        % Implicitly input a number, read as a double
7Y%     % Cast to uint32
1Z%     % Convert to uint8 without changing underlying data. The result is 
        % an array of four uint8 numbers, each corresponding to a byte of
        % the original number's representation 
P       % Flip array
7Z%     % Convert back to uint32 without changing underlying data. The array
        % of four uint8 numbers is interpreted as one uint32 number.
        % Implicitly display

2

JavaScript (ES6), 51 45 bytes

Saved 6 bytes with @Neil's help

n=>(n>>>24|n>>8&65280|(n&65280)<<8|n<<24)>>>0

Test cases


Nice, best I could get with recursion was f=(n,p=0,t=4)=>t?f(n/256|0,p*256+n%256,t-1):p.
ETHproductions

@ETHproductions ...that's shorter?
Erik the Outgolfer

1
@ETHproductions That's definitely shorter. You should post it.
Arnauld

46 bytes: n=>(n>>>24|n>>8&65280|n<<8&16711680|n<<24)>>>0
Neil

1
@hvd No worries. You can either add it as an alternate version or replace the existing one entirely. Up to you!
Arnauld

2

J, 16 bytes

|.&.((4#256)#:])

Try it online!

Working on shortening the right-hand expression. I think I can shave off a few bytes by making this work with a beta J version. I swear I saw on here that you can end a train with a noun in a new beta version...

Explanation

|.&.((4#256)#:])
    ((4#256)#:])  Convert to 4 two-byte blocks
            #:      Debase to
      4#256         4 digits base 256
  &.              Apply right function, left function, then inverse of right
|.                Reverse digits

Convert to 4 digits base 256, reverse the digits, then convert back to decimal. Basically, perform the algorithm that is provided in the OP. This is perhaps the one time where it's helpful that J's mixed base conversion requires you to specify the number of digits, although it would be 2 fewer bytes if I could end the train in a noun ((#:~4#256) instead).


2

Excel VBA, 103 92 Bytes

Anonymous VBE immediate window function that takes input from range [A1] converts to hex, reverses bytes, and outputs to the VBE immediate window

h=[Right(Rept(0,8)&Dec2Hex(A1),8)]:For i=0To 3:s=s+Mid(h,7-2*i,2):Next:[B1]=s:?[Hex2Dec(B1)]

Can I test this somewhere? Could you add an online interpreter, please?
ბიმო

2
@BruceForte No, unfortunately there are no online interpretters for any of the variants of VBA, however, if you have a copy of Excel on your computer, you can access the VBE by pressing Alt + F11, and then the immediate window by pressing Ctrl + G. For this anonymous function you would then paste your input into cell A1 and the code above into the immediate window and press enter
Taylor Scott

Oh - and sometimes VBA is a bit funky (and the Mac version is imperically worse than the windows version) so this, and unless otherwise stated all, VBA solutions assume the default 32-Bit Windows version
Taylor Scott

2

PPC Assembly (32-bit), 8 bytes

endian_swap:    # WORD endian_swap(WORD)
7c 60 1c 2c     LWBRX 3,0,3
4e 80 00 20     BLR

How this works:

  • PPC calling convention puts the first 32-bit word parameter into SP+24, and shadows that address into GPR3.
  • LWBRX takes load GPR3 (third operand) and zero-extends it (second operand) into EA, then reads 4 bytes in reverse order and stores it into GPR3 (first operand).
  • GPR3 holds the return value.
  • BLR returns from the function (branches to the address in the LR register)

Unfortunately there aren't any online PPC assembly emulators that I could find to demonstrate. Sorry!


2

Befunge, 62 61 or 49 bytes

0&0v!p22:/3g22/*:*82\+%*:*82+<
@.$_:28*:*%00p\28*:**00g28*:*^

Try it online!

This is using standard Befunge on the reference interpreter, and we thus need to account for the fact that memory cells are 8-bit signed, and correct for possible signed overflow.

On implementations with unsigned memory cells (e.g. PyFunge), or where the range is greater than 8 bits (e.g. FBBI), we can get away without those checks, saving 12 bytes.

0&0v!p22:/3g22/*:*82\+g<
@.$_:28*:*%00p\28*:**00^

Try FBBI online!
Try PyFunge online!

Although note that PyFunge has a bug processing integer input, so when testing on TIO you need to follow the number in the input field with a space or line break.


2

Octave, 10 bytes

@swapbytes

Try it online!

This may be the first time that Octave has the exact same score as its golfing derivative, MATL. Of course, in this case, it's Octave that has the built-in, rather than MATL, making it a lot easier.

Defines a handle to the built-in swapbytes, which takes any data type, swaps the endianness and outputs the result. In this case, the input is a 32-bit unsigned integer.



2

R, 86 bytes

I thought there was already an answer (or two) in R for this question, but I must have been mistaken or they had the same issues that I had with R not doing signed ints. That issue took out any builtins that could have helped. I tried the 256 base conversion, but it ended up being to long, but I think there is still room for someone smarter than me to do that. Then I ended up with the following which it a base 2 conversion swapping the order in a recursive function.

f=function(x,y=0,i=31)'if'(i+1,f(x-(2^i*z),y+(2^((3-i%/%8)*8+i%%8)*(z=2^i<=x)),i-1),y)

Try it online!

f=function(x,y=0,i=31)       # set up the function and initial values
  'if'(i+1,                  # test for i >= 0
    f(                       # recursively call the function
      x-(2^i*z),             # remove 2^i from x when 2^i <= x
      y+(2^                  # add to y 2 to the power of
        ((3-i%/%8)*8+i%%8)   # calc to swap the order of the bytes
        *(z=2^i<=x)),        # when 2^i <= x
      i-1),                  # decrement i
   y)                        # return y

you were right about base 256 being shorter!
Giuseppe

@Giuseppe, you are going to put hat one up aren't you
MickyT

2

R, 41 bytes

function(n)n%/%256^(0:3)%%256%*%256^(3:0)

Try it online!

Verify all test cases!

Uses a base-256 conversion as MickyT suggested here. R does not have unsigned 32-bit integers, nor does it have 64-bit integers. This prevents us from using bitwise operations but this approach (and likely MickyT's) is probably still shorter since R's bitwise operators are quite verbose.

Utilizes number 4 of this tip, taking into account that we're never getting a number as large as 256^4.

n%/%256^(0:3)%%256 extracts the bytes, and %*%, the matrix product, is the dot product in this situation, with 256^(3:0) effecting the reversed order of bytes. %*% will return a 1x1 matrix containing the endian-reversed value.


1

CP-1610 assembly, 6 DECLEs = 8 bytes

This code is intended to be run on an Intellivision.

A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This function is 6 DECLEs long, starting at $480C and ending at $4811.

The CP-1610 has 16-bit registers, so we're using two of them (R0 and R1) to store a 32-bit value.

                               ROMW  10           ; use 10-bit ROM

                               ORG   $4800        ; start program at address $4800

                               ;; example call
4800  0001                     SDBD               ; load 0xDEAD into R0
4801  02B8 00AD 00DE           MVII  #$DEAD, R0
4804  0001                     SDBD               ; load 0xBEEF into R1
4805  02B9 00EF 00BE           MVII  #$BEEF, R1

4808  0004 0148 000C           CALL  swap32       ; call our function

480B  0017                     DECR  PC           ; loop forever

                               ;; swap32 function
                       swap32  PROC

480C  0040                     SWAP  R0           ; 16-bit SWAP of R0
480D  0041                     SWAP  R1           ; 16-bit SWAP of R1

480E  01C1                     XORR  R0, R1       ; exchange R0 and R1
480F  01C8                     XORR  R1, R0       ; using 3 consecutive eXclusive OR
4810  01C1                     XORR  R0, R1

4811  00AF                     JR    R5           ; return

                               ENDP

Execution dump

 R0   R1   R2   R3   R4   R5   R6   R7    CPU flags  instruction
 ------------------------------------------------------------------
 0000 4800 0000 0000 01FE 1041 02F1 4800  ------iq   SDBD
 0000 4800 0000 0000 01FE 1041 02F1 4801  -----D-q   MVII #$DEAD,R0
 DEAD 4800 0000 0000 01FE 1041 02F1 4804  ------iq   SDBD
 DEAD 4800 0000 0000 01FE 1041 02F1 4805  -----D-q   MVII #$BEEF,R1
[DEAD BEEF]0000 0000 01FE 1041 02F1 4808  ------iq   JSR  R5,$480C

 DEAD BEEF 0000 0000 01FE 480B 02F1 480C  ------iq   SWAP R0
 ADDE BEEF 0000 0000 01FE 480B 02F1 480D  S------q   SWAP R1
 ADDE EFBE 0000 0000 01FE 480B 02F1 480E  S------q   XORR R0,R1
 ADDE 4260 0000 0000 01FE 480B 02F1 480F  ------iq   XORR R1,R0
 EFBE 4260 0000 0000 01FE 480B 02F1 4810  S-----iq   XORR R0,R1
[EFBE ADDE]0000 0000 01FE 480B 02F1 4811  S-----iq   MOVR R5,R7

 EFBE ADDE 0000 0000 01FE 480B 02F1 480B  ------iq   DECR R7

Why is this 7.5 bytes? I think it should be 8 bytes.
Erik the Outgolfer

@EriktheOutgolfer Fair enough. Updated accordingly.
Arnauld

@EriktheOutgolfer Because 60 bits equals 7.5 bytes?
Jeppe Stig Nielsen

@JeppeStigNielsen That's true, but a file can never be 7.5 bytes long, it will be pre- or post-padded with 0s.
Erik the Outgolfer

@EriktheOutgolfer Technically, this could really be stored inside a 10-bit ROM. Here is an example spec sheet. (Today, we're using 16-bit ROM for Intellivision homebrew games, but back in the day, memory chips were so expensive that using 10-bit was a real money saver.)
Arnauld

1

C# (.NET Core), 72+31=103 bytes

m=>BitConverter.ToUInt32(BitConverter.GetBytes(m).Reverse().ToArray(),0)

Try it online!

+31 for using System;using System.Linq;

I was hoping to use Array.Reverse inline, but it wasn't to be (see alternative below).

C# (.NET Core), 87+13=100 bytes

m=>{var a=BitConverter.GetBytes(m);Array.Reverse(a);return BitConverter.ToUInt32(a,0);}

Try it online!

+13 for using System;

This solution care of @JeppeStigNielsen; removing the restriction of having everything inline saved 3 bytes.


Because you can save using System.Linq;, it can still be cheaper to use x=>{var a=BitConverter.GetBytes(x);Array.Reverse(a);return BitConverter.ToUInt32(a,0);}.
Jeppe Stig Nielsen

1

REXX, 42 bytes

say c2d(left(reverse(d2c(arg(1))),4,'0'x))

Try it online!

Ungolfed:

n=arg(1) -- take n as argument
n=d2c(n) -- convert from decimal to character (bytes)
n=reverse(n) -- reverse characters
n=left(n,4,'0'x) -- extend to four bytes, padding with zeros
n=c2d(n) -- convert from bytes to decimal again
say n -- output result


1

ARM machine language Linux, 8 bytes

0:       e6bf0f30       rev     r0, r0
4:       e12fff1e       bx      lr

To try this yourself, compile and run the following on a Raspberry Pi or Android device running GNUroot

#include<stdio.h>
#define f(x) ((unsigned int(*)(unsigned int))"0\xf\xbf\xe6\x1e\xff/\xe1")(x)
int main(){
  printf( "%u %u\n", 0, f(0) );
  printf( "%u %u\n", 1, f(1) );
  printf( "%u %u\n", 42, f(42) );
  printf( "%u %u\n", 128, f(128) );
  printf( "%u %u\n", 16885952, f(16885952) );
  printf( "%u %u\n", 704643072, f(704643072) );
  printf( "%u %u\n", 3735928559U, f(3735928559U) );
  printf( "%u %u\n", 4009738240U, f(4009738240U) );
  printf( "%u %u\n", 4026531839U, f(4026531839U) );
  printf( "%u %u\n", 4294967295U, f(4294967295U) );
}



1

K4, 18 bytes

Solution:

0b/:,/8#|12 8#0b\:

Examples:

q)\
  0b/:,/8#|12 8#0b\:0
0
  0b/:,/8#|12 8#0b\:1
16777216
  0b/:,/8#|12 8#0b\:42
704643072
  0b/:,/8#|12 8#0b\:4294967295
4294967295
  0b/:,/8#|12 8#0b\:4026531839
4294967279

Explanation:

There are no unsigned ints, so takes input as a long.

Convert into boolean array (64bits), reshape, reverse, take first 8 bytes, convert back to long.

0b/:,/8#|12 8#0b\: / the solution
              0b\: / convert to bits
         12 8#     / reshape into 12x8 grid (wraps)
        |          / reverse
      8#           / take first 8
    ,/             / flatten
0b/:               / convert to long

Bonus:

19 byte version in oK which you can Try online!

2/,/8#|12 8#(64#2)\
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.