더블베이스


12

배경

IEEE 754 배정 밀도 부동 소수점 형식 은 64 비트로 실수를 나타내는 방법입니다. 다음과 같습니다.

실수 는 다음과 같은 방식으로 n변환됩니다 double.

  1. s숫자가 양수이면 부호 비트 는 0이고, 그렇지 않으면 1입니다.
  2. 의 절대 값은 2거듭 제곱n 의 형태로 표시됩니다 .2**y * 1.xxx
  3. 지수 ey(2의 거듭 제곱)에서 1023을 뺀 값입니다.
  4. 분수 fxxx가장 중요한 52 비트를 취하는 부분 (베이스의 분수 부분)입니다.

반대로, 비트 패턴 (sign s, exponent e및 fraction로 정의되고 f각각 정수)은 숫자를 나타냅니다.

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

도전

실수가 주어지면 n, double표현의 52 비트 분수 부분을 n정수로 출력하십시오.

테스트 사례

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)

비트 필드와 공용체를 사용 하는 이 C 참조 를 사용 하여 다른 숫자를 확인할 수 있습니다 .

예상 답변을 위해 동일합니다 +n-n임의의 번호 n.

입력과 출력

표준 규칙이 적용됩니다.

허용되는 입력 형식 :

  • 적어도 double내부적으로 정밀도를 갖는 부동 소수점 숫자
  • 진수 숫자의 문자열 표현 (당신이 사용할 수 있기 때문에 당신이 과학적 표기법을 지원 할 필요가 없습니다 1000...00또는 0.0000...01입력으로)

출력의 경우 최하위 비트에서의 반올림 오류는 허용됩니다.

승리 조건

이것은 이므로 각 언어에서 가장 낮은 바이트가 이깁니다.



1
테스트 사례에는 음수가 아닌 숫자 만 포함됩니다. 입력이 음수 일 수 있습니까?
Dennis

@ 데니스 예. 테스트 사례를 더 추가하겠습니다.
Bubbler

3
IEEE 부동 소수점 형식에 대한 설명에서 약간 다른 방식으로 해석되는 비정규 숫자는 언급하지 않습니다 (암시 적 선행 1 없음). 비정상을 올바르게 처리해야합니까?
nwellnhof

1
@nwellnhof 비정규, NaN 및 무한대를 고려할 필요가 없습니다.
Bubbler

답변:


8

C (gcc) , 42 30 바이트

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

double 을 인수로 가리키는 포인터를 가져와 long을 반환합니다 .

64 비트 long과 gcc (정의되지 않은 동작)가 필요합니다.

-2 바이트를위한 @nwellnhof에게 감사합니다!

온라인으로 사용해보십시오!


&~0UL>>122 바이트 더 짧습니다. 그러나 매크로는 lvalue에서만 작동합니다.
nwellnhof

macro를 사용 -Df(x)=*(long *)&x&~0UL>>12하고 3 바이트를 저장 하십시오 . TIO
GPS


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 바이트로 이것을 사용할 수 있습니다 .
Kirill L.

1
음, 나는 음수를 잊어 버렸으므로 결국 50 바이트 처럼 보입니다 .
Kirill L.

@ kirill-l 항상 "1"로 시작하는 것은 아닙니다. (예를 들어 (2 **-1028) 참조) OP는 subnormals에 대해 아무 말도하지 않으므로 두 번째 제안이 허용되는 것 같습니다. 자유롭게 편집하십시오.
Luca Citi

실제로 최근 의견에서 OP는 명시 적으로 우리는 비정상을 무시할 수 있다고 말합니다.
Luca Citi

5

Linux 용 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를 사용하십시오. 더블이 rax에 있어야하므로 xmm0에서 전체 이동을 쉽게 삭제할 수 있습니다. 이에 필요한 변경 사항은 C가 아닌 ASM에서 테스트 프레임 워크를 만드는 것입니다 (GCC가 더 똑똑하지 않은 경우).
moonheart08

4

MATL , 10 바이트

IZ%52W\0YA

온라인으로 사용해보십시오!

설명

        % Implicit input
IZ%     % Cast to uint64 without changing underlying byte representation
52W     % Push 2^52
\       % Modulus
0YA     % Convert to decimal. Gives a string. This is needed to avoid
        % the number being displayed in scientific notation
        % Implicit display

4

자바 스크립트 (ES7), 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 * 2 ** 52
DanielIndie

@DanielIndie 골프가 플로트와 함께 작동한다는 것을 잊었 기 때문에 ...
Neil



2

T-SQL , 80 바이트

SELECT CAST(CAST(n AS BINARY(8))AS BIGINT)&CAST(4503599627370495AS BIGINT)FROM t

입력은 다음 n과 같은 이름의 테이블 열에서 가져옵니다 t.

CREATE TABLE t (n FLOAT)
INSERT INTO t VALUES (0.0),(1.2),(3.1),(3.5),(10.0),(1234567.0),(1e-256),(1e+256)

SQLFiddle


2

Hoon , 25 바이트

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

입력 mod를 리턴하는 일반 함수를 작성하십시오 2^52.

그것을 호출 :

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

나는 여기서 훈을 볼 줄은 몰랐다. 나는 몇 년 전에 요도를 이해하려고 노력했지만 실제로 머리 나 꼬리를 만들 수는 없었습니다.
재귀

2

자바 스크립트 (ES7), 98 76 바이트

@Neil 덕분에 22 (!) 바이트 절약

Neil의 답변 보다 더 장황 하지만 유형 배열 로 시도해보고 싶었습니다 .

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

온라인으로 사용해보십시오!


ES7 + UInt32Array는 22 바이트를 절약합니다 :(n,[l,h]=new Uint32Array(new Float64Array([n]).buffer))=>(h&-1>>>12)*2**32+l
Neil

BigInt64Array이미 구현 한 통역사가 있습니까?
tsh


1

Stax , 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

Linux 용 Aarch64 기계어, 12 바이트

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

이를 시도하려면 Aux64 Linux 시스템 또는 Termux를 실행하는 (Aarch64) Android 장치에서 다음 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

4 번째 (2 번째) , 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

4 번째 ( 4 번째) 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.