##Problem
Problem
The problem with Log[1. + 1.*^-15]
not yielding 1.*^-15
is not due to Log
, but to MachinePrecision
inputs, which I think the OP implied in the question statement:
1 + 1.*^-15
% - 1
(*
1.
1.11022*10^-15
*)
So Log[1 + 1.*^-15]
does return the right answer, 1.11022*10^-15
, for the actual input.
###Solution
Solution
Here is a simple way to get log1p
-type evaluation:
log1p[x_] := x Hypergeometric2F1[1, 1, 2, -x];
log1p[1.*^-15]
(* 1.*10^-15 *)
One needs to be careful, because log1p[x]
evaluates to Log[1+x]
when x
is symbolic and you lose the precision:
log1p[x] /. x -> 1.*^-15
(* 1.11022*10^-15 *)
To prevent this, one can use the Precision
tricks in the other answers, or use ?NumericQ
and clear the previous definition. For instance
log1p[x] /. x -> SetPrecision[1.*^-15, $MachinePrecision] // N
(* 1.*10^-15 *)
or
ClearAll[log1p];
log1p[x_?NumericQ] := x Hypergeometric2F1[1, 1, 2, -x];
log1p[x] /. x -> 1.*^-15
(* 1.*10^-15 *)
Of course, in this second method, you lose the symbolic equivalence to Log[1+x]
. But all the other current solutions suffer the same drawbacks of one or the other definitions of log1p
that are given here.
###Addendum: expm1
Addendum: expm1
The function
expm1[x_] := x Hypergeometric1F1[1, 2, x];
can be used like log1p
above.