数値をE表現の数値文字列に変換する関数

 投稿者:nagram  投稿日:2019年 4月27日(土)15時42分57秒
  十進BASICの今回のバージョンアップで、1000桁モードでE表現になる出力が一掃されました。
今までは、15桁モードや2進モードと違いE表現で出力される基準が明確ではなかったので、今回の変更を歓迎します。
そうは言っても、指数表記には利点もあるので、数値を指数表記文字列に変換する関数を2種類作りました。

● xを有効数字n桁の指数表記文字列に変換する関数
関数 STR_E1$(x,n) … def文で定義。x=0 または n=0 のときエラー。
関数 STR_E2$(x,n) … 数値文字列の表示形式をオプションで設定。
例) STR_E1$(2345678,3)→" 2.35E+6"   STR_E1$(0.004321,8)→" 4.3210000E-3"   STR_E2$(123400000,6)→" 1.234E8 "
精度を確保できるnの上限は、10進15桁・2進→n=15、1000桁・有理数→n=1000
変換した文字列は、組込みのVAL関数で数値に戻せる。VAL(" 2.35E+6")→2350000
負数で端数がちょうど5のときSTR_E1$とSTR_E2$では丸め方に違いがある。
有理数モードでも使えるが、有効数字1000桁まで。
複素数モードでは引数x,nが複素数のときエラー。複素数を実部と虚部に分ければ使える。


DEF STR_E1$(x,n)=USING$("-%."&REPEAT$("#",n-1)&REPEAT$("^",LEN(STR$(ABS(INT(LOG10(ABS(x))))))+2),x)

FUNCTION STR_E2$(x,n)
   LOCAL u$,e,i
   IF x=0 OR ROUND(n)=0 THEN  ! 有効数字0桁の数値は0
      IF n>0 THEN LET u$=" 0."&REPEAT$("0",n-1)&"E+0" ELSE LET u$=" 0"
   ELSE
      LET e=INT(LOG10(ABS(x)))
      LET u$=USING$("-%."&REPEAT$("#",n-1)&REPEAT$("^",LEN(STR$(ABS(e)))+2),ROUND(x,n-e-1))
   END IF
   !             ここからはオプション[1~6]
   !LET u$=LTRIM$(u$)  ![オプション1]xが非負のときの先頭空白を削除 " 3.45E+6"→"3.45E+6"
   FOR i=POS(u$,"E")-1 TO 2 STEP -1  ![オプション2]仮数部末尾の"0"を削除 n=4,"-6.700E+8"→"-6.7E+8"
      IF u$(i:i)="0" THEN LET u$(i:i)="" ELSE EXIT FOR
   NEXT i
   !LET u$(POS(u$,".E"):POS(u$,".E"))=""  ![オプション3]仮数部が1桁のとき小数点を削除 "-7.E4"→"-7E4"
   IF POS(u$,"E+0")>0 THEN  ![オプション4]指数が0のとき指数部を削除 n=5," 6.5400E+0"→" 6.5400"
      LET u$=u$(1:POS(u$,"E")-1)
      IF u$(LEN(u$):LEN(u$))="." THEN LET u$=u$(1:LEN(u$)-1)  ! "-4.E+0"→"-4."→"-4"
   END IF
   LET u$(POS(u$,"+",3):POS(u$,"+",3))=""  ![オプション5]指数部の"+"を削除 " 1.23E+5"→" 1.23E5"
   LET u$=u$&" "  ![オプション6]文字列の末尾に空白を付加 " 5.678900E-3"→" 5.678900E-3 "
   LET STR_E2$=u$
END FUNCTION

DO
   READ IF MISSING THEN EXIT DO: a,n
   PRINT a;n
   PRINT STR_E1$(a,n)
   PRINT STR_E2$(a,n)
   PRINT
LOOP
DATA 2496376014,5, -6715400000000,8, 0.000007102385,6, 3.95180751,4, -218.60135,7

END
 

戻る