首页 > 解决方案 > Is Math.Log implemented in a way to avoid loss of precision for log(1 + x)?

问题描述

I'm translating some C# code to C++, which contains uses of Math.Log(1 + x), where x can be a very small value close to zero. I came across the recommendation (in C++) to use std::log1p for when dealing with log(1 + x), where x is close to zero, i.e. to avoid loss of precision.

Is the C#/.NET Math.Log method implemented in a way that similarly avoids loss of precision? I could not find a similar Math.Log1p() function referenced to in the .NET API reference.

标签: c#c++.netprecisionlogarithm

解决方案


不,Math.Log() 使用 C 库函数 log() 来完成它的工作。log1p() 实际上包含在 CLR 使用的 CRT 库中,但它没有通过框架公开。您可以使用 pinvoke 声明来解决此问题:

using System;
using System.Runtime.InteropServices;

public static class Math {
    public static double Log1p(double arg) {
        if (arg < -1.0) throw new ArgumentException();
        return log1p(arg);
    }

    [DllImport("msvcr120_clr0400.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern double log1p(double arg);
}

如果您需要针对低于 4.0 的 .NET 版本,请考虑将 DllImport 声明更改为使用“ucrtbase.dll”。

值得注意的是,我无法在此代码上获得一致的性能。在我的 poky 笔记本电脑上针对 C# 和 C 上的 x64 目标,我每次调用大约 140 纳秒。但是在针对 x86、225 和 40 时看到了很大的差异。很大的差异,我对此没有很好的解释。


推荐阅读