Conversione base reale


19

Abbiamo avuto alcune sfide per la conversione di base, ma tutte sembrano applicarsi ai valori interi. Facciamolo con numeri reali!

La sfida

ingressi:

  • Un vero numero positivo x , espresso in base 10. Questo può essere preso come un galleggiante a doppia precisione o come una stringa. Per evitare problemi di precisione, si può presumere che il numero sia maggiore di 10 −6 e inferiore a 10 15 .
  • Una base target b . Questo sarà un numero intero compreso tra 2 e 36.
  • Un numero di cifre frazionarie n . Questo sarà un numero intero compreso tra 1 e 20.

Output: la rappresentazione di x nella base b con n cifre frazionarie.

Quando si calcola l'espressione di output, le cifre oltre l' n -esimo devono essere troncate (non arrotondate). Ad esempio, x = 3.141592653589793in base b = 3è 10.0102110122..., quindi per n = 3l'output sarebbe 10.010(troncamento), non 10.011(arrotondamento).

Per x e b che producono un numero finito di cifre nella parte frazionaria, la rappresentazione infinito equivalente (troncato a n è consentito anche cifre). Ad esempio, 4.5in decimale può anche essere rappresentato come 4.49999....

Non preoccuparti degli errori in virgola mobile .

Formato di input e output

verrà dato x senza zeri iniziali. Se x sembra essere un numero intero, puoi presumere che verrà dato con una parte decimale zero ( 3.0) o senza parte decimale ( 3).

L'output è flessibile. Ad esempio, può essere:

  • Una stringa che rappresenta il numero con un separatore adatto (punto decimale) tra numero intero e parti frazionarie. Cifre 11, 12ecc. (Per b oltre 10) possono essere rappresentate come lettere A, Bcome al solito, o come qualsiasi altro carattere distinto (specificare).
  • Una stringa per la parte intera e un'altra stringa per la parte frazionaria.
  • Due matrici / elenchi, uno per ogni parte, contenenti numeri da 0a 35come cifre.

Le uniche restrizioni sono che le parti intere e frazionarie possono essere separate (adatto separatore) e utilizzare lo stesso formato (ad esempio no [5, 11]per l'elenco che rappresenta la parte intera e ['5', 'B']per l'elenco che rappresenta la parte frazionaria).

Regole aggiuntive

Casi test

Uscita è indicata come una stringa con cifre 0, ..., 9, A, ..., Zutilizzando .come separatore decimale.

x, b, n                    ->  output(s)

4.5, 10, 5                 ->  4.50000 or 4.49999
42, 13, 1                  ->  33.0 or 32.C
3.141592653589793, 3, 8    ->  10.01021101
3.141592653589793, 5, 10   ->  3.0323221430
1.234, 16, 12              ->  1.3BE76C8B4395
10.5, 2, 8                 ->  1010.10000000 or 1010.01111111
10.5, 3, 8                 ->  101.11111111
6.5817645, 20, 10          ->  6.BCE2680000 or 6.BCE267JJJJ
0.367879441171442, 25, 10  ->  0.94N2MGH7G8
12944892982609, 29, 9      ->  PPCGROCKS.000000000


perché 42, 13, 1possiamo avere 33invece di 33.0?
Liefde:

@LiefdeWen No, una parte essenziale della sfida è che l'output deve avere ncifre decimali
Luis Mendo,

Risposte:


1

Gelatina , 16 byte

*×⁵b⁸ḞðṖḣ⁹,ṫø⁹N‘

Provalo online!

Si noti che i singoli sono stampati come elemento nell'output.


Ehi, cos'è successo alla tua foto?
Luis Mendo,

@LuisMendo alcune persone non possono renderlo, poiché era collegato a Facebook
Leaky Nun

Sai che puoi caricare un'immagine qui, giusto? Quelli di default sono così impersonali
Luis Mendo il

7

JavaScript (ES8), 81 74 71 byte

f=
(x,b,n,g=x=>x.toString(b))=>g(x-x%1)+'.'+g(x%1).substr(2,n).padEnd(n,0)
<div oninput=o.textContent=f(+x.value,b.value,n.value)><input id=x><input type=number min=2 max=36 value=10 id=b><input type=number min=1 max=20 value=10 id=n><pre id=o>

Funziona xtra 1e-6e 1e21, bda 2a 36(esattamente come richiesto) e nda 1a qualsiasi cosa da a 10a 48seconda della base prima che si verifichino errori in virgola mobile. Modifica: salvato 7 byte con l'aiuto di @Birjolaxew. Salvati altri 3 byte con l'aiuto di @tsh. La precedente versione a 74 byte funzionava anche con numeri negativi:

f=
(x,b,n,[i,d]=`${x.toString(b)}.`.split`.`)=>i+`.`+d.slice(0,n).padEnd(n,0)
<div oninput=o.textContent=f(+x.value,b.value,n.value)><input id=x><input type=number min=2 max=36 value=10 id=b><input type=number min=1 max=20 value=10 id=n><pre id=o>


1
Come si fa la conversione di base con regex?!?
Erik the Outgolfer,

@EriktheOutgolfer Non lo sono, è solo un modo golfista (si spera) di estrarre fino a n"cifre" da una stringa.
Neil,

Allora qual è la logica principale della tua funzione?
Erik the Outgolfer,

@EriktheOutgolfer Perché, ovviamente, la funzione di conversione di base integrata di JavaScript. (Suggerimento: guarda dove uso il parametro base.)
Neil

Oh, dice .toString(b)...
stupidami

5

Python 2 , 153 149 144 137 135 109 byte

def f(x,b,m):
 i=int(x);s=[];t=[]
 while i:s=[i%b]+s;i/=b
 while m:m-=1;x=x%1*b;t+=[int(x)]
 return s or[0],t

Non avevo notato che posso solo restituire le cifre come numeri, quindi questo rende molto più semplice. Restituisce due elenchi di cifre, la prima per la parte intera, la seconda per la frazione.

Provalo online!


Nel caso in cui mi aiuti: ho aggiunto una nota secondo cui devi solo supportare numeri maggiori di 1e-6(e inferiori a 1e15, come prima)
Luis Mendo,

5

Perl 6 , 25 byte

->\x,\b,\n{+x .base(b,n)}

Provalo

Allargato:

-> \x, \b, \n {
  +x            # make sure it is a Numeric
  .base( b, n ) # do the base conversion
}

Si noti che lo spazio è in modo che venga analizzato come (+x).base(b,n)
no +( x.base(b,n) ).


Nel caso in cui mi aiuti: ho aggiunto una nota che devi solo supportare numeri maggiori di 1e-6(e inferiori a 1e15, come prima)
Luis Mendo

3

Mathematica, 158 byte

dato che questa sfida ha già ottenuto una risposta molto bella in matematica da @KellyLowder, ho cercato di produrre (con un approccio diverso) i risultati esatti, come mostrato nei casi di test

ToUpperCase[""<>Insert[StringReplace[ToString@BaseForm[#,p]&/@PadRight[#&@@(d=RealDigits[#,p=#2]),w=(#3+d[[2]])][[;;w]],"\n "<>ToString@p->""],".",d[[2]]+1]]&


ingresso

[12944892982609, 29, 9]

produzione

PPCGROCKS.000000000


3

Rubino , 45 byte

->x,b,n{(x*b**n).round.to_s(b).insert(~n,?.)}

Perché?

Poiché b ^ n nella base b è 10 ^ n, moltiplichiamo x per quel numero e quindi aggiungiamo il punto decimale a cui appartiene.

Provalo online!


-1 byte + correzione di bug sostituendo .roundcon .to_i; questo risolve l'ultima cifra dell'output per quelli in cui non corrisponde agli output del test. -1 byte in più usando .insert ~n,?., senza parentesi.
Nnnes,

3

C (gcc) ,157 152 byte

Ha bisogno di 64 bit long intper funzionare con casi di test più grandi.

-5 byte grazie a Peter Cordes

#define P r=99;i=l=x;do{z[--r]=48+7*(l%b>9)+l%b;}while(l/=b);printf(z+r)
long i,r,l;char z[99];f(x,b,n)double x;{P;putchar(46);while(n--){x=(x-i)*b;P;}}

Provalo online!

modifica: alcuni byte possono essere rasati se è consentito generare due stringhe separate da un separatore newline:

149 byte:

#define P r=99;i=l=x;do{z[--r]=48+7*(l%b>9)+l%b;}while(l/=b);printf(z+r)
long i,r,l;char z[99];f(x,b,n)double x;{P;puts("");while(n--){x=(x-i)*b;P;}}

modifica: questa presentazione non è la più lunga, yay!


2
Puoi usarlo printf(z+r)se non contiene %caratteri. (Questo è code-golf; sicurezza e buone pratiche escono dalla finestra: P). È inoltre possibile utilizzare puts(z+r)per ottenere una nuova riga gratuitamente (salvando puts("")nella seconda versione).
Peter Cordes,

Grazie! Ho dimenticato di fornire un carattere * direttamente come modello, questo in effetti fa risparmiare parecchi byte :-) Non posso usare put (z + r) nella seconda versione poiché ciò significherebbe che ogni decimale verrà stampato su una nuova riga
scottinet

Ah, quest'ultima parte non era ovvia senza una versione ungolfed con commenti.
Peter Cordes

float è più corto di double , ma sembra che la domanda richieda un doubleinput o una stringa.
Peter Cordes,

1
Non ce n'è bisogno. Alcune implementazioni comuni di C hanno 64 bit longe, secondo le regole del code-golf, è tutto ciò di cui hai bisogno perché la tua risposta sia valida. (Inoltre, è comune che le risposte code-golf C e C ++ assumano 64 bit long, poiché è quello che usa Try It Online.) Suggerirei di ripristinare la modifica e aggiungere semplicemente una nota come " longdeve essere 64 bit per questo per supportare i più grandi casi di test ".
Peter Cordes,

2

Mathematica 47 byte

TakeDrop@@r[#,#2,#3+Last@(r=RealDigits)[#,#2]]&

Chiamare RealDigitsdue volte per capire prima il numero di cifre a sinistra del decimale.


Nel caso in cui mi aiuti: ho aggiunto una nota che devi solo supportare numeri maggiori di 1e-6(e inferiori a 1e15, come prima)
Luis Mendo,

1
Pensavo che la domanda fosse solo per chiedere, TakeDrop@@RealDigits[##]ma poi mi sono reso conto di avere frainteso le cose: la tua soluzione sembra ottimale.
Mark S.

2

SageMath , 68 byte

def f(n,b,k):y=n.str(b).split('.')+[''];return y[0],(y[1]+'0'*k)[:k]

Provalo online!


Nel caso in cui mi aiuti: ho aggiunto una nota che devi solo supportare numeri maggiori di 1e-6(e inferiori a 1e15, come prima)
Luis Mendo

1

Haskell , 188 byte

f=fromIntegral
g 0 _=[]
g n p=g(div n p)p++[mod n p]
z=(!!)(['0'..'9']++['A'..'Z']++['.'])
h x p l|(i,d)<-properFraction x=z<$>(g i p++[36]++(last$g(floor$d*(f p**f l))p:[0<$[1..l]|d==0]))

Provalo online!

g converte un numero in un elenco che rappresenta quel numero in una data base

zassocia numeri interi a lettere ( 36 = .)

h applica le funzioni precedenti all'intero e alla parte frazionaria di un numero.


1

Assioma, 566 byte

c:=alphanumeric()::List Character
f(a:INT,b:PI):List Character==(r:=[];repeat(y:=a rem b;r:=cons(c.(y+1),r);a:=a quo b;a=0=>break);r)
g(x)==floor(x)::INT
F(x)==>for i in 1..#x repeat z:=concat(z,x.i)
w(a:Float,b:PI,n:NNI):String==
  z:="";b<2 or b>36 or a<0=>z
  ip:=g(a);    fp:=g((a-ip)*b^n)
  ipb:=f(ip,b);fpb:=f(fp,b);cnt:=n-#fpb
  for i in 1..cnt repeat fpb:=cons(c.1,fpb)
  F(ipb);z:=concat(z,".");F(fpb)
  z

h(a,b,n)==>(n>=0 and b>0=>(nd123:=10+g(n*log_2(b)/log_2(10));mxv123456:=digits(nd123::PI);res78484:=w(a,b,n);digits(mxv123456);res78484);"")

era particolarmente difficile questa domanda; dopo qualche tempo scrivendo qualcosa, i risultati giusti sembrano generarsi usando una macro per conservare le cifre () ... non si gioca troppo ... risultati:

(7) -> h(4.5,10,5)
   (7)  "4.50000"
                                                             Type: String
(8) -> h(42,13,1)
   (8)  "33.0"
                                                             Type: String
(9) -> h(%pi,3,8)
   (9)  "10.01021101"
                                                             Type: String
(10) -> h(%pi,5,10)
   (10)  "3.0323221430"
                                                             Type: String
(11) -> h(1.234,16,12)
   (11)  "1.3BE76C8B4395"
                                                             Type: String
(12) -> h(0.367879441171442,25,10)
   (12)  "0.94N2MGH7G8"
                                                             Type: String
(13) -> h(12944892982609,29,9)
   (13)  "PPCGROCKS.000000000"
                                                             Type: String
(14) -> h(6.5817645,20,10)
   (14)  "6.BCE267JJJJ"
                                                             Type: String

il vero obiettivo è una funzione che converte in base 2..36 ogni Float [che ha k: = cifre ()] o ogni numero calcolato come% pi o% e o la divisione di due float / int come in 1./3 . [cifre 'oo']

(15) -> h(%pi,13,800)
   (15)
  "3.1AC1049052A2C77369C0BB89CC9883278298358B370160306133CA5ACBA57614B65B410020
  C22B4C71457A955A5155B04A6CB6CC2C494843A8BBBBA9A039B77B34CB0C036CAC761129B3168
  B8BAB860134C419787C911812985646C7AAA3025BAA118B3AB8265CB347852065667291482145
  6C533447BC53A5262177C9985455C395626091A2CC3126B395C91B65B654A1804226197528410
  29A8A4A55CC7937B347B77B5A914127B11C6A57A84510775A9A467819A468B6B74339CC1290B2
  24921C6A771BC2AB6AB41735119C2231545A86399483119AAA5AC34B46B7B5C9089946A364860
  9B26CB0BAC0ABCBA182C12881933AA93C3942C71AA664753989A3C82166BA2109796C4A134607
  59725A72C9117AC980556A147557C319438287226C94725B125753B009387A48AA45CB1960A04
  A064052C00A6069371949872B14590895C555CB01A39B7589824B8621618A8B1971841201A2AB
  B04B80C7534CC1CB079581491995B46C679555316288C82665645A1A600C1A669B865651B6B842470C018B03C1115B3C4306C015C0B45C"
                                                             Type: String

1

Assioma, 127 byte

g(a)==floor(a)::INT;f(a:Float,b:PI,n:NNI):Any==(b<2 or n>28=>%i;x:=g(a);radix(x,b)+radix(g((a-x)*b^n),b)::RadixExpansion b/b^n)

risultati

(4) -> f(%e,2,10)
   (4)  10.1011011111
                                                   Type: RadixExpansion 2
(5) -> f(%e,3,10)
   (5)  2.2011011212
                                                   Type: RadixExpansion 3
(6) -> f(%e,35,10)
   (6)  2.P4VBNEB51S
                                                  Type: RadixExpansion 35
(7) -> f(1.4,35,10)
   (7)  1.DYYYYYYYYY
                                                  Type: RadixExpansion 35
(8) -> f(%pi,3,8)
   (8)  10.01021101
                                                   Type: RadixExpansion 3
(9) -> f(%pi,5,10)
   (9)  3.032322143
                                                   Type: RadixExpansion 5
(10) -> f(1.234,16,12)
   (10)  1.3BE76C8B4395
                                                  Type: RadixExpansion 16

Ha un piccolo problema per l'esempio zero finale

 f(4.5,10,5)

Restituirebbe "4.5" e non "4.50000"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.