任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

2024-05-23

例如:2^0.5=1.414...&所以想要。 我是 c 的新手,所以请解释简单的逻辑,如果不是复杂的逻辑也足够了


在数学中,从整数取幂到实数取幂的步骤是相当大的一步。虽然整数求幂可以定义为重复乘法(例如x^5 = x*x*x*x*x) 指数中实数值的求幂通常是通过自然指数函数定义的。你的例子2^0.5可以重写为

2^0.5 = exp(0.5*ln(2))

where exp是自然指数函数并且ln是它的倒数,即自然对数。这两个函数都具有众所周知的幂级数:

exp(x) = 1 + x + x^2/2 + x^3/3 + ... 
ln(x)  = (x-1) - (x-1)^2/2 + (x-1)^3/3 - ...

幂级数是无穷级数,因此您无法精确计算它,但根据您希望结果的精确程度,您可以在级数中的某个点停止。整个系列的公式可以在以下位置找到:维基百科 https://en.wikipedia.org/wiki/Taylor_series#Exponential_function.

请注意,对数的级数展开仅对 0 到 2 之间的 x 值收敛。在您的示例中,ln(2)已经到了这个区域的边缘。通过进一步重写表达式可以找到此问题的解决方案。对于任何数字x, ln(x)可以扩展为

ln(x) = ln(m*2^e) = ln(m) + e*ln(2)

Where m是尾数(1 到 2 之间)并且e是数字 x 的指数。在您的示例中,您可以这样写:

ln(2) = ln(1*2^1) = ln(1) + 1*ln(2)

的价值ln(2)可以预先计算并存储为常数,因为它总是相同的。的价值ln(1)可以使用上面的级数展开来准确计算(在您的示例中,这恰好是ln(1) = 0,但一般情况并非如此)。尾数和指数可以很容易地从double or float类型,通过使用其内部位表示 https://en.wikipedia.org/wiki/Single-precision_floating-point_format.

有了这些信息,我们就可以尝试编写自己的ln, exp最终pow功能:

#include <stdio.h>

/* constant to control how many terms in the series expansion we want to calculate before aborting */
const int N = 50;

float my_ln(float x) {
    const float ln2 = 0.6931471805599453;
    union {
        float f;
        uint32_t i;
    } u;

    /* get the mantissa by bit manipulation of the float binary representation */
    u.f = x;
    u.i = (u.i & 0x07ffffff) | 0x3f800000;

    /* calculate the logarithm according to its series expansion */
    float result = 0.0;
    float tmp = u.f - 1.0;
    for ( int i = 1; i < N; i++ ) {
        result += tmp/i;
        tmp *= 1.0 - u.f;
    }

    /* get the exponent */
    u.f = x;
    u.i = ((u.i >> 23) & 0xff) - 127;

    /* multiply it with ln(2) and add it to the logarithm of the mantissa */
    result += (float)u.i * ln2;
    return result;
}

float my_exp(float x) {
    float result = 0.0;
    float tmp = 1.0;
    for ( int i = 1; i < N; i++ ) {
        result += tmp;
        tmp *= x/i;
    }
    return result;
}

float my_pow(float x, float a) {
    /* multiply the logarithm of the base x with the exponent a and compute the natural exponential of this value */
    return my_exp( my_ln(x) * a);
}

int main() {
    float x = 2.0;
    float a = 0.5;
    printf("%f ^ %f == %f\n", x,a, my_pow(x,a));
}

这给出了相当好的结果,至少对于我测试的几个例子来说是这样。请注意,编写此类函数很困难且容易出错。例如,我上面提供的函数不能正确处理负数。 NaN、无穷大和零也没有得到正确处理。虽然这也可以通过更多的努力来完成,但人们确实应该使用标准库中的函数,因为它们是

  • 经过充分测试
  • 可能更快并且经过优化
  • 在更极端的数字区域(非常小或很大的数字)可能更准确
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭] 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐