Двомірна база


12

Фон

Формат IEEE 754 з подвійною точністю з плаваючою комою - це спосіб представити реальні числа з 64 бітами. Виглядає так:

Реальне число nперетворюється в a doubleтаким чином:

  1. Біт знака sдорівнює 0, якщо число додатне, 1 в іншому випадку.
  2. Абсолютне значення nпредставлено у формі 2**y * 1.xxx, тобто потужність у 2 рази від бази .
  3. Показник eє y(сила 2) мінус тисяча двадцять три.
  4. Фракція f- це xxxчастина (дробова частина основи), що займає найбільш значущі 52 біти.

І навпаки, бітовий візерунок (визначений знаком s, експонентом eі дробом f, кожне ціле число) представляє число:

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

Виклик

З огляду на дійсне число n, виведіть його 52-бітну частку doubleподання 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 Так. Додам ще кілька тестових випадків.
Бубон

3
У вашому описі формату IEEE з плаваючою точкою не згадуються деннормальні числа, які інтерпретуються дещо по-іншому (без неявного ведучого 1). Чи потрібно правильно поводитися з днормалями?
nwellnhof

1
@nwellnhof Вам не потрібно вважати деннормати, NaN та нескінченність.
Бубон

Відповіді:


8

C (gcc) , 42 30 байт

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

Бере вказівник на подвійний аргумент і повертає довгий .

Потрібні 64-бітні тривалості та gcc (невизначена поведінка).

Дякуємо @nwellnhof за -2 байти!

Спробуйте в Інтернеті!


&~0UL>>12на два байти коротше. Однак макрос працює лише з значеннями lvalues.
nwellnhof

Використовуйте макрос -Df(x)=*(long *)&x&~0UL>>12, збережіть 3 байти. TIO
GPS


5

Python 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)

Спробуйте в Інтернеті!


Я можу помилятися, але думаю, що Python hex()дає нормалізовані позначення, які завжди починаються з 0x1.. Якщо так, ви можете просто використовувати це на 44 байти.
Кирило Л.

1
Ну, я забув про негативні цифри, так що це схоже на 50 байт .
Кирило Л.

@ kirill-l Це не завжди починається з "1." . Будь ласка, не соромтесь редагувати.
Лука Сіті

Насправді в останньому коментарі ОП прямо говорить, що ми можемо сміливо ігнорувати субнормальних.
Лука Сіті

5

x86_64 машинна мова для Linux, 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

Спробуйте в Інтернеті!


спробуйте використовувати власний CC замість стандартного ABI. Вимагаючи подвійного перебування в rax, ви можете легко скинути весь хід з xmm0. Для цього потрібні лише зміни, щоб зробити тестовий фреймворк в ASM, а не C (якщо GCC не є надзвичайно розумним).
moonheart08


4

JavaScript (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))тому що це не гарантовано, щоб бути точним. Редагувати: збережено 2 байти завдяки @DanielIndie.


чому б ні --n * 2 ** 52
DanielIndie

@DanielIndie Тому що я забув, що гольф працює з поплавками ...
Ніл


2

C (gcc) макрос, 49 байт

-DF(x)=x?ldexp(frexp(fabs(x),(int[1]){})-.5,53):0

Спробуйте в Інтернеті!

Повертає, doubleале припускаючи точність IEEE, вона не матиме дробової частини. Також зараз обробляє негативні числа.


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

Хун , 25 байт

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

Створіть загальну функцію, яка повертає вхідний мод 2^52.

Виклик:

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

Я ніколи не думав, що побачу тут хуна. Кілька років тому я намагався зрозуміти урбіт, але насправді не міг зробити його головами чи хвостами.
рекурсивна

2

JavaScript (ES7), 98 76 байт

Збережено 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
Ніл

Чи є якийсь перекладач, який вже реалізований BigInt64Array?
tsh






0

Мова машини машини Aarch64 для Linux, 12 байт

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

Щоб спробувати це, скомпілюйте та запустіть наступну програму C на будь-якій машині Aarch64 Linux або (Aarch64) Android на пристрої під керуванням Termux

#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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.