c# - 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.
解决方案
不,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 时看到了很大的差异。很大的差异,我对此没有很好的解释。
推荐阅读
- python - 为什么我的 pygame 窗口不适合我的 4k(3840x2160) 显示器?pygame 窗口的比例:(3000x1500)
- java - 无法使用 Apache POI 从 Payara 服务器中的 ADF 应用程序实用地导出 Excel 文件
- java - 使用用户凭据通过 Microsoft Graph API 通过控制台应用发送电子邮件
- swift - 在 swift 中使用 WebRTC 的 iOS 屏幕共享 (ReplayKit)
- arrays - 在我的控制器数组中检索 1 个变量
- python - 如何在 Django 模板中使用垂直表创建动态标题
- javascript - 单击复选框后如何使我的动态表格行消失?
- javascript - 分组和升序,如何制作具有2个属性的对象数组?
- html - 链接到同一 html 页面中的特定部分
- c# - 来自登录用户的 ADAL.NET ID-Token