Gerçek taban dönüşümü


19

Temel dönüşüm için birkaç zorluk yaşadık, ancak hepsi tamsayı değerlere uygulanıyor gibi görünüyor. Gerçek sayılarla yapalım!

Meydan okuma

girişler:

  • Temel 10'da ifade edilen gerçek bir pozitif sayı x . Bu, çift kesinlikli bir kayan nokta veya bir dize olarak alınabilir. Hassasiyet sorunlarını önlemek için, sayının 10 −6'dan büyük ve 10 15'ten az olduğu varsayılabilir .
  • Bir hedef baz b . Bu 2 ile 36 arasında bir tam sayı olacaktır.
  • Bir kesir basamak sayısı n . Bu 1 ile 20 arasında bir tam sayı olacaktır.

Çıkış: temsili bir x üssü b ile n fraksiyonel basamağı.

Çıkış ifade işlem olduğunda, ötesinde basamak N th gereken kesik (yuvarlak) içerir. Örneğin, x = 3.141592653589793temel olarak b = 3bir 10.0102110122...çok için n = 3çıkış olacaktır 10.010(kesme) değil, 10.011(yuvarlama).

İçin x ve b fraksiyonel kısmen basamak sonlu sayıda üretmek eşdeğer sonsuz gösterimi (kesiliyor N basamak) kullanmak da mümkündür. Örneğin, 4.5ondalık olarak da temsil edilebilir 4.49999....

Kayan nokta hataları hakkında endişelenmeyin .

Giriş ve çıkış formatı

x baştaki sıfır olmadan verilecektir. Eğer x bir tamsayı olur bunu bir sıfır ondalık kısmı (ile verilecektir varsayabiliriz 3.0) veya ondalık kısmı olmadan ( 3).

Çıktı esnektir. Örneğin, şunlar olabilir:

  • Tamsayı ve kesirli parçalar arasında uygun bir ayırıcıyla (ondalık nokta) sayıyı temsil eden bir dize. Rakamlar 11, 12vb (için b 10 öteye) harfleri olarak temsil edilebilir A, Bher zamanki gibi, ya da başka farklı karakterler olarak (lütfen belirtin).
  • Tamsayı kısmı için bir dize ve kesirli kısım için başka bir dize.
  • Numara içeren iki diziler / listeleri, her bir parça için bir tane 0için 35basamak olarak.

Tek sınırlama, tamsayı ve kesirli kısımların birbirinden ayrılabilmesi (uygun ayırıcı) ve aynı formatın kullanılmasıdır (örneğin, [5, 11]tamsayı kısmını ['5', 'B']temsil eden liste ve kesirli kısmı temsil eden liste için hayır ).

Ek kurallar

Test senaryoları

Çıktı basamaklı bir dize olarak gösterilir 0, ..., 9, A, ..., Z, kullanarak .ondalık ayırıcı olarak.

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


için 42, 13, 1biz olabilir 33yerine 33.0?
LiefdeWen

@LiefdeWen Hayır, mücadelenin önemli bir parçası çıktının nondalık basamağa sahip olması gerektiğidir
Luis Mendo

Yanıtlar:



7

JavaScript (ES8), 81 74 71 bayt

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>

İçin Works xarasında 1e-6ve 1e21, bgelen 2için 36(tam olarak gerekli) ve ngelen 1herhangi bir şey için 10hiç 48tabanına bağlı kayan noktasından önce hatalar sürünme Düzenleme:. Kayıtlı @Birjolaxew yardımıyla 7 bayt. @Tsh yardımıyla 3 bayt daha kaydetti. Önceki 74 baytlık sürüm de negatif sayılarla çalıştı:

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
Regex ile temel dönüşüm nasıl yapılır?!?
Outgolfer Erik

@EriktheOutgolfer Değilim, bu sadece bir dizeden n"rakam" kadar çıkarmak için golfçü (umarım) bir yoludur .
Neil

O zaman ne olduğunu senin fonksiyonunun çekirdek mantığı?
Outgolfer Erik

@EriktheOutgolfer Neden JavaScript'in yerleşik temel dönüştürme işlevi elbette. (İpucu: temel parametreyi kullandığım yere bakın.)
Neil

Oh diyor ki .toString(b)... aptal beni> _ <
Outgolfer Erik

5

Python 2 , 153 149 144 137 135 109 bayt

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

Rakamları sayı olarak döndürebileceğimi fark etmemiştim, bu yüzden çok daha basit hale getiriyor. Birincisi tamsayı kısmı için, ikincisi kesirli için olmak üzere iki basamaklı liste döndürür.

Çevrimiçi deneyin!


Durumda yardımcı olur: Ben sadece daha büyük destek numaralarının gerektiğini not ekledim 1e-6(küçüktür ve 1e15daha önce olduğu gibi,)
Luis Mendo

5

Perl 6 , 25 bayt

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

Dene

Expanded:

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

Boşluğun ayrıştırılmayacak şekilde ayrıldığını (+x).base(b,n)
unutmayın +( x.base(b,n) ).


Yardımcı olması durumunda: Sadece daha önce 1e-6(daha 1e15önce olduğu gibi) daha büyük sayıları desteklemeniz gerektiğini bir not ekledim
Luis Mendo

3

Mathematica, 158 bayt

Bu meydan okuma zaten @KellyLowder tarafından mathematica'da çok güzel bir cevap aldığından, test örneklerinde gösterildiği gibi kesin sonuçlar üretmeye çalıştım (farklı bir yaklaşımla)

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


giriş

[12944892982609, 29, 9]

çıktı

PPCGROCKS.000000000


3

Ruby , 45 bayt

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

Neden?

B tabanındaki b ^ n değeri 10 ^ n olduğundan, x değerini bu sayı ile çarpar ve ondalık noktayı ait olduğu yere ekleriz.

Çevrimiçi deneyin!


-1 bayt + hata düzeltme değiştirerek .roundile .to_i; bu, test çıkışlarıyla eşleşmediği çıkışların son basamağını sabitler. .insert ~n,?.Parantez olmadan -1 bayt daha .
Nnnes

3

C (gcc) ,157 152 bayt

long intDaha büyük test durumlarıyla çalışabilmesi için 64 bit gerekir.

Peter Cordes sayesinde -5 bayt

#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;}}

Çevrimiçi deneyin!

edit: bir satırsonu ayırıcı ile ayrılmış iki dizgenin çıkışına izin verilirse birkaç bayt tıraş edilebilir:

149 bayt:

#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;}}

edit: bu teslim en uzun değil, yay!


2
printf(z+r)Herhangi bir %karakter içermiyorsa kullanabilirsiniz . (Bu kod golf; güvenlik ve iyi uygulamalar pencereden dışarı çıkar: P). puts(z+r)Ücretsiz olarak yeni bir satır almak için de kullanabilirsiniz ( puts("")ikinci sürümde kaydederek ).
Peter Cordes

Teşekkürler! Doğrudan bir desen olarak bir char * sağlamayı unuttum, bu gerçekten birkaç bayt tasarruf :-) Her ikinci ondalık
koya

Ah, bu son bölüm yorum yapılmamış bir versiyon olmadan belli değildi.
Peter Cordes

floatdaha kısa double, ancak soru bir doubleveya dize girişi gerektiriyor gibi görünüyor .
Peter Cordes

1
Buna gerek yok. C'nin bazı yaygın uygulamaları 64 bitliktir longve kod golf kurallarına göre cevabınızın geçerli olması için ihtiyacınız olan her şey budur. (Ayrıca, C ve C ++ kod golf cevapları için 's yaygın 64-bit varsaymak longÇevrimiçi kullanımları Deneyin ne anlama yıllardan beri.) Ben Düzenlemenizi geri alma ve tıpkı bir not eklemenizi öneririz ediyorum " longiçin 64 bit olmalıdır bu, daha büyük test senaryolarını desteklemek için. "
Peter Cordes

2

Mathematica 47 Bayt

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

RealDigitsİlk olarak ondalık basamağın solundaki basamak sayısını bulmak için iki kez arama .


Durumda yardımcı olur: Ben sadece daha büyük destek numaralarının gerektiğini not ekledim 1e-6(küçüktür ve 1e15daha önce olduğu gibi,)
Luis Mendo

1
Sorunun sadece sorduğunu düşündüm ve TakeDrop@@RealDigits[##]sonra yanlış şeyler yaptığımı fark ettim - çözümünüz optimal görünüyor.
Mark

2

SageMath , 68 bayt

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

Çevrimiçi deneyin!


Yardımcı olması durumunda: Sadece daha önce 1e-6(daha 1e15önce olduğu gibi) daha büyük sayıları desteklemeniz gerektiğini bir not ekledim
Luis Mendo

1

Haskell , 188 bayt

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

Çevrimiçi deneyin!

g sayıyı verilen bir tabanda o sayıyı temsil eden bir listeye dönüştürür

ztam sayıları harflerle eşler ( 36 = .)

h önceki işlevleri sayının tamsayı ve kesirli kısmına uygular.


1

Aksiyom, 566 bayt

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);"")

bu soru özellikle zordu; Bir şey yazarken bir süre sonra, rakamları korumak için bir makro kullanarak oluşturulan doğru sonuçlar () ... çok fazla golf yapılmaz ... sonuçlar:

(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

gerçek hedef, taban 2..36'ya her bir Float [k: = basamak ()] veya hesaplanan her sayıyı% pi veya% e olarak veya 1 / 3'teki gibi iki float / int bölümüne dönüştüren bir işlevdir. . ['oo' rakamları]

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

1

Aksiyom, 127 bayt

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)

Sonuçlar

(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

Son sıfır örneği için küçük bir sorunu var

 f(4.5,10,5)

'4.50000' değil '4.5' döndürür

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.