質問

ウィキペディアの記事を踏まえると、 基数点, 、10.1 に相当する 2 進数、または 17.17 に相当する 16 進数はどのように計算すればよいでしょうか?前者の場合、10 分の 1 に相当する 2 進法は何でしょうか?後者の場合、17/100 の 16 進数表現?

私はこれら 2 つの例に対する解決策よりもアルゴリズムを探しています。

役に立ちましたか?

解決

10 進数 10.1 を 2 進数に変換するには、整数部分と小数部分を分離し、それぞれを個別に変換します。

整数部分を変換するには、整数を 2 で除算し、剰余を逆の順序で書き込みます。

10/2 = 5 余り 0

5/2 = 2 余り 1

2/2 = 1 余り 0

1/2 = 0 余り 1

答え:1010

小数部を変換するには、2 の乗算を繰り返し、各ステップで整数部を減算します。整数部分は生成順に 2 進数を表します。

0.1 * 2 = 0.2

0.2 * 2 = 0.4

0.4 * 2 = 0.8

0.8 * 2 = 1.6

0.6 * 2 = 1.2

0.2 * 2 = 0.4

0.4 * 2 = 0.8

...(サイクルは永遠に繰り返される)

つまり、10進数の0.1は2進数の0.000110011001100...

(より詳細な説明については、私の記事のルーチン dec2bin_i() および dec2bin_f() を参照してください。 http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ .)

16 進数の場合は、除数/乗数を 2 ではなく 16 にする点を除き、同じ手順を使用します。9 を超える剰余と整数部分は、16 進数に直接変換する必要があります。10 は A になり、11 は B になり、..., 15はFになります。

他のヒント

基底Bにおける着信番号(ディジットの有限数で表すことができる数)N <サブ> 1 <サブ> 1 、非終了数で終わることができます異なる基底Bにおける 2 。逆に、一つの基地Bにおいて非終了数<サブ> 1 基底Bにおける着信番号であることが判明するかもしれ 2

進数に変換するとき0.17 <サブ> 10 であるように、

数0.1 <サブ> 10 バイナリに変換されたとき、非終端番号です。しかし、10塩基に変換ベース3に着信番号0.1 <サブ> 3 非終端、番号0を繰り返す(3)<サブ> 10 (その数3反復を意味であります)。同様に、16進数にバイナリ0.17 <サブ> 10 0.1 <サブ> 10 変換、一方が数値0.0(0011)を繰り返す、非終端で終わる 2 0.2(B851E)<サブ> 16

別の基部からそのような数を変換する際に、

このため、自分自身ではなく、完全に正確な表現を有するの数を近似する必要があります。

このアルゴリズムは非常に簡単ですが、実際には、あなたはそれをスピードアップするためにルックアップテーブルとログとの両方の調整の多くを行うことができます。 しかし、基本的なアルゴリズムのために、あなたはこのような何かを試すことがあります:

shift=0;

while v>=base,  v=v/base, shift=shift+1;  

Next digit: 
if v<1.0 && shift==0, output the decimal point
else 
   D=floor(v)
   output D
   v=v-D
v=v*base
shift = shift-1
if (v==0) exit;
goto Next Digit

また、循環小数長くN桁の後に印刷を停止するには、そこにテストを置いてもよい。

10分の1 'バイナリ等価' が代わりに1/10 ^ 1のすなわち半分が、それは1/2 ^ 1です。

各桁は、2のべき乗を表します。小数点の後ろの数字が同じである、それは彼らが2の累乗の上に1を表していることだけです。

 8 4 2 1 . 1/2 1/4 1/8 1/16 

10.1だから、あなたは明らかに10の部分を作るために「8」と「2」が必要です。 1/2(0.5)が多すぎると、1/4(0.25)が1/8(0.125)が多すぎると、多すぎます。私たちは、0.0375で私たちを残している、1/16(0.0625)が必要です。 1/32は0.03125であるので、我々はあまりにもそれを取ることができます。これまでのところ、私たちは持っています:

 8 4 2 1 . 1/2 1/4 1/8 1/16 1/32
 1 0 1 0    0   0   0   1     1

0.00625のエラーで。 1/64(0.015625)と1/128(0.0078125)がともにあまり、1/256(0.00390625)に動作します:

 8 4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256
 1 0 1 0    0   0   0   1     1    0   0     1

0.00234375のエラーでます。

0.1は(1/3が正確に小数で表すことができないだけのような)バイナリで正確に表現できません。あなたの基数を置く場所にもよりますが、最終的には、おそらくラウンド、停止、およびエラーを受け入れなければならない。

私は私のGMPライブラリの光の中でこれをひねり前に、私は36までの2から任意の底のためのリック・リーガンのPHPコードはジェネリックにしようとしました。ここで、

、ここにあります。

Function dec2base_f(ByVal ddecimal As Double, ByVal nBase As Long, ByVal dscale As Long) As String
    Const BASES = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 'up to base 36
    Dim digitCount As Long
    Dim wholeNumber As Double
    Dim digit As String * 1
    digitCount = 0
    dscale = max(dscale, Len(CStr(ddecimal)) - Len("0."))
    Dim baseary_f As String
    baseary_f = "0."
    Do While ddecimal > 0 And digitCount < dscale
        ddecimal = ddecimal * nBase
        digit = Mid$(BASES, Fix(ddecimal) + 1)
        baseary_f = baseary_f & digit '"1"
        ddecimal = ddecimal - Fix(ddecimal)
        digitCount = digitCount + 1
    Loop
    dec2base_f = baseary_f
End Function

Function base2dec_f(ByVal baseary_f As String, nBase As Double) As Double
    Const BASES As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Dim decimal_f As Double
    Dim i As Long
    Dim c As Long
    For i = Len(baseary_f) To Len("0.") + 1 Step -1
        c = InStr(BASES, Mid$(baseary_f, i, 1)) - 1
        decimal_f = decimal_f + c
        decimal_f = decimal_f / nBase
    Next
    base2dec_f = decimal_f
End Function

Debug.Print base2dec_f(dec2base_f(0.09, 2, 200), 2) --> 0.09
Debug.Print base2dec_f(dec2base_f(0.09, 8, 200), 8) --> 0.09
Debug.Print base2dec_f(dec2base_f(0.09, 16, 200), 16) --> 0.09
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top