好的,我知道关于pow函数并将其结果转换为int有很多问题,但是我找不到这个特定问题的答案。

OK,这是C代码:

#include

#include

#include

int main()

{

int i = 5;

int j = 2;

double d1 = pow(i,j);

double d2 = pow(5,2);

int i1 = (int)d1;

int i2 = (int)d2;

int i3 = (int)pow(i,j);

int i4 = (int)pow(5,2);

printf("%d %d %d %d",i1,i2,i3,i4);

return 0;

}

这是输出:" 25 25 24 25"。 注意,只有在第三种情况下,pow的参数不是文字,我们才得到错误的结果,可能是由于舍入错误引起的。 没有显式强制转换,也会发生相同的事情。 有人可以解释这四种情况吗?

我在Windows 7和随附的MinGW gcc编译器中使用CodeBlocks。

您要确切解释什么? 24和25都是正确答案。 该实现会执行最有效的操作。

我的输出是25 25 25 25。 那真是怪了。

@ user2448027尝试禁用所有优化。

在Ubuntu系统中,我也得到" 25 25 25 25",这仅在Windows中发生。 而且只有第三种情况,那才是最有趣的。

@Marko如果禁用Ubuntu中的所有优化会怎样?

@ user2448027对不起,我的回答很晚。 所有优化均已禁用。 但是,使用-O3优化时,我也会得到正确的结果。

pow操作的结果为25.0000,加上或减去一些舍入误差。如果舍入误差为正或为零,则转换为整数将产生25。如果舍入误差为负,则结果为24。两个答案都是正确的。

内部最有可能发生的情况是,一种情况是直接使用精度更高的80位FPU值,另一种情况是将结果从FPU写入内存(为64位double值),并且然后读回(将其转换为稍有不同的80位值)。这可以在最终结果中产生微观差异,这就是将25.0000000001更改为24.999999997所需的全部

另一种可能性是,编译器会识别传递给pow的常量,然后自己进行计算,将结果替换为对pow的调用。您的编译器可以使用内部的任意精度数学库,也可以仅使用一个不同的数学库。

舍入永远不会将大于25的值更改为小于25的值。即使不知道浮点算术的规则或机制,术语"舍入"也是一个大提示:24.999999997的舍入不大于25.0000000001。浮点算术不是随机数生成器。

@EricPostpischil我同意。那不是我在说什么。林说的是,舍入可以将原本为25的值舍入为24.9999997或25.000001。从不能保证重复执行完全相同的操作的意义上讲,浮点算术可以是随机数生成器。

重复执行完全相同的操作会产生完全相同的结果。在这种情况下,由于C实现无法明确地将源代码绑定到浮点操作,因此不重复操作。即使这样,每次操作每次执行都会产生相同的结果。只是看起来相似的源代码(不完全相同)会产生不同的结果。这是C实现的缺陷,而不是浮点算法的缺陷。

@EricPostpischil您在争论语义,并给一个非常简单的问题增加混乱和不必要的复杂性。严格来说,您永远无法执行两次"完全相同的操作"。问题是您无法知道哪些更改会导致不同的浮点结果。 (如果更改编译器版本,是否执行完全相同的操作?如果升级CPU,是否进行?)此处没有"缺陷"。这就是应该的样子。如果存在缺陷,则可以期待。

这不是语义,因为它告诉您在哪里寻找答案。如果您使用C标准来控制浮点,则会遇到麻烦。如果您遵循IEEE 754标准,则会发现完全指定的操作。关于您的问题:如果更改编译器版本,则操作不一定相同。如果更改CPU型号,则基本操作是相同的(诸如reciprocal-square-root-estimate之类的深奥操作可能会有所不同)。您提倡无知,断言这些事情是未知的。但是它们是已知的并且可以控制的。

@EricPostpischil:这是一个C问题。它与IEEE 754无关。如果您认为我的陈述不正确或具有误导性,则必须同意不同意。如果您认为它们不完整-当然可以。从C或C ++程序员的角度来看,即使从语言的角度来看,即使浮点运算看起来是相同的,也试图理解为什么浮点运算会给它们带来不一致的结果,答案很简单-规范允许实现提供任何"合理的"",并且除非合理,否则不需要保持一致。

这是由两个问题的组合引起的:

您使用的pow的实现质量不是很高。在许多情况下,浮点算术都必须是近似值,但是良好的实现应注意确保诸如pow(5, 2)之类的简单情况返回准确的结果。您正在使用的pow返回的结果小于25且数量大于0但小于或等于2–49。例如,它可能返回25–2-50。

您使用的C实现有时使用64位浮点格式,有时使用80位浮点格式。只要数字以80位格式保留,它就保留pow返回的完整值。如果将此值转换为整数,则会产生24,因为该值小于25,并且转换为整数截断;它不圆。将数字转换为64位格式时,将对其进行舍入。在浮点格式之间进行舍入,因此结果舍入为最接近的可表示值25。此后,转换为整数将产生25。

从某种意义上说,只要"方便",编译器就可以切换格式。例如,数量有限的80位格式的寄存器。当它们已满时,编译器可能会将某些值转换为64位格式,并将其存储在内存中。编译器还可以在编译时而不是在运行时重新排列表达式或执行表达式的一部分,这些表达式可能会影响所执行的算法和所使用的格式。

当C实现混用浮点格式时,这很麻烦,因为用户通常无法预测或控制何时进行格式之间的转换。这会导致结果难以再现,并且会干扰软件的数值属性的推导或控制。可以将C实现设计为始终使用单一格式,并避免其中的某些问题,但您的C实现显然不是这样设计的。

除了你的最后一段,我都同意。当实现不混合浮点格式时,实际上更糟。然后,您的代码似乎可以正常工作,并且漏洞会被忽略。正是由于他的实现,他才知道他不能在一个实际上不能依赖于可预测的领域中依靠可预测的实现。当您做错了什么时,由于失败而导致实施失败的时间越早,越好。

@DavidSchwartz:这是有害的立场,主张程序员接受草率的编译器。当编译器的行为使设计好的软件变得困难时,应将其视为编译器中的错误。 (符合C标准不是编译器的终点。它们可以并且应该超越此标准,并且应该在其浮点规范中进行改进。)

对于不需要拧紧的人,拧紧标准将导致较差的性能。 这可能是一个不错的折衷,但我并不相信。 只要标准允许这种行为,要么必须将代码限制为仅在指定为以超出标准要求的特定方式运行的编译器上运行,否则代码将被破坏。 我认为主张代码应围绕某些特定编译器可能提供的保证而构建是错误的,尤其是因为您是根据表现行为(而不是保证)来表达自己的评论。

要在此处添加其他答案:使用浮点值时通常要非常小心。

我强烈建议您阅读本文(即使阅读时间很长):

http://hal.archives-ouvertes.fr/docs/00/28/14/29/PDF/floating-point-article.pdf

跳至第3节以获取实际示例,但请不要忽略前面的章节!

我相当确定这可以通过"中间舍入"和pow不是简单地循环乘以i而是围绕j倍,而是使用exp(log(i)*j)作为浮点计算的事实来解释。中间舍入可以很好地将24.999999999996转换为25.000000000-即使值的任意存储和重装也可能导致这种行为上的差异,因此,取决于代码的生成方式,它可能会与实际结果有所不同。

当然,在某些情况下,编译器甚至可以"知道" pow的实际作用,并用恒定的结果替换计算。

c语言xp与pow的差别,关于c ++:调用pow()时舍入结果的差异相关推荐

  1. python中pow是什么函数_python中pow什么意思

    python中pow什么意思? python中pow() 方法返回 xy(x的y次方) 的值. 语法 以下是 math 模块 pow() 方法的语法:import math math.pow( x, ...

  2. c语言访问oc变量,OC中的方法调用流程

    OC是一门动态语言,其方法调用方式与C++还是有很大区别的. 具体的方法调用过程,可以参考下面一片枫叶的博客,写的还是很详细的. 对于OC的方法调用,有两个点是重点: 1.对于OC的一切方法调用,最终 ...

  3. python pow函数用法_Python代码中pow()函数具有哪些功能呢?

    摘要: 下文讲述Python代码中pow()函数的功能说明,如下所示: pow函数功能说明 pow() 函数用于 计算 xy(x 的 y 次方) 的值 pow函数语法: import math mat ...

  4. 易语言服务器调试输出为假,易语言判断、如果真、文本到整数比较时,调试时运行正常,编译后不正常...

    今天在用易语言帮一个客户写程序的时候,发言一个奇怪的问题,就是在用判断.如果真命令比较2个文本到整数后的值时,在调试运行的时候,一切正常,但是编译出来后,运行不正常,不符合逻辑,最终经过调试输出,发现 ...

  5. python里面pow是什么意思_python中pow是什么意思

    pow()方法返回xy(x的y次方)的值. 语法 以下是math模块pow()方法的语法:import math math.pow( x, y ) 内置的pow()方法pow(x, y[, z]) 函 ...

  6. python power函数_python中pow函数的用法_python中pow函数用法及功能说明

    幂运算是高更数学的应用学科,是一种关于幂的数学运算.同底数幂相乘,底数不变,指数相加.同底数幂相除,底数不变,指数相减.幂的乘方,底数不变,指数相乘.适用于精确计算领域. 计算机作为精确计算的一种方式 ...

  7. python中pow函数的用法_python中pow函数用法及功能说明

    幂运算是高更数学的应用学科,是一种关于幂的数学运算.同底数幂相乘,底数不变,指数相加.同底数幂相除,底数不变,指数相减.幂的乘方,底数不变,指数相乘.适用于精确计算领域. 计算机作为精确计算的一种方式 ...

  8. 天天向上python题目答案_python语言程序设计基础 习题 天天向上的力量(math.pow)...

    实例1: 一年365天,,以第一天的能力值为基数1.0,当好好学习时能力值相比前一天提高1%,没有学习时能力值相比前天要降低1%,每天努力和每天放任,一年下来的能力值相差多少? 解析: 如果每天都好好 ...

  9. c语言 overflow_C语言和其他语言的不得不说的差别!

    提到C语言,我们知道c语言和其他高级语言的最大的区别就是C语言是要操作内存的!我们需要知道--变量,其实是内存地址的一个抽像名字罢了.在静态编译的程序中,所有的变量名都会在编译时被转成内存地址.机器是 ...

最新文章

  1. mac下mysql5.7.10密码问题
  2. MyBatis 的工作原理,你了解过吗?
  3. 创建oracle数据库有哪些方法,oracle11g创建数据库的方法-Oracle
  4. 高通平台java层操作NV数据的方法
  5. java构造函数中的this_关于构造函数中使用this的问题
  6. [dp][前缀和] Jzoj P5907 轻功(qinggong)
  7. Nacos源码DistroConsistencyServiceImpl
  8. JMS学习(1):MS基本概念
  9. 亿些模板【字符串+其他】
  10. Django模型定义参考
  11. 安卓入门程序《发短信》
  12. MySQL 在512M一下内存优化配置
  13. java yml文件_Yml文件的写入和读取
  14. python3url编解码base64编解码ASE加解密
  15. 基于单片机的音乐播放器设计
  16. 免费思维导图软件, 简单脑图工具,支持导出图片
  17. localtime和localtime_r
  18. distinct返回null报错_distinct
  19. 一个男孩子如果到了23岁,就不会再长高了。。。
  20. [河北师范大学“云淮杯”][D]MJJ玩磁铁(Java)(贪心)

热门文章

  1. 【Ocr】ocr表格检测;返回结果说明;可定制表格模板识别处理
  2. 嵌入式开发常用到的在线工具
  3. TcaplusDB君 · 行业新闻汇编(11月08号)
  4. win10语言栏不见了_当我把电脑的系统语言改成了西班牙语,从此打开了新世界的大门!...
  5. 什么是高内聚与低耦合?
  6. 利用eyoucms快速构建网站
  7. Python之pip:pip包管理工具的简介、安装、使用方法之详细攻略
  8. 一个简单的百度换肤效果
  9. java webservice开发和调用(jdk1.5+eclipse3.4 + tomcat5.5+axis1.4+xfire1.2.6)
  10. 什么是中央银行数字货币 (CBDC)?为什么各国都喜欢它?