จัดรูปแบบจำนวนไบต์ที่กำหนดเป็นรูปแบบที่มนุษย์สามารถอ่านได้


16

ความท้าทายและแหล่งกำเนิด

ใน Stack Overflow คำถามยอดนิยมคือ: วิธีการแปลงขนาดไบต์เป็นรูปแบบที่มนุษย์อ่านได้ใน java? คำตอบที่โหวตมากที่สุดมีวิธีที่ดีมากในการทำสิ่งนี้ แต่นี่คือ codegolf และเราทำได้ดีกว่าใช่ไหม?

ความท้าทายของคุณคือการเขียนวิธีการหรือโปรแกรมที่ครอบคลุมจำนวนไบต์ที่กำหนดให้กับรูปแบบที่มนุษย์สามารถอ่านได้ที่ถูกต้องและพิมพ์ผลลัพธ์ออกมาเป็นมาตรฐานของภาษาของคุณ *

* ดูกฎสำหรับการชี้แจงเพิ่มเติม!

อินพุต

อินพุตจะเป็นจำนวนบวกเสมอโดยมีค่าสูงสุด (2 ^ 31) -1

เอาท์พุต

คุณอาจเลือกหากคุณต้องการระบบนานาชาติของหน่วยหรือสัญกรณ์ไบนารี่เป็นผลลัพธ์ (สัญกรณ์ SI อาจช่วยคุณประหยัดได้ไม่กี่ไบต์)

SI:      B, kB,  MB,  GB  
Binary:  B, KiB, MiB, GiB

หมายเหตุ: หน่วยที่สูงกว่า GB หรือ GiB จะไม่สามารถตั้งค่าได้เนื่องจากช่วงอินพุตที่ถูก จำกัด

ตัวอย่างผลลัพธ์

ระบบหน่วยสากล:

Input       Output
0           0.0     B
999         999.0   B
1000        1.0     kB
1023        1.0     kB
1024        1.0     kB
1601        1.6     kB
160581      160.6   kB
4066888     4.1     MB
634000000   634.0   MB
2147483647  2.1     GB

ไบนารี่:

Input       Output
0           0.0     B
999         999.0   B
1000        1000.0  B
1023        1023.0  B
1024        1.0     KiB
1601        1.6     KiB
160581      156.8   KiB
4066888     3.9     MiB
634000000   604.6   MiB
2147483647  2.0     GiB

กฎระเบียบ

  • ไม่อนุญาตให้ใช้ฟังก์ชั่น Build-in สำหรับการจัดรูปแบบไบต์!
  • ผลลัพธ์ควรอยู่ในมาตรฐานสัญกรณ์เดียวกันคุณไม่สามารถผสม SI หรือไบนารีได้
  • เอาต์พุตควรอยู่ในหน่วยที่ใหญ่ที่สุดเท่าที่เป็นไปได้โดยที่จำนวนผลลัพธ์ยังคงสูงกว่าหรือเท่ากับหนึ่ง
  • ผลลัพธ์ควรมีเลขทศนิยมหนึ่งตัวเสมอ แต่คุณอาจเลือกที่จะพิมพ์ตัวเลขจำนวนเต็มเมื่อผลลัพธ์ที่ได้นั้นเป็นไบต์ (B)
  • คุณสามารถเลือกได้ว่าต้องการเพิ่มช่องว่างแท็บหรืออะไรระหว่างตัวเลขกับหน่วย
  • รับอินพุตผ่าน STDIN หรือพารามิเตอร์ฟังก์ชัน
  • เอาต์พุตถูกพิมพ์ไปยังคอนโซลหรือส่งคืนเป็นสตริง (หรือคอนเทนเนอร์อักขระที่คล้ายกัน);
  • นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดชนะ มีความสุข!

แก้ไข: ชี้แจงเพิ่มเติม

ตัวเลขบางตัวมีพฤติกรรมการปัดเศษที่น่าสนใจเช่นหมายเลข 999950 การใช้รหัสส่วนใหญ่จะส่งคืน 1,000.0 kB แทน 1.0 MB ทำไม? เนื่องจาก 999950/1000 ประเมินเป็น 999.950 ซึ่งจะถูกปัดเศษเป็น 1,000.0 อย่างมีประสิทธิภาพเมื่อใช้ String.format ใน Java (ในภาษาอื่น ๆ ส่วนใหญ่เช่นกัน) Hench จำเป็นต้องมีการตรวจสอบเพิ่มเติมเพื่อจัดการกับกรณีเช่นนี้

สำหรับความท้าทายนี้ทั้งสองสไตล์ยอมรับ 1,000.0 kB และ 1.0 MB แม้ว่าจะต้องการสไตล์ล่าสุดก็ตาม

รหัสหลอก / รหัสทดสอบ java:


public static String bytesToSI(long bytes){
      if (bytes < 1000){
          return bytes + ".0 B";
      }
      //Without this rounding check:
      //999950    would be 1000.0 kB instead of 1.0 MB
      //999950000 would be 1000.0 MB instead of 1.0 GB
      int p = (int) Math.ceil(Math.log(bytes) / Math.log(1000));
      if(bytes/Math.pow(1000, p) < 0.99995){
          p--;
      }
      //Format
      return String.format("%.1f %sB", bytes/Math.pow(1000, p), "kMGTPE".charAt(p-1));
}


1
ในทางเทคนิค SI กิโลไบต์ควรใช้kB(หมายเหตุ k ตัวพิมพ์เล็ก)
SuperJedi224

จุดดีคงที่!
Rolf ツ

1
ฉันไม่ต้องการ จำกัด ให้มากดังนั้นฉันจะบอกว่าระยะห่างอาจไม่สอดคล้องกัน แต่ด้วยกฎนี้: ความแตกต่างของอักขระเว้นวรรคและแท็บสำหรับอินพุตที่ถูกต้องที่แตกต่างกันอาจไม่เกิน 10 (เพื่อให้ทุกอย่างเป็น "มนุษย์อ่านได้")
Rolf ツ

2
ผลลัพธ์ที่คาดหวังสำหรับ999999และ1000000คืออะไร 160581การจัดแสดงนิทรรศการการปัดเศษดังนั้นมันควรจะเป็น1000.0kBและ1.0MB?
Sp3000

3
@ Sp3000 เป็นคำถามที่ดีทางออกที่ดีที่สุดคือราคา 999999 ที่แสดง 1.0 MB แต่สำหรับความท้าทายนี้ฉันจะบอกว่า 1,000.0 KB และกรณีการปัดเศษที่คล้ายกันก็ดีเช่นกัน
Rolf ツ

คำตอบ:


10

TI-BASIC, 44

จะเป็นเครื่องมือที่เหมาะสมสำหรับงานถ้า TI-BASIC มีการจัดการสตริงที่เหมาะสมครึ่งทาง (ฉันต้องหันไปเขียนทับเลขชี้กำลังของตัวเลขที่แสดงในสัญลักษณ์ทางวิศวกรรมพร้อมหน่วย) เนื่องจากเป็นรอบและแสดงผลถูกต้อง แต่ไม่ใกล้เคียงกับรายการที่ชนะ บางทีภาษาเครื่องคิดเลขที่แตกต่างกันสามารถชนะสิ่งนี้

Fix 1
Eng
ClrHome
Disp Ans
Output(1,15,sub(" kMG",1+iPart(log(Ans+.5)/3),1)+"B

ป้อนข้อมูลในแบบฟอร์ม[number]:[program name]บนหน้าจอหลัก

รับกรณีทดสอบ:

Input       Output (leading spaces intentional; screen clear before each output)
0                      0.0 B
999                  999.0 B
1000                   1.0kB
1023                   1.0kB
1024                   1.0kB
1601                   1.6kB
160581               160.6kB
4066888                4.1MB
634000000            634.0MB
2147483647             2.1GB

ฉันไม่รู้เลยว่า TI-BASIC นั้นมีประโยชน์มากมายฮ่า ๆ
Beta Decay

1
TI-BASIC ไม่ได้ใช้งานได้หลากหลาย แต่มักจะมีวิธีการแก้ไขที่แปลกสำหรับข้อบกพร่องบางประการ
lirtosiast

6

CJam, 35 27 ไบต์

ri{_e-3_i}g;1mOo]," kMG"='B

ขอบคุณเดนนิสที่ลบข้อมูล 8 ไบต์

สิ่งนี้ไม่ได้พิมพ์.0ในล่ามออนไลน์ล่ามออนไลน์แต่ดังที่เดนนิสได้ชี้ให้เห็นมันทำงานได้ดีในล่าม Java

คำอธิบาย

ri         e# Read the input as an integer.
{          e# Do:
    _e-3   e#   Make a copy and divide by 1000.
           e#   This will generate one more item in the stack for each iteration.
    _i     e#   Make a copy and truncate to integer.
}g         e# until the integer part is 0.
;          e# Discard the final value with integer part 0.
1mOo       e# Output the number before it with the correct format.
],         e# Count the number of iterations - 1.
" kMG"=    e# Select a character according to the number of iterations.
'B         e# Output B.

ri{_e-3XmO_i}g;o]," kMG"='B(27 bytes)
Dennis

1mOขอบคุณสำหรับ @Dennis แต่รหัสนี้ใช้ไม่ได้กับ1149999...
jimmy23013

ri{_e-3_i}g;1mOo]," kMG"='Bควร
Dennis

เกาที่มีข้อบกพร่องอื่น ๆ
Dennis

9999991000kBจะกลายเป็น อ่านคำถามอีกครั้งฉันไม่แน่ใจว่า1000kBจริงจะผิด
Dennis

5

Pyth, 29 27 ไบต์

p@" kMG"Js.lQK^T3.RcQ^KJ1\B

สาธิต. สายรัดทดสอบ

คำอธิบาย:

p@" kMG"Js.lQK^T3.RcQ^KJ1\B
                                 Implicit: Q = eval(input())
p                                print, in the order 2nd arg then 1st arg:
             K^T3                K = 10^3 = 1000
          .lQK                   log of Q base K
         s                       Floored
        J                        Store to J
 @" kMG"J                        The Jth character of ' kMG'
                     ^KJ         K^J
                   cQ            Q/K^J (Floating point division)
                 .R     1        Round to 1 decimal place.
                         \B      Print a trailing 'B'.

3

CJam, 28

r_dA@,(3/:X3*#/1mO" kMG"X='B

ลองออนไลน์

หมายเหตุ: มันไม่ได้แสดง" 0.0" กับล่ามออนไลน์, แต่ไม่ได้อย่างเป็นทางการล่ามภาษาจาวา

คำอธิบาย:

r_          read and duplicate
dA          convert to double and push 10
@           bring the initial string to the top
,(          get the length and decrement
3/          divide by 3 (for thousands)
:X3*        store in X and multiply by 3 again
#           raise 10 to that power
/           divide the original number by it
1mO         round to 1 decimal
" kMG"X=    convert X from 0/1/2/3 to space/k/M/G
'B          add a 'B'

Backtick คืออะไร
Dennis

@Dennis กำลังแสดง. 0 ในล่ามออนไลน์
aditsu

มันทำงานได้ดีในล่าม Java ที่ไม่มี backtick ดังนั้นฉันไม่คิดว่าคุณต้องการ
Dennis

3

Python 2 - 76 ไบต์

ใช้ระบบนานาชาติของหน่วยเพียงเพราะง่ายต่อการทำในหัวของคุณ;)

n=input();m=0;f=1e3
while n>=f:n/=f;m+=2
print"%.1f%s"%(n,'B kBMBGB'[m:m+2])

ดูเหมือนว่าจะไม่เป็นไรสำหรับฉันมันไม่เคารพการจัดรูปแบบที่ถามสำหรับตัวอย่างถ้าฉันส่ง "2147483647" ฉันได้รับ "2.000000GB" - คำถามจะถามหนึ่งทศนิยมและอาจเว้นวรรค
Dieter

1
นอกจากนี้เป็น 79 ไบต์ตามนี้ นี่คือ 75 ไบต์ ฉันไม่เชื่อว่ามีการระบุว่าจำเป็นต้องมีช่องว่างระหว่างหมายเลขและหน่วย
Kade

คุณสามารถบันทึกหนึ่งไบต์ด้วยf=1e3
mbomb007

@ mbomb007 ที่จริงแล้วมันบันทึก 2 ไบต์เพราะ 1e3 เป็นทุ่น
Beta Decay

ฉันรู้ว่ามันลอย ฉันเดาว่าฉันไม่สามารถนับได้ ...
mbomb007

2

PowerShell 190

$x=Read-Host
function f($a,$b){"$x`t"+[math]::Round($x/$a,1).ToString("F1")+"`t$b"}
if(1KB-gt$x){f 1 "B"}elseif(1MB-gt$x){f 1KB KiB}
elseif(1GB-gt$x){f 1MB MiB}elseif(1TB-gt$x){f 1GB GiB}

การใช้

PS C:\> .\makehum.ps1
1601
1601    1.6     KiB
PS C:\> .\makehum.ps1
4066888
4066888 3.9     MiB
PS C:\> .\makehum.ps1
160581
160581  156.8   KiB
PS C:\> .\makehum.ps1
634000000
634000000       604.6   MiB
PS C:\> .\makehum.ps1
2147483647
2147483647      2.0     GiB
PS C:\>

2

Haskell, 119

ฉันเศร้าไม่ได้หาวิธีที่สั้นกว่าใน Haskell เพื่อให้แน่ใจว่าทศนิยม 1 ตำแหน่งในการลอย แต่ฉันโพสต์สำหรับลูกหลาน

import Text.Printf
a#n|p>=1=(a+1)#p|1<2=(a,n)where p=n/1000
m n=let(a,b)=0#n in printf"%.1f"b++["B","kB","MB","GB"]!!a

การใช้งาน:

> m 160581
"160.6kB"

รุ่น golfed น้อยกว่าปานกลาง:

import Text.Printf

countThousands :: Int -> Float -> (Int, Float)
countThousands count num
 |nextNum >= 1 = countThousands (count+1) nextNum
 |otherwise    = (count,num)
 where nextNum = num/1000

printHuman :: Float -> String
printHuman n = let (a,b) = countThousands 0 n in 
  (printf "%.1f" b) ++ (["B","kB","MB","GB"]!!a)

2

Java, 106 ไบต์

คนนี้เป็นวิธีการที่ใช้ตัวเลขและส่งกลับสตริง

String f(int n){int k=0;for(;n>1e3;k++)n/=1e3;return(int)(10*n)/10.0+new String[]{"","k","M","G"}[k]+"B";}

คุณได้รับอนุญาตให้ตั้งค่าฟังก์ชั่นที่คืนค่าสตริงแทนที่จะเป็นโปรแกรมที่สมบูรณ์มันอาจช่วยคุณประหยัดไบท์ได้)
Rolf ツ

สามสิ่ง: หากคุณแปลง a เป็นสองเท่า (ฉันไม่รู้ว่าจำเป็นหรือไม่) คุณสามารถใช้1e3สำหรับ1000; คุณสามารถแปลงwhile()เป็น a for()และใช้เซมิโคลอนฟรี; และฉันไม่รู้ว่ามันใช้งานได้หรือไม่เพราะดูเหมือนว่าจะแสดงตัวเลขทศนิยมทั้งหมดไม่ใช่แค่ตำแหน่งทศนิยมที่ผ่านมา
lirtosiast

@ThomasKwa: ครั้งสุดท้ายที่ฉันตรวจสอบคำถามดูเหมือนจะไม่ระบุอย่างชัดเจน แต่ตอนนี้ฉันเดาแล้ว
SuperJedi224

1

Python 2, 127 ไบต์

การใช้ ISU ตัวอย่างประกาศฟังก์ชัน 'C' ที่ใช้จำนวนที่จะถูกแปลงเป็นอาร์กิวเมนต์

C=lambda v:min(['%.1f %sB'%(x,u)for x,u in[(v/1000.0**i,'bkMG'[i])for i in range(4)]if x>=1]).replace('.0 b',' ')if v else'0 B'

รหัสทดสอบบางส่วน:

    print 'Input\tOutput'
for v in [0,999,1000,1023,1023,1601,160581,4066888,634000000,2147483647]:
 print v,C(v)

คุณสามารถใช้1e3แทน1000.0
mbomb007

1

JavaScript ( ES6 ), 71

ใช้หน่วย SI - ฟังก์ชั่นกลับสตริงที่ร้องขอ

f=(a,b=3)=>+(r=eval('a/1e'+b*3).toFixed(1))[0]?r+' kMG'[b]+'B':f(a,b-1)

อันที่สั้นกว่านี้เป็นไปตามกฎโดยเฉพาะ 3 และ 4

  • เอาต์พุตควรอยู่ในหน่วยที่ใหญ่ที่สุดเท่าที่เป็นไปได้โดยที่จำนวนผลลัพธ์ยังคงสูงกว่าหรือเท่ากับหนึ่ง 995 => 1.0kB
  • ผลลัพธ์ควรมีเลขทศนิยมหนึ่งตัวเสมอ แต่คุณอาจเลือกที่จะพิมพ์ตัวเลขจำนวนเต็มเมื่อผลลัพธ์ที่ได้เป็นไบต์ (B) ฉันเลือกไม่ดังนั้น 10 => 10.0 B

อนิจจาด้วยวิธีนี้ผลลัพธ์ไม่ตรงกับตัวอย่าง

เพื่อให้ตรงกับตัวอย่างนี่คืออีกหนึ่งความยาวพิเศษสำหรับกล่องขนาดเล็ก (82 ไบต์)

f=(a,b=3)=>a<1e3?a+'B':+(r=eval('a/1e'+b--*3).toFixed(1))[0]?r+'kMG'[b]+'B':f(a,b)

เรียกใช้ตัวอย่างเพื่อทดสอบ (เป็น EcmaScript 6, Firefox เท่านั้น)


1

Python ขนาด 61 ไบต์

f=lambda n,i=0:"%.1f%cB"%(n," kMG"[i])*(n<1e3)or f(n/1e3,i+1)

f(999)โทรเช่น สังเกตได้ว่า1e3เป็นแบบลอยดังนั้นจึงใช้ได้กับทั้ง Python 2 และ Python 3


1

PHP4.1, 63 62 ไบต์

ไม่ใช่สนามกอล์ฟที่ดีที่สุด แต่ก็ค่อนข้างสั้น

<?for($S=kMG;$B>1e3;$I++)$B/=1e3;printf("%.1f{$S[$I-1]}B",$B);

หากต้องการใช้งานให้เข้าถึง POST / GET หรือตั้งค่าใน SESSION บนปุ่ม Bหรือตั้งค่าในเซสชั่นบนที่สำคัญ

ปล่อยให้Iไม่มีการตั้งค่าคีย์!


1

SpecBAS - 100 ไบต์

ใช้การประชุม ISU

ฉันรู้ว่าการตั้งค่าตัวแปรเป็น 1e3 (ซึ่งต้องการคำสั่ง LET เพื่อกำหนดมัน) จากนั้นใช้ตัวแปรนั้นในการออกกำลังกายจริง ๆ แล้วใช้อักขระมากกว่าตัวอักษรเพียง 1e3 ที่ต้องการ

1 INPUT n: LET i=1
2 DO WHILE n>1e3: LET n=n/1e3: INC i: LOOP 
3 PRINT USING$("&.*0#",n);" kMG"(i);"B"

1

Ruby, 128 ไบต์

c=->i{p i.to_s+'B'if i<1e3;p (i/1e3).to_s+'kB'if i>=1e3&&i<1e6;p (i/1e6).to_s+'MB'if i>=1e6&&i<1e9;p (i/1e9).to_s+'GB'if i>=1e9}

ฉันทำไปไกลแล้วนี่แย่มาก

เอาท์พุต

c[0] # => "0B"
c[999] # => "999B"
c[1000] # => "1.0kB" 
c[1023] # => "1.023kB"
c[1024] # => "1.024kB"
c[1601] # => "1.601kB"
c[160581] # => "160.581kB"
c[4066888] # => "4.066888MB"
c[634000000] # => "634.0MB"
c[2147483647] # => "2.147483647GB"

แก้ไข

เพิ่ม TB สำหรับ 39 ไบต์พิเศษ

c=->i{p i.to_s+'B'if i<1e3;p (i/1e3).to_s+'kB'if i>=1e3&&i<1e6;p (i/1e6).to_s+'MB'if i>=1e6&&i<1e9;p (i/1e9).to_s+'GB'if i>=1e9&&i<1e12;p (i/1e12).to_s+'TB'if i>=1e12}

เอาท์พุท:

c[1000000000000] # => "1.0TB"

1

Sed -r, 218 + 1

ฉันใช้หน่วย SI ผมคิดว่าการเลือกหน่วยไบนารีจะเป็นนโยบายที่กล้าหาญ ;-)

s/(.)((...)+)$/\1z\2/;h;s/[^z]*z?//;s/.../k/g;s/kk/M/;s/Mk/G/;x;s/(z.)[5-9].*/\1c/;s/(z.c?).*/\1/;:;s/9c/c0/;s/zc/cz/;t;s/(^|0)c/1/;s/1c/2/;s/2c/3/;s/3c/4/;s/4c/5/;s/5c/6/;s/6c/7/;s/7c/8/;s/8c/9/;G;s/\n//;s/$/B/;y/z/./

จัดรูปแบบ:

#!/bin/sed -rf

# Place decimal point (use z as shorthand for \.)
s/(.)((...)+)$/\1z\2/
h

# count thousands into hold space
s/[^z]*z?//
s/.../k/g
s/kk/M/;s/Mk/G/
x

# truncate to 1 decimal place
s/(z.)[5-9].*/\1c/
s/(z.c?).*/\1/

# propagate carry
:
s/9c/c0/
s/zc/cz/
t
s/(^|0)c/1/
s/1c/2/
s/2c/3/
s/3c/4/
s/4c/5/
s/5c/6/
s/6c/7/
s/7c/8/
s/8c/9/

# Append units
G;s/\n//
s/$/B/
y/z/./

เอาท์พุต

1 => 1B
9 => 9B
99 => 99B
999 => 999B
1000 => 1.0kB
9999 => 10.0kB
99949 => 99.9kB
99950 => 100.0kB
99999 => 100.0kB
999999 => 1000.0kB
9999999 => 10.0MB
9999999999 => 10.0GB
1000 => 1.0kB
10000 => 10.0kB
10005 => 10.0kB
10440 => 10.4kB
10450 => 10.5kB
10950 => 11.0kB

รูปแบบ

กฎดูเหมือนจะบ่งบอกถึงรอบที่ใกล้ที่สุด แต่สำหรับการแสดงของมนุษย์ฉันเชื่อว่าการปัดเศษลงเป็นทางเลือกที่ยอมรับได้และช่วยประหยัด 123 ไบต์ (ดีกว่า 50%):

s/(.)((...)+)$/\1.\2/;h;s/[^\.]*\.?//;s/.../k/g;s/kk/M/;s/Mk/G/;x;s/(\..).*/\1/;G;s/\n//;s/$/B/

ส่วนขยายตามธรรมชาติไปยังหน่วยที่ใหญ่กว่า (ยังคงปัดเศษลง 130 + 1 ไบต์):

s/(.)((...)+)$/\1.\2/;h;s/[^\.]*\.?//;s/.../k/g;s/kk/M/g;s/Mk/G/;s/MM/T/g;s/TT/Y/;s/TM/E/;s/TG/Z/;x;s/(\..).*/\1/;G;s/\n//;s/$/B/

รูปแบบผลลัพธ์:

1 => 1B
9 => 9B
99 => 99B
999 => 999B
1000 => 1.0kB
9999 => 9.9kB
99949 => 99.9kB
99950 => 99.9kB
99999 => 99.9kB
999999 => 999.9kB
9999999 => 9.9MB
9999999999 => 9.9GB
1000 => 1.0kB
10000 => 10.0kB
10005 => 10.0kB
10440 => 10.4kB
10450 => 10.4kB
10950 => 10.9kB
1000000000 => 1.0GB
1000000000000 => 1.0TB
1000000000000000 => 1.0MGB
1000000000000000000 => 1.0EB
1000000000000000000000 => 1.0ZB
1000000000000000000000000 => 1.0YB
999999999999999999999999999 => 999.9YB

เยี่ยมมาก! ฉันชอบที่คุณคิดเกี่ยวกับตัวเลือกต่าง ๆ ทั้งหมด!
Rolf ツ

1

C, 77 75

f(float l){char*u=" kMG";while((l/=1e3)>=1)++u;printf("%.1f%cB",l*1e3,*u);}

สิ่งนี้ใช้หน่วย SI และใช้ตัวเลือก 1000.0kB สำหรับการปัดเศษ

รหัสขยาย:

f(float l)
{
    char *u = " kMG";
    while ((l/=1000) >= 1)
        ++u;
    printf("%.1f%cB", l*1000, *u);
}

เอาท์พุต

9 => 9.0 B
9999 => 10.0kB
1023 => 1.0kB
1024 => 1.0kB
999990 => 1000.0kB
1048575 => 1.0MB
1048576 => 1.0MB
2147483647 => 2.1GB

สายพันธุ์

หากต้องการรับหน่วยไบนารีให้เปลี่ยน1000เป็น1024และเพิ่มลงiในสตริงรูปแบบหากมีตัวคูณ เพื่อหลีกเลี่ยงการปัดเศษ 4 หลักเปรียบเทียบแทน>=.95 >=1หากต้องการยอมรับหน่วยที่ใหญ่ขึ้นให้ขยายuสตริง เมื่อรวมตัวเลือกทั้งหมดเข้าด้วยกันเราจะได้รับ:

f(float l)
{
    char*u=" kMGTPEZY";
    while((l/=1024)>=.95)++u;
    printf(*u-' '?"%.1f%ciB":"%.0fB",l*1024,*u);
}

เอาต์พุตตัวแปร

9 => 9B
9999 => 9.8kiB
1023 => 1.0kiB
1024 => 1.0kiB
999990 => 1.0MiB
1048575 => 1.0MiB
1048576 => 1.0MiB
2147483647 => 2.0GiB
1000000000 => 953.7MiB
1000000000000 => 931.3GiB
1000000000000000 => 909.5TiB
1000000000000000000 => 888.2PiB
1000000000000000000000 => 867.4EiB
1000000000000000000000000 => 847.0ZiB
999999999999999999999999999 => 827.2YiB
1176043059457204080886151645 => 972.8YiB

โปรแกรมทดสอบ

ส่งผ่านอินพุตจำนวนเท่าใดก็ได้เป็นอาร์กิวเมนต์บรรทัดคำสั่ง:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    while (*++argv) {
        printf("%s => ", *argv);
        f(strtod(*argv, 0));
        puts("");
    }
    return 0;
}

Nice one;) ดำเนินการได้ดี!
Rolf ツ

0

Ruby, 91 ไบต์

n=gets.to_i;i=0;while n>1023;n/=1024.0;i+=1;end;puts "#{n.round 1} #{%w[B KiB MiB GiB][i]}"

ฉันอาจจะทำได้ดีกว่านี้เล็กน้อยถ้าฉันพยายามให้หนักขึ้น แต่นี่คือสิ่งที่ฉันทำได้


ใช้แทน1024. 1024.0
mbomb007

0

Javascript ES5, 69 ไบต์

นี้จะใช้วิธีการที่แตกต่างกันไปถึงเป้าหมายสุดท้ายที่คำตอบ @ edc65 ของ
จริงนี้เป็นสวยใกล้เคียงกับคำตอบของฉัน PHP

for(i=+prompt(z=0);i>1e3;z++)i/=1e3;alert(i.toFixed(1)+' kMG'[z]+'B')

เพียงแค่เรียกใช้ส่วนย่อยของสแต็กหรือวางลงบนคอนโซลของคุณ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.