【问题标题】:Why tanh function from math.h library give wrong result?为什么 math.h 库中的 tanh 函数给出错误的结果?
【发布时间】:2017-03-03 01:41:10
【问题描述】:
#include<stdio.h>
#include<math.h>
#define PI 2*acos(0.0)
int main(void)
{
    double theta;
    theta=tanh(1/(sqrt(3.0)));
    printf("With tanh function = %lf\n",theta);
    printf("Actual value = %lf\n",PI/6.0);
    return 0;
}

输出:

使用 tanh 函数 = 0.520737

实际值 = 0.523599

为什么这两个值不同?应该和我的理解一样。

【问题讨论】:

  • @LưuVĩnhPhúc 注意在这种情况下,它应该评估为相同的结果
  • @immibis 是的,我知道。这只是一种应该熟悉的行为
  • 浮点数的不准确性和宏上缺少的括号都不是问题所在。我在 HP42S 仿真器上计算了 tanh(1/sqrt(3.0)),得到了 0.520736883716。您确定预期结果是 pi/6 吗?
  • 根据 wolfram (functions.wolfram.com/ElementaryFunctions/Tanh/03/02) tanh(πi/6) 是 i/sqrt(3)。这里i 是虚数单位(即-1 的平方根)。您不能只将is 分开,而且无论如何您似乎正在反转tanh 和atanh。我认为您可以从身份 e^iπ=-1 中推断出身份

标签: c math.h


【解决方案1】:

你的身份完全错了。

实际身份是

tanh-1(i ⁄ √3) = πi ⁄ 6(其中 i 是虚数单位,√-1)

C11 可以轻松验证:

#define _XOPEN_SOURCE 700
#include<stdio.h>
#include<math.h>
#include<complex.h>

int main(void)
{
    complex double theta=catanh(I/sqrt(3.0));
    printf("With atanh function = %lf\n",cimag(theta));
    printf("Actual value = %lf\n",M_PI/6);
    return 0;
}

(在 coliru 上直播:http://coliru.stacked-crooked.com/a/f3df5358a2be67cd):

With atanh function = 0.523599
Actual value = 0.523599

M_PI 将在任何 Posix 兼容系统中的 math.h 中。显然,在 Windows 上你使用

#define _USE_MATH_DEFINES

但我不知道 Visual Studio 是否支持complex.h

【讨论】:

【解决方案2】:

您的程序有几个小缺陷,但没有一个会导致其行为不端。

你的PI 宏应该用括号括起来:

#define PI (2*acos(0.0))

但是由于你使用它的方式,你碰巧没有括号。

打印double 值的正确格式实际上是%f,但也接受%lf。 (%Lf 用于long double%f 也适用于float,因为float 可变参数函数的参数被提升为double)。这也不会影响程序的行为。

事实上,您的程序运行正常。我已经使用 HP 42S 模拟器确认 tanh(1/(sqrt(3.0))) 大约为 0.520737(我得到 0.520736883716)。

问题在于您假设结果应该是 π/6.0。不是。

【讨论】:

  • 我也在matlab 2014b中测试过。不得不放弃我几乎书面的答案。 :D
猜你喜欢
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多