• ベストアンサー

VBAのlogとintについて

エクセル2007のVBAについての質問です  イミディエントウインドウでの出力なのですが ? log(1000)/log(10#) 3 ? int(3) 3 ?int(log(1000)/log(10#)) 2 となります。このような  int(log(10^n)/log(10#))  に対する、数学的な計算に対する誤差は、今のところn=3の場合のみで 見受けられるのですが、対処法はあるのでしょうか?よろしくお願いいたし ます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

■原因など コンピュータ一般に、浮動小数点演算という手法が使われているのですが、計算結果は内部的には限りなく3に近い2の小数として保持されています。このため、計算結果を int 関数で処理すると限りなく3に近い2の小数でも2になってしまうことがあります。 (int 関数は、整数部を返すという動作をします。) int(number) の閾値 ?int(2.9999999999999997) => 2 内部的には、整数部が2として保持されている。(と思われる*) ?int(2.9999999999999998) => 3 内部的には、整数部が3として保持されている。(と思われる*) *厳密には浮動小数点演算の仕様等を確認すればいいのですが、時間の都合的に推測です。 ?2.9 => 2.9 ?2.99 => 2.99 ?2.999 => 2.999 (中略) ?2.99999999999999 => 2.99999999999999 ?2.999999999999995 => 3 ■対策 通常、丸め処理は round 関数を使用します。 ただ、 round 関数の丸め処理は偶数丸め仕様ですので注意してください。(つまり、四捨五入ではありません) ?round(1.25,1) => 1.2 ?round(1.35,1) => 1.4 質問については、下のようにすればいいと思います。 ?round(log(1000#)/log(10#)) => 3 ?int(round(log(1000#)/log(10#))) => 3

kfnorisu
質問者

お礼

 早速のご回答ありがとうございます。  なるほど、roundを使えばよかったのですね。roundの仕様を確認した ところ、許容範囲の出力を得られました。明解な解答をありがとうござい ます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • logについて

    この度基本情報の試験を受けようと思っている者です。過去問を解いててどうしても分からないところがあるので、皆様のお力をお借りしたく質問いたしました。 <問題> ゼロでない整数の10進表示のけた数Dと2進表示のけた数Bとの関係を示した式はどれか。 <解答> ゼロでない整数をNとすると 10^D-1≦N≦10^D   (1) 2^B-1≦N≦2^B     (2) (1)より D-1≦log(10)N<D log(10)N<D≦log(10)N+1 したがってけた数Dが大きい場合D≒log(10)N  この解答の、D-1≦log(10)N<D から log(10)N<D≦log(10)N+1 へはどんな計算式でこうなるのかがまったく分かりません。 よろしくお願いします。 

  • (int) の使い方に関して

    いま、C言語をVBに書き換える作業をしています。 m=2*((n+(int) sqrt(ACC*n))/2); という文があるのですが、このintというのはどういう意味で使われているのでしょうか? m=2*((n+(int sqrt(ACC*n)))/2); というようにsqrt(ACC*n)の整数をとるという意味でしょうか?

  • logの計算

    {log (n+1) -1} ×2 ×(n+1)/4 + {log (n+1) -2} ×2 ×(n+1)/8 + {log (n+1) -3} ×2 ×(n+1)/16 + …… = (n+1) log (n+1) { 1 + 1/2 + 1/2^2 + 1/2^3 + 1/2^4 + …… } - (n+1) {1 + 1/2 + 2/2^2 + 3/2^3 + 4/2^4 + …… } 上の計算がどうしてこうなるかが分かりません。 これを計算すると 2n*log(n+1)-4(n+1) になりますか? ちなみにlogの底は2です。

  • log0*0 の計算

    以前の質問が、分割質問に該当するとして削除されました。 回答者には、ご迷惑をお掛けしてすみませんでした。 考え直します。 お詫び…にはなりませんが、新たな質問をします。 log0*0 の計算を考えます。 log(1-x)=Σ[n=1,∞](-1/n*x^n) x=1 だと収束しません。 この式に、0 を掛けます。 0*log(1-x)=Σ[n=1,∞](-1*0/n*x^n)=0 0*(-∞) が 0 になるのは不思議なのですが、してはいけない変形はどこですか?

  • 最小2乗法に関して

    はじめて質問させていただきます。よろしくお願いいたします。 数学が苦手でよくわからず助けてください。 a,b,cはパラメーターであり、 log(Yn)=log(a)+blog(n)-cn の最小2乗法で各パラメーターを出すことができるみたいなのですが、どのように出すのでしょうか? またYとnに関しては Y=10,n=20 Y=50,n=60 Y=15,n=100 Y=13,n=180 といった感じです。 また、このパラメーターはエクセルで計算できるのでしょうか? わかり難い内容となってしまいましたが、 大変困っております。どうぞ教えてください。 よろしくお願いいたします。

  • セルの文字式の計算をVBAで行いたい

    A1のセルに "100+5n" という文字式が入っている状態で VBAにてこのセルの文字式計算を行いB1のセルから順に結果を出力したいと思っています。 "n"は1から順に指定された数まで1づつ増えていくようにし B1のセル:105、C1のセル:110、D1のセル:115 ・・・・ と結果がなるようにしたいのですが、VBAでどのように記述すればいいのか悩んでいます。 VBAを使わずにExcelの関数で計算できるのならそれでもよいと思っています。

  • log計算につきまして

    logを使った計算で困っています。 2 n-1 (←右上小文字) < 10 7(←右上小文字) < 2 n(←右上小文字) とした場合、7/log10(←右下小文字)2 < n < 7/log10(←右下小文字)2+1 となる との事ですが、どのように変換したらたどり着くのか分かりません。 どなたか教えていただけますか? よろしくお願いいたします。

  • VBAで 2n!! はどのように表示しますか

    2n!! という式があります。 n=1のとき 2n!!=2 n=2のとき 2n!!=2*4 n=3のとき 2n!!=2*4*6 n=4のとき 2n!!=2*4*6*8 のような関数で n(最大値)=20 の値を求める式の表示方法をご教示 お願いします。nを変数として扱いたいのですが、不可能なのでしょうか?(計算結果は概略でOK) (2n-1)!!,(3n-1)!!なども組み込むために冗長な方法は利用したくないのです。丸投げですみませんが、趣旨をお汲み取りください。 Excel2000のVBAで利用したいのです。

  • VBAでの最小値抽出

    ExcelのVBAにおいて,最小値の抽出方法の質問です. たとえばA1に変数nがあり,A2にnの関数(例えば=n^4-2n^3+5n-10とか)があるとします. A1を1から100まで動かしたときのA2の最小値を求めたいのですが,これはそのまま1から100まで値をズラっと出力すれば,あとはそこから最小値を探すだけで求まりますが,こういう方法はとらず,一発でこの最小値を1つのセルに出力させたいのです. いろいろわけあって,使用するセルを最小限におさえたく,この方法が知りたいのです. よろしくお願いします.

  • 数値解析の矩形法について

    区間分割数nを10から100まで10ずつ増やして計算値を求め、面積の計算誤差が区間分割数によってどのように変化するかを求める矩形法プログラムを下記に作成したのですが、 計算誤差を求める式で ・計算誤差=(計算値ー真値)/真値×100 (%) (真値は0.68269) と計算するのですが、プログラムでは分母の真値×100 (%)を()を付ける場合の計算の答えと()を付けない計算の答えとが全然違います。どうしてこのようなことが起こるのですか? また、この計算誤差の求め方は()を付ける場合とつけない場合のどちらが正しいのですか? public class Kukei { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 10; // 区間分割数 double suti= ((n+10)-0.68269)/0.68269*100; //真値 for(int k=1; k <= 10; k++){ double h = (b - a) / (double)n; // 分割幅 double s = 0.0; n=k*10; for (int i=0; i < n; i++) { s += f(a + i * h); } s *= h; suti= (s-0.68269)/0.68269*100; System.out.println("区間分割数 =" + n); System.out.println("矩形法による計算値 =" + s); System.out.println("矩形法による計算誤差 =" +suti+"\n"); } } }

専門家に質問してみよう