Skip to content

Commit f5929bc

Browse files
Watson1978claude
andcommitted
Math.expm1 / Math.log1p を追加 (Ruby 4.0)
Ruby 4.0 で Math.expm1 と Math.log1p が追加された (Feature #21527)。 x が 0 に近いときの桁落ちを避けて exp(x) - 1 / log(x + 1) を計算する メソッドで、C の expm1(3) / log1p(3) に対応する。 実機で登場バージョンを確認した結果、3.1 から 3.4 には存在せず 4.0 で 追加されたため #@SInCE 4.0 で分岐した。既存の並びに合わせて expm1 は Math.exp の直後、log1p は Math.log10 の直後に配置した。 なお Ruby 本体の rdoc は expm1(-INFINITY) の結果を 0.0 と記載しているが、 実機で確認したところ正しくは -1.0 だったため、-1.0 として記述している。 例の出力はすべて実機 (4.0.6) で確認済み。桁落ちを避けられることが分かる 例 (Math.exp(1e-16) - 1 が 0.0 になるのに対し Math.expm1(1e-16) は 1.0e-16 を返す) も添えた。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0f53391 commit f5929bc

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

manual/api/_builtin/Math.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,41 @@ p Math.exp(-Float::INFINITY) # => 0.0
341341

342342
- **SEE** [man:exp(3)], [m:Math?.log]
343343

344+
#@since 4.0
345+
### module_function def expm1(x) -> Float
346+
347+
e の x 乗から 1 を引いた値、すなわち `exp(x) - 1` を返します(e は自然対数の底)。
348+
349+
x が 0 に近いとき、[m:Math?.exp] の結果から 1 を引くと桁落ちによって精度が
350+
失われますが、このメソッドはそれを避けて計算します。
351+
352+
- **param** `x` -- 実数
353+
354+
- **raise** `TypeError` -- x に数値以外を指定した場合に発生します。
355+
356+
- **raise** `RangeError` -- x に実数以外の数値を指定した場合に発生します。
357+
358+
```ruby title="例"
359+
p Math.expm1(0) # => 0.0
360+
p Math.expm1(-1.0) # => -0.6321205588285577
361+
p Math.expm1(0.5) # => 0.6487212707001282
362+
```
363+
364+
```ruby title="例: 0 に近い値での精度"
365+
p Math.exp(1e-16) - 1 # => 0.0 (桁落ちして 0 になる)
366+
p Math.expm1(1e-16) # => 1.0e-16
367+
```
368+
369+
x に負の無限大を渡した場合は -1.0 を返します。
370+
371+
```ruby title="例: 無限大を渡す"
372+
p Math.expm1(-Float::INFINITY) # => -1.0
373+
p Math.expm1(Float::INFINITY) # => Infinity
374+
```
375+
376+
- **SEE** [man:expm1(3)], [m:Math?.exp], [m:Math?.log1p]
377+
#@end
378+
344379
### module_function def frexp(x) -> [Float, Integer]
345380

346381
実数 x の仮数部と指数部の配列を返します。
@@ -458,6 +493,40 @@ p Math.log10(10**100) # => 100.0
458493

459494
- **SEE** [m:Math?.log], [m:Math?.log2]
460495

496+
#@since 4.0
497+
### module_function def log1p(x) -> Float
498+
499+
1 に x を足した値の自然対数、すなわち `log(x + 1)` を返します。
500+
501+
x が 0 に近いとき、1 に x を足してから [m:Math?.log] を取ると桁落ちによって
502+
精度が失われますが、このメソッドはそれを避けて計算します。
503+
504+
- **param** `x` -- -1 以上の実数
505+
506+
- **raise** `TypeError` -- x に数値以外を指定した場合に発生します。
507+
508+
- **raise** `RangeError` -- x に実数以外の数値を指定した場合に発生します。
509+
510+
- **raise** `Math::DomainError` -- x に -1 未満の実数を指定した場合に発生します。
511+
512+
```ruby title="例"
513+
p Math.log1p(0) # => 0.0
514+
p Math.log1p(Math::E - 1) # => 1.0
515+
p Math.log1p(-1.0) # => -Infinity
516+
```
517+
518+
```ruby title="例: 0 に近い値での精度"
519+
p Math.log(1 + 1e-16) # => 0.0 (桁落ちして 0 になる)
520+
p Math.log1p(1e-16) # => 1.0e-16
521+
```
522+
523+
```ruby title="例: 定義域外"
524+
Math.log1p(-2.0) # ~> Math::DomainError
525+
```
526+
527+
- **SEE** [man:log1p(3)], [m:Math?.log], [m:Math?.expm1]
528+
#@end
529+
461530
### module_function def sqrt(x) -> Float
462531

463532
x の非負の平方根(principal square root)を返します。

0 commit comments

Comments
 (0)