HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0403
けものみちある少数について、0以外の数字が出てこなくなる桁数を求めたい。6解決


けものみち

リンク

2017/4/3(Mon) 18:11:54|NO.78855

タイトルの通りで、例えば

0.123400052000000... // 以降0が続く
のような少数があったとしたら

0.123400052 までの桁数、つまり 9 が返ってくる関数を書きたいのですが

なにかスマートな方法がありませんか?

ちなみに、浮動小数点の仕組みが分かっていません。



この記事に返信する


Velgail

リンク

2017/4/3(Mon) 18:51:28|NO.78856

理論値で、一部の値(あまりに小さい数値)には非対応ですが、計算で出す方法を書いてみました。

#module #defcfunc under_digit double a, local b b=a c=wpeek(b,6) c&=32767 c>>4 c-=1<<10 d=logf(2)/logf(10)*c d=-d+15 return d #global a=0.12345678901234567890 b=-543210.1234567890234567890 mes under_digit(a) mes strf("%.20f",a) mes under_digit(b) mes strf("%.20f",b)

もらった値を切り上げれば出てくる桁数とほぼ一致、切り下げれば精度とほぼ一致するはずです。
//記憶では15で良かったはずだけど、間違ってたら誰か指摘して



Velgail

リンク

2017/4/3(Mon) 19:01:27|NO.78857

おっと、精度的にやってしまった。この解だと、「意味のある0」という概念が飛んで来るから不適当か?
対応させたものはこちら。2つ目の例で11じゃなく10なのは、11桁目は精度上のゴミだから。


#module #defcfunc under_digit double a, local b,local c,local d b=a c=wpeek(b,6) c&=32767 c>>4 c-=1<<10 d=logf(2)/logf(10)*c d=-d+15 return d #defcfunc udigit double a, local b, local c, local d,local e d=under_digit(a) b=1+d //もし、ゴミでも必要であるという場合は、2あるいは3程度に変更することも可 c=strf(strf("%%.%df",b),a) repeat if strmid(c,-1,1)!="0"{ break } c=strmid(c,0,strlen(c)-1) loop return strlen(c)-instr(c,0,".")-1 #global a=0.12345678901234567890 b=-543210.1234567890234567890 mes under_digit(a) mes udigit(a) mes strf("%.20f",a) mes under_digit(b) mes udigit(b) mes strf("%.20f",b) mes under_digit(0.123400052000000) mes udigit(0.123400052000000)



けものみち

リンク

2017/4/3(Mon) 20:13:32|NO.78860

おおお。。回答ありがとうございます
一旦文字列に変更してからという方法が・・!
思いつかなかったです。

Velgailさんのソース参考にして、自分の望む動作の関数が出来ました。

#module #defcfunc under_digit double a, int d t = int(a) if t{ uplen = strlen(str(t)) + 1 }else{ uplen = 2 } c = strf("%0.60f", a) c = strmid(c, uplen, d) for i, strlen(c) - 1, - 1, -1: if peek(c, i) = '0': next return i + 1 #global #define global ctype udigit(%1, %2 = 10) under_digit(%1, %2) mes udigit(-651.12370080008)

解決にします。ありがとうございました。

そして桁数を求めるのに文字列にキャストするのは違和感があるので、違う回答も募集します!



けものみち

リンク

2017/4/3(Mon) 20:16:43|NO.78862


#module #defcfunc under_digit double a, int d t = int(a) if t{ uplen = strlen(str(t)) + 1 }else{ uplen = 2 + (a < 0) } c = strf("%0.60f", a) c = strmid(c, uplen, d) for i, strlen(c) - 1, - 1, -1: if peek(c, i) = '0': next return i + 1 #global #define global ctype udigit(%1, %2 = 10) under_digit(%1, %2) mes udigit(-0.12370080008)

バグがありました。修正版です



けものみち

リンク

2017/4/3(Mon) 20:42:04|NO.78863

またしてもバグが。

#module #defcfunc under_digit double a, int d t = int(a) if t{ uplen = strlen(str(t)) + 1 }else{ uplen = 2 + (a < 0) } c = strf("%0.10f", a) c = strmid(c, uplen, d) for i, strlen(c) - 1, - 1, -1: if peek(c, i) = '0': next return i + 1 #global #define global ctype udigit(%1, %2 = 10) under_digit(%1, %2) mes udigit( 0.1234000520007) mes udigit( 200.1234000520007) mes udigit( -0.1234000520007) mes udigit(-200.1234000520007)
これでもバグっているかもしれませんが、これで最後にします。
しっかり分かってから書き込まないといけないですね。反省します。



Velgail

リンク

2017/4/3(Mon) 21:21:56|NO.78865

いや、それ桁数10桁までしか出ないんじゃない……?>NO.78863



ONION software Copyright 1997-2021(c) All rights reserved.