1

10 進整数を 2 進表現に変換するプログラムを作成しています。これが私のコードです:

program test
implicit none
integer, dimension(:), allocatable :: binary
integer :: decimalnum, i, initvalue

print*, "Enter decimal number to convert: "
read*,initvalue

decimalnum = initvalue
i = 0

do while (decimalnum > 0)
    if (MOD(decimalnum,2)==0) then
        binary(i) = 0                  ! this is as far as the program executes up to 
        decimalnum = decimalnum / 2
        i = i + 1
    else if (MOD(decimalnum,2)==1) then
        binary(i) = 1
        decimalnum = (decimalnum -1) / 2
        i = i + 1
    end if
end do
end program test

マークされたポイントで、エラーSegmentation faultを返し、コード 139 で終了します。

なぜこれが起こるのですか?

前もって感謝します。

4

4 に答える 4

3

整数iをバイナリ表現に変換する簡単な方法を次に示します。

write(*,'(b16)') i

書かれているように、これは先頭の s を書き込みません00先頭の sが必要な場合は、試してください

write(*,'(b16.16)') i

もちろん、上記のコードはバイナリ表現をデフォルトの出力ユニットに書き込みますが、Fortran の内部書き込み機能を使用すると、ビットを文字変数に簡単に書き込むことができます。例えば:

character(len=16) :: bits
...
write(bits,'(b16.16)') i

の 2 進数をi文字変数 に書き込みますbits

ここで、それぞれがバイナリ表現の 1 ビットを表す整数の配列を作成することが本当に必要な場合は、次のようになります。

integer, dimension(16) :: bitarray
...
bitarray = 0
...
do ix = 1,len(bits)
    if (bits(ix:ix)=='1') bitarray(ix) = 1
end do

おそらくうまくいくでしょう。

于 2012-10-08T08:50:02.587 に答える
2

1) クラッシュが発生するのは、配列 binary(:) に 1 つの要素しか割り当てておらず、While ループがおそらく i = 2 に移動したためです。この時点で、配列のインデックスは範囲外 (クラッシュ) になります。

2) Fortran には、ビットを直接処理する多くの組み込み関数があります。例えば、

a) Bit_Size(var) は「var」のビット数を返すため、アロケータブルを使用する必要がある場合は、事前に必要な配列サイズがわかります。

b) BTest(iVar, pos) は .True を返します。iVar の pos のビットが 1 の場合

たとえば、上記の他の宣言を使用すると、次のようになります。

Integer     :: n

n = Bit_Size(decimalnum)    

If( Allocated(Binary) ) DeAllocate(Binary)          ! good practice
Allocate( Binary(1:n) )                             ! in general, should get IOStat, just in case

Binary(:) = 0

ForAll(i=1:n, Mask = BTest( decimalnum, i-1 ) ) ! remember, bit intrinsics index from 0
    Binary(i) = 1
End ForAll

...これは Do や While に比べて少し効率的で、smp に (少し) 役立つ可能性があります。Where/EndWhere コンストラクトも使用できますが、ForAll の方が少し効率的です。

c) IBits(var, pos, len) は var からビット数 len の pos から始まるビットを抽出します。

などなど

3) DecimalNum を Bin に変換することを「本当に意味する」場合、Dec に浮動小数点 Dec (つまり、Reals) も含まれている場合、Reals のビット表現は指数で表されるため、(実質的な) 追加の問題があります。そのためのコード/説明ははるかに複雑であるため、そうではないと思います。

最後に、Fortran では、Num は通常「符号付き」Num であり、先行ビットは +ve (0) または -ve (1) を決定するために使用されます。したがって、「他の」方向 (Bin2Dec) に進む場合は、結果が符号付きか符号なしかを制御する追加の引数 (おそらくオプション) を使用することをお勧めします。符号なしの場合、出力変数は入力変数よりも「大きい」必要があります (たとえば、符号なしの 1 バイト int を Fortran int に変換する場合、少なくとも 2 バイトの int を使用する必要があります (つまり、入力 Integer(1) はInteger(2)) などに出力します。

于 2014-06-26T19:22:26.577 に答える
-1

したがって、これはおそらくひどい形式であり、確かに悪いランタイムです(すべてのビットの配列をコピーします)が、これが私が思いついたものです. うまくいくようです。

  program test
      implicit none
      integer, dimension(:), allocatable :: binary
      integer :: decimalnum, i, initvalue, curSize, curBit


      print*, "Enter decimal number to convert: "
      read*,initvalue

      decimalnum = initvalue
      i = 1
      ALLOCATE ( binary(1) )
      curSize = 1

      DO WHILE (decimalnum > 0)
        IF (i > curSize ) THEN
            curSize = curSize * 2
            CALL expandArray( curSize, i-1 )
        END IF

        IF (MOD(decimalnum,2)==0) then
            binary(i) = 0                  ! this is as far as the program executes up to 
            decimalnum = decimalnum / 2
            i = i + 1
        ELSE IF (MOD(decimalnum,2)==1) then
            binary(i) = 1
            decimalnum = (decimalnum -1) / 2
            i = i + 1
        END IF

      end do
      PRINT*, binary


  CONTAINS
      SUBROUTINE expandArray( newSize, oldSize )
          IMPLICIT NONE
          INTEGER, DIMENSION(:), ALLOCATABLE :: temp
          INTEGER :: j, newSize, oldSize
          ALLOCATE( temp(newSize) )
          DO j=1,oldSize
              temp(j) = binary(j)
          END DO
          DEALLOCATE (binary)
          ALLOCATE( binary(newSize) )
          DO j=1,oldSize
              binary(j) = temp(j)
          END DO
          DO j=oldSize+1,newSize
              binary(j) = 0
          END DO
          DEALLOCATE (temp)
      END SUBROUTINE

  END PROGRAM test
于 2012-10-08T08:21:44.557 に答える