💭
[Feature #21527] Math.log1p と Math.expm1 を追加する提案
[Feature #21527] Proposal: Math.log1p and Math.expm1
-
Math.log1pとMath.expm1を追加する提案 - それぞれ以下と同じ挙動になる
-
Math.log1p(x)->Math.log(x + 1) -
Math.expm1(x)->Math.exp(x) - 1
-
- 直接右のコードを呼び出したときと比較して専用のメソッドを用意することで以下のような誤差をなくすことができるみたいですね
# log / exp を呼び出すと精度が失われる
p Math.log(1 + 1.0e-16) #=> 0.0
p Math.exp(1.0e-16) - 1 #=> 0.0
# log1p / expm1 は精度を失わずに計算できる
p Math.log1p(1.0e-16) #=> 1.0e-16
p Math.expm1(1.0e-16) #=> 1.0e-16
- これらのメソッドはいずれも他の言語でも標準で用意されている一般的な関数みたいですね
- C99 にも標準で定義されている関数になる
-
log1p / expm1という名前がわかりづらい、というコメントも書かれてしますがこれらの名前も割と一般的な名前みたい - 他には
fiddleを経由して直接関数を呼び出すようにする案とかもコメントされていますね
require 'fiddle'
log1p = Fiddle::Function.new(Fiddle.dlopen(nil)["log1p"], [Fiddle::TYPE_DOUBLE], Fiddle::TYPE_DOUBLE)
p log1p.call(1.0e-16) # => 1.0e-16
- この提案は承認されて開発版の Ruby 3.5-dev では既に実装済み
# Ruby 3.5 から利用可能
p Math.log1p(1.0e-16) #=> 1.0e-16
p Math.expm1(1.0e-16) #=> 1.0e-16
Discussion