質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1267閲覧

擬似的なlog計算の方法を知りたい

pypy7

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/05/26 06:46

プログラム上でlog(底はe)の計算を擬似的に行う方法はありますか?
精度は高くなくてよく,速度を重視した方法がいいです.
普通にcなどにあるlogの関数を使うよりも低い精度でいいので早い方法が知りたいです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rinjinto

2021/05/26 06:51

log(x)よりも早く結果が出せるということですか? 結構厳しいような。
maisumakun

2021/05/26 06:58

引数の範囲は限定できますでしょうか?
pypy7

2021/05/26 07:04 編集

ありがとうございます 引数の範囲は0~1の一様乱数です 一様乱数にlogをかませた擬似的な乱数を生成したいというのが一番の目的です
guest

回答4

0

遅くなりましたが、Fast log2のテストをしてみました。

誤差はまあまあですが、おそらく標準のlog2よりは遅いでしょう。

ソースは以下です。

C

1$ cat log2.c 2#include <stdio.h> 3#include <stdlib.h> 4#include <math.h> 5 6#define FRACTION (23) 7#define EXPONENTMASK (0xFF) 8#define BIAS (127) 9 10float fast_log2 (float val) 11{ 12 int *exp_ptr = (int *)&val; 13 int x = *exp_ptr; 14 int log_2 = ((x >> FRACTION) & EXPONENTMASK) - (BIAS + 1); 15 x &= ~(EXPONENTMASK << FRACTION); 16 x += BIAS << FRACTION; 17 *exp_ptr = x; 18 val = ((-1.0f/3) * val + 2) * val - 2.0f/3; 19 return (val + log_2); 20} 21 22int main(void) { 23 float f; 24 25 f = 1.0; 26 printf("%f fast_log2: %15.15f\n", f, fast_log2(f)); 27 f = 2.0; 28 printf("%f fast_log2: %15.15f\n", f, fast_log2(f)); 29 f = 3.0; 30 printf("%f fast_log2: %15.15f\n", f, fast_log2(f)); 31 printf("%f math log2: %15.15f\n", f, fast_log2(f)); 32 f = 0.1; 33 printf("%f fast_log2: %15.15f\n", f, fast_log2(f)); 34 printf("%f math log2: %15.15f\n", f, log2(f)); 35}

実行結果

shell

1$ ./log2 21.000000 fast_log2: -0.000000059604645 32.000000 fast_log2: 0.999999940395355 43.000000 fast_log2: 1.583333253860474 53.000000 math log2: 1.583333253860474 60.100000 fast_log2: -3.319999933242798 70.100000 math log2: -3.321928073389531

投稿2021/05/27 23:48

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikadzuchi

2021/05/28 13:45

いえ、少なくとも私のPCでは早いですね。 int time0 = clock(); double temp = 0; for(double i=0.1; i<1; i+=0.00000001) { temp += fast_log2(i); } printf("%d\n(%f)\n", clock()-time0, temp); のようなコードで、 mathのlog2が 1515625 fast_log2が 859375 空(加算のみ)が 296875 程度でしたので、2倍ちょっと早いようです。
guest

0

ベストアンサー

考え方として簡単なのは範囲を区切って直線で近似する方法です。

たとえば以下のグラフは 6x-20.8x-0.8 で近似した例です。

イメージ説明

最大誤差の見積もりは事前に可能ですから、必要な精度に応じて分割を多くすればよいでしょう。 とはいえ、標準ライブラリが提供する log はかなり高度にチューニングしていることが多いと思われるのでそれより速くなるレベルにするにはかなり雑な分割しか出来ないかもしれませんね。

CPU が対数計算のための (あるいは直接ではないにしても役立つような) 命令を持っている場合もあるので理論上の計算速度が速い式であっても専用回路にはかなわないという場合もあります。

投稿2021/05/26 07:51

SaitoAtsushi

総合スコア5466

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pypy7

2021/05/27 07:42

なるほど ありがとうございます!
guest

0

frexpを使って0.5<x<=1の範囲に持ち込んで(指数分はln(2)の定数を用意しておいて調整)、ln(1+x)のマクローリン展開を途中で打ち切る、ような流れが考えられます。

ただし、ライブラリは徹底的にチューニングされていることも多いです。自分で書いて勝てるかは、実験してみないとわかりません。

投稿2021/05/26 07:24

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ググっただけですが、こんなのを見つけました

Fast log() Function - flipcode

投稿2021/05/26 06:56

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pypy7

2021/05/26 07:02

ありがとうございます! 試してみようと思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問