Skip to main content
Commonmark migration
Source Link

##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.

##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

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

The function

expm1[x_] := x Hypergeometric1F1[1, 2, x];

can be used like log1p above.

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

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

The function

expm1[x_] := x Hypergeometric1F1[1, 2, x];

can be used like log1p above.

Added addendum
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775

##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

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

The function

expm1[x_] := x Hypergeometric1F1[1, 2, x];

can be used like log1p above.

##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

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.

##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

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

The function

expm1[x_] := x Hypergeometric1F1[1, 2, x];

can be used like log1p above.

Fixed typo
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775

##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

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.

##Problem

The problem with Log[1. + 1.*^-15] not yielding 1. 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

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.

##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

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.

Clarification
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775
Loading
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775
Loading