考虑下面两个非常简单的乘法:
double result1;
long double result2;
float var1=3.1;
float var2=6.789;
double var3=87.45;
double var4=234.987;
result1=var1*var2;
result2=var3*var4;
默认情况下乘法的精度是否高于操作数?我的意思是,如果第一次乘法是以 double 完成的,如果是 x86 架构中的第二次乘法,它是以 80 位扩展精度完成的,还是我们应该像下面那样将表达式中的操作数转换为更高精度?
result1=(double)var1*(double)var2;
result2=(long double)var3*(long double)var4;
其他操作(加、除、取余)呢?例如,当添加两个以上的正单精度值时,如果用于保存表达式的中间结果,使用 double 的额外有效位可以减少舍入误差。
最佳答案
C++11 incorporates cfloat 中来自 C99 的 FLT_EVAL_METHOD 的定义。
FLT_EVAL_METHOD Possible values: -1 undetermined 0 evaluate just to the range and precision of the type 1 evaluate float and double as double, and long double as long double. 2 evaluate all as long double
If your compiler defines FLT_EVAL_METHOD as 2, then the computations of r1 and r2, and of s1 and s2 below are respectively equivalent:
double var3 = …;
double var4 = …;
double r1 = var3 * var4;
double r2 = (long double)var3 * (long double)var4;
long double s1 = var3 * var4;
long double s2 = (long double)var3 * (long double)var4;
如果您的编译器将 FLT_EVAL_METHOD 定义为 2,则在上述所有四种计算中,乘法均以 long double 类型的精度完成。
但是,如果编译器将FLT_EVAL_METHOD定义为0或1,则r1和r2,分别为s1和 s2,并不总是相同的。计算 r1 和 s1 时的乘法以 double 的精度完成。计算 r2 和 s2 时的乘法以 long double 的精度完成。
如果您正在计算的结果注定要存储在比操作数类型更广泛的结果类型中,就像您问题中的 result1 和 result2 一样,您应该始终将参数转换为至少与目标一样宽的类型,就像您在此处所做的那样:
result2=(long double)var3*(long double)var4;
如果不进行这种转换(如果您编写 var3 * var4),如果编译器对 FLT_EVAL_METHOD 的定义为 0 或 1,则将以 的精度计算乘积code>double,这是一种耻辱,因为它注定要存储在 long double 中。
如果编译器将 FLT_EVAL_METHOD 定义为 2,则 (long double)var3*(long double)var4 中的转换不是必需的,但它们也无妨: 无论有没有它们,这个表达式的意思完全一样。
矛盾的是,对于单个操作,最好只四舍五入到目标精度。以扩展精度计算单个乘法的唯一影响是结果将四舍五入为扩展精度,然后为 double 精度。这使得它成为less accurate .换句话说,当 FLT_EVAL_METHOD 为 0 或 1 时,上面的结果 r2 由于双舍入有时不如 r1 准确,如果编译器使用 IEEE 754 浮点,再好不过了。
对于包含多个操作的较大表达式,情况有所不同。对于这些,通常最好通过显式转换或因为编译器使用 FLT_EVAL_METHOD == 2 以扩展精度计算中间结果。这question及其接受的答案表明,当使用 80 位扩展精度中间计算对 binary64 IEEE 754 参数和结果进行计算时,插值公式 u2 * (1.0 - u1) + u1 * u3 总是产生介于两者之间的结果u2 和 u3 for u1 介于 0 和 1 之间。此属性可能不适用于 binary64 精度的中间计算,因为那时会出现较大的舍入误差。
关于c++ - 浮点算术运算的精度是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25302480/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
当谈到运行时自省(introspection)和动态代码生成时,我认为ruby没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow
我正在尝试使用正则表达式验证美元金额:^[0-9]+\.[0-9]{2}$这工作正常,但每当用户提交表单并且美元金额以0(零)结尾时,ruby(或rails?)将0砍掉。所以500.00变成500.0,因此正则表达式验证失败。有没有办法让ruby/rails保持用户输入的格式,而不管尾随零? 最佳答案 我假设您的美元金额是小数类型。因此,用户在字段中输入的任何值在保存到数据库之前都会从字符串转换为适当的类型。验证适用于已转换为数字类型的值,因此在您的情况下,正则表达式并不是真正合适的验证过滤器。不过,您有几种可能性可以解决这个问
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“