pow的精确度与c中的重复乘法

如何解决pow的精确度与c中的重复乘法

我有一些浮点代码,这些代码在性能分析中陷入了对pow的重复调用中。由于提供幂的值的数量非常有限,并且指数可以全部归为整数,因此我想将这些调用替换为预先计算的数组。

在代码性能方面,预先计算数组不太可能非常重要,但是准确性的含义是什么:

array[0]= 1 ;
for (int n=1 ; n<100 ; n++)
    array[n]=array[n-1]*some_double ;

vs

for (int n=0 ; n<100 ; n++)
    array[n]=pow(some_double,n) ;

假设n不超过100,可能更少。如果不一样,对长双倍的答案也很感激。

解决方法

这应该给您一个模糊的想法:

#include <stdio.h>
#include <math.h>

double mypow(double d,int n)
{
  double result = d;
  for (int i = 1; i < n; i++)
    result *= d;

  return result;
}

int main(int argc,char* argv[])
{
  for (double d = 0; d < 10; d += 0.1)
  {
    for (int n = 1; n < 100; n++)
    {
      double r1 = pow(d,n);
      double r2 = mypow(d,n);    
      printf("d = %f,n = %d %f %f %f\n",d,n,r1,r2,r1-r2);
    }
  }
}
,

您的连续乘法会导致100个舍入误差相加。您可以通过更聪明的方式做到这一点:存储x ^ 0和x ^ 1,然后使用x ^(2n)=(x ^ n)^ 2和x ^(2n + 1)= x ^(2n)* x 。四舍五入的错误更少。

现在与pow(x,n)比较:一个好的库实现将意识到n是一个整数,并使用乘法计算结果,并且它将使用与我上面的代码相同的乘法,做一些更聪明的事情。一种更聪明的实现方式是将long double用于中间结果,或使用quad precision算法以尽可能小的舍入误差获得结果。

由于您只计算100次幂,因此,如果您真的想将舍入误差保持在尽可能低的水平,我很想使用pow()。

,

在重复调用pow时,代码分析陷入了困境。

要提高整体速度性能,而不是着眼于如何更快地完成x y ,请发布较大的代码。最佳优化涉及更广泛的代码视图。


*pow()的效果。

重复的多阳离子*每次在产品中最多引起1/2 ULP。如果10 100 是99乘法,则可以预期√99* 0.5 ULP。

取决于FLT_EVAL_METHOD的编译器可能对*使用更宽泛的数学运算,并且导致错误可以忽略。

pow()是一个难以实现的棘手的库函数。采用简单实现的z = x y 的误差与ln(| z |)(IIRC)成正比-这对于大z来说是相当糟糕的。好的pow()将使用扩展的数学和其他精心设计的代码来最大程度地减少错误,该错误可能降至1.0 ULP。这是以适度的时间性能成本为代价的。

要获得高质量的答案,请使用pow(),除非提高到简单的小整数幂,例如2,3,4。


double的某些替代代码提高为正整数幂。 n可能等于或大于5时,比乘法循环更省时。可能更准确。

double pow_n(double base,unsigned exp) {
  double y = 1.0;
  while (1) {
    if (exp % 2) y *= base;
    exp /= 2;
    if (exp == 0) break;  
    base *= base;
  }
  return y;
}
,

据我所知,没有电路可以计算幂,这意味着pow()函数必须是一种算法(不能由硬件在单个时钟周期内完成)。关于此的论文很多,主要关注的是精度而不是性能(每次进行乘法都会失去精度),某些算法会在每次乘法后进行补偿,这将需要更多的计算。 我的假设与您的情况无关,在最坏的情况下,pow()的算法与手动执行的算法相同,但要考虑所有CPU,操作系统和编译器。

//this should be faster
array[0]= 1 ;
for (int n=1 ; n<100 ; n++)
array[n]=array[n-1]*some_double ;

//this should be more accurate 
for (int n=0 ; n<100 ; n++)
    array[n]=pow(some_double,n) ;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-