Bc ile dönüşüm durumunda “ibase” ve “obase” ı anladınız mı?


22

Genellikle bchex'i ondalık sayıya dönüştürmek için yardımcı program kullanırım . Ancak, her zaman bit deneme yanılmadır ve nasıl yapılandırılacağı ibaseve nasıl obaseyapılması gerektiği. Mesela burada C0 hex değerini ondalık karaktere dönüştürmek istiyorum:

$ echo "ibase=F;obase=A;C0" | bc
180
$ echo "ibase=F;obase=10;C0" | bc
C0
$ echo "ibase=16;obase=A;C0" | bc
192

Buradaki mantık nedir? obase( Aüçüncü örneğime göre) dönüştürülen değerle aynı temelde olmalı ( C0örneklerime göre) ve ibase( 16üçüncü örneğime göre) dönüştürdüğüm temelde olmalı?


1
hex hesaplamaları için (hex cinsinden giriş ve çıkış) ibase'den önce obase ayarlamam gerekiyor!
Paschalis

Yanıtlar:


36

Gerçekten söylemek istediğin şey şudur:

$ echo "ibase=16; C0" | bc
192

onaltılık-ondalık için ve

$ echo "obase=16; 192" | bc
C0

Ondalık-altıgen için.

Her iki vermek gerekmez ibaseve obase10 bu ayarları varsayılan beri, ondalık sayılar içeren herhangi dönüşüm için.

Sen do tür ikili-hex olarak dönüşümler için hem vermek gerekir. Bu durumda, önce verirseniz bir şeyleri anlamlandırmanın en kolay yolu olduğunu düşünüyorum obase:

$ echo "obase=16; ibase=2; 11000000" | bc
C0

ibaseBunun yerine ilk siz verirseniz , aşağıdaki obaseayarın yorumunu değiştirir , böylece komut şöyle olur:

$ echo "ibase=2; obase=10000; 11000000" | bc
C0

Bunun nedeni, bu siparişte obasedeğerin ikili bir sayı olarak yorumlanmasıdır, bu nedenle onaltılı olarak çıktı almak için 10000₂ = 16 vermeniz gerekir. Bu çok sakar.


Şimdi üç örneğinizin neden böyle davrandıklarına bakalım.

  1. echo "ibase=F;obase=A;C0" | bc

    180

    Bu giriş tabanını 15 ve çıkış tabanını 10 olarak ayarlar, çünkü POSIX'e göre tek basamaklı bir değer hex şeklinde yorumlanır . Bu, bcC0₁₅’nın A₁₅ = 10 üssünde ne olduğunu ve 180₁₀’e doğru cevap verdiğini söylemenizi ister, ancak bu kesinlikle sormak istediğiniz soru değildir.

  2. echo "ibase=F;obase=10;C0" | bc

    C0

    Bu, taban 15'deki boş bir dönüşümdür.

    Niye ya? İlk Folarak, önceki örnekte de belirttiğim gibi , tek basamak onaltılı olarak yorumlanmıştır. Ancak şimdi üs 15'e ayarladınız, aşağıdaki çıkış temel ayarı bu şekilde yorumlandı ve 10₁₅ = 15, bu nedenle C0₁₅ ile C0₁₅ arasında boş bir dönüşüme sahip olursunuz.

    Doğru, çıktı sandığınız gibi altıgen değil, 15 üssünde!

    Bunun F0yerine dönüştürmeye çalışarak bunu kendinize kanıtlayabilirsiniz C0. FTabanda (15) rakam bulunmadığından bconu sıkıştırır ve çıktı olarak E0verir E0.

  3. echo "ibase=16; obase=A; C0"

    192

    Muhtemelen pratik kullanımı olan üç örnekinizden sadece biri bu.

    Onaltılık giriş tabanını değişiyor ilk böylece artık gerek kazmak olduğunu, POSIX Spec anlamak için Abu durumda onaltılık, 10 olarak yorumlanır. Bununla ilgili tek sorun, çıkış tabanını A₁₆ = 10 olarak ayarlamanın fazlalık olması, çünkü varsayılan değer.


7

Ayar , aynı temelde ibaseayarlamanız gerektiği anlamına gelir obase. Örneklerinizi açıklamak şunu gösterecektir:

echo "ibase=F;obase=A;C0" | bc

Sen set bc"ibase = F" ile baz 15'de gösterildiği gibi giriş sayıları dikkate almak. "obase = A", çıkış numaralarını varsayılan 10 olan temel 10 a ayarlar.

bc C0'ı bir baz 15 sayı olarak okur: C = 12. 12 * 15 = 180.


echo "ibase=F;obase=10;C0" | bc

Bu ayarda, giriş 15 tabanına ayarlanır ve çıkış 15 - 15 tabanına, yani çıkış tabanı 15 olur. 15 tabanındaki C0 girişi 15 tabanındaki C0 çıkışıdır.


echo "ibase=16;obase=A;C0" | bc

Tabanı 16'ya ayarlayın, tabana 10 verin (tabanda 16 A, tabanda 10 10'dur).

10 tabanına dönüştürülen C0: 12 * 16 = 192


Benim kişisel kuralım, ilk önce obase'i ayarlamaktır, böylece 10 tabanını kullanabilirim.

Not bcyapar ironik bir istisna vardır: ibase=Ave obase=Ahep itibaren bankasına 10 giriş ve çıkış setleri bcadam sayfası:

Single digit numbers always have the value of the digit 
regardless of the value of ibase.

Bu davranış, aşağıdaki şartnamede belirtilmiştir bc: 2004 OpenGroup bcşartnamesinden :

When either ibase or obase is assigned a single digit value from 
the list in 'Lexical Conventions in bc', the value shall be assumed
in hexadecimal. (For example, ibase=A sets to base ten, regardless 
of the current ibase value.) Otherwise, the behavior is undefined 
when digits greater than or equal to the value of ibase appear in
the input.

Bu nedenle, ibase=Fayar giriş tabanınızı taban 15 olarak değiştirdi ve tabanını her zaman taban 10 kullanarak ayarlamamı önerdim.


@ StéphaneChazelas - 1989'da SysVr3 makinesinde çalışan "ibase = A" nın bir hatırasını öğrendim. Bahse girerim, Single Unix Spec. Daha önce bir ref.
Bruce Ediger,

Bunun nedeni, daha uzun süredir bulundukları için eski özelliklerle ilgili daha fazla bağlantı olması nedeniyle. Aynı şey apache / mysql / bugzilla ... dokümantasyonu için de geçerlidir, burada google size en eski sürümler için eski sürümler için dokümanı verir.
Stéphane Chazelas,

5

Tüm sayılar GNU bc tarafından sayının göründüğü ifade için geçerli giriş üssü olarak yorumlanır. Sayının içinde görünür. Geçerli girişin dışında bir basamak kullandığınızda, bunları bir kısmı zaman bazında mevcut en yüksek basamak (9'lu) olarak yorumlar. Çok basamaklı bir sayının veya tek basamaklı sayı olarak kullanıldığında normal değerleri olarak ( Aondalık sayı = = 10).

Gönderen manuel bc GNU :

Tek basamaklı sayılar, ibase değerinden bağımsız olarak daima basamaktaki değere sahiptir . (örn. A = 10.) Çok basamaklı sayılar için, bctüm giriş basamaklarını büyük veya eşittir ibase ile ibase -1 değerine değiştirir . Bu, sayıyı FFFher zaman giriş tabanının en büyük 3 haneli numarası yapar .

Ancak, POSIX standardı yalnızca atamaları için bu davranışı tanımlar bilmelidir ibaseve obasedeğil de başka bir bağlamda.

Gönderen bc üzerinde SUS şartname :

Ya zaman ibase veya obase tek atanır basamaklı bc Sözcük Sözleşmeleri listeden değer, değer onaltılık kabul edilecektir. (Örneğin, ibase = A, mevcut ibase değerine bakılmaksızın, on tabanına ayarlanır .) Aksi halde, girdide ibase değerinden daha büyük veya ona eşit olan rakamlar göründüğünde davranış tanımlanmaz . Hem ibase hem de obase , 10 başlangıç ​​değerine sahip olacaktır.

Kaçırdığınız temel faktör, F'nin aslında on altı olmadığı, aslında onbeş olduğu, yani ibase = F ayarını yaparken, giriş tabanını onbeşe ayarlıyorsunuz.

Portably bilinmeyen bir durumdan onaltılık IBase ayarlamak için nedenle, bu nedenle iki ifadeleri kullanmak gerekir: ibase=A; ibase=16. Ancak, programın başında, ondalık olmasına ve basitçe kullanmasına güvenebilirsiniz ibase=16.


+1: Sevimli numara ibase=A; ibase=16.
Warren Young,


Her zaman başlıklardaki 6 ve 7'nin sürüm olduğunu sanırdım. Daha önce hiç farklı bir şey görmedim - sayı 1-5 nedir?
Random832,

@ Random832: SUS ve POSIX aynı şey değil .
Warren Young,

@WarrenYoung SUS, POSIX içermez mi? Bu paragrafın bir uzatma etiketi yoktur ve belgede baştan sona "bu POSIX.1-2008 biriminin parçası" gibi şeyler yazmaktadır.
Random832

0

Man sayfasına göre bir sayı yerine her zaman tek basamaklı bir sayı ayarlamanız ibaseve obasekullanmanız önerilir.16bc

Tek basamaklı sayılar, ibase değerinden bağımsız olarak daima basamaktaki değere sahiptir.

Bu , değerinin ne olduğuna bakılmaksızın A,B,...,Fher zaman 10,11,...,15sırasıyla değerlere sahip olduğu anlamına gelir ibase. F+1Numara belirtmek için de kullanabilirsiniz 16. Mesela, yazsan iyi olur

echo "ibase=F+1; obase=A; C0" | bc

echo "ibase=16; obase=A; C0" | bcgirdi tabanının 16ve çıktı tabanının olduğunu belirtmek için yazmak yerine 10. Örneğin, ikisini de ibaseve obase16 olmak istiyorsanız, daha iyi kullanmak

ibase=F+1; obase=F+1

kullanmak yerine ibase=16; obase=10. Benzer şekilde, numaralarınızı 14 tabanına girip bunları 16 tabanına verecekseniz,

ibase=E; obase=F+1

Her ne kadar banyo formları aynı sonuçlara sahip olsa da, birincisi daha az hata eğilimi gösterirken, ikincisi daha fazla kafa karışıklığına ve hataya yol açabilir.

İki form arasındaki fark özellikle, yürütme ortamında olduğunuzda bcveya hesaplamalarınızı bir dosyaya yazdığınızda ve daha sonra bu dosyayı bcbir argüman olarak ilettiğinizde daha belirgin hale gelir . Böyle durumlarda, değerlerini değiştirmek gerekebilir ibaseve obasebirkaç kez, ve ikincisi formu kullanarak, ciddi karışıklığa ve hatalara yol açabilir. (deneyimlemek)

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.