C 什么是记录十进制数的最好方法?
我的问题是从mod计算中得到最准确的结果,我得到了一个余数答案来进行另一个舍入计算,所以我确实需要一个准确的结果来这样做C 什么是记录十进制数的最好方法?,c,math,floating-point,double,C,Math,Floating Point,Double,我的问题是从mod计算中得到最准确的结果,我得到了一个余数答案来进行另一个舍入计算,所以我确实需要一个准确的结果来这样做 double a=0.12345678…(可能包含多个数字) double b=fmod(a,0.01) 结果b可能不准确,无法处理二进制存储问题 我必须考虑使用浮点< /代码>来提高准确性。 或者我只是把数字从小数点移到整数 double a=12345678.0 谢谢如果我正确理解了您的问题,您需要fmod在double中的结果。正如Pascal Couq在评论中所述,f
double a=0.12345678…(可能包含多个数字)代码>
double b=fmod(a,0.01)代码>
结果b
可能不准确,无法处理二进制存储问题
<>我必须考虑使用<代码>浮点< /代码>来提高准确性。
或者我只是把数字从小数点移到整数
double a=12345678.0代码>
谢谢如果我正确理解了您的问题,您需要fmod
在double
中的结果。正如Pascal Couq在评论中所述,fmod
原型是double fmod(double x,double y)代码>您可以这样做:
#include<stdio.h>
#include<math.h>
int main()
{
double a = 12.1649232848373633242;
double b = 1.234;
double c;
setbuf(stdout,NULL);
c = fmod(a,b);
printf("%.13f",c);//.13 in the format specifiers here describes the number of decimal places upto which you want to get the value .
return 0;
}
#包括
#包括
int main()
{
双a=12.1649232848373633242;
双b=1.234;
双c;
setbuf(标准输出,空);
c=fmod(a,b);
此处格式说明符中的printf(“%.13f”,c);//.13描述了要获取值的小数位数。
返回0;
}
如果我确实正确理解了您的问题,您希望fmod
的结果出现在double
中。正如Pascal Couq在评论中所述,fmod
原型是double fmod(double x,double y)代码>您可以这样做:
#include<stdio.h>
#include<math.h>
int main()
{
double a = 12.1649232848373633242;
double b = 1.234;
double c;
setbuf(stdout,NULL);
c = fmod(a,b);
printf("%.13f",c);//.13 in the format specifiers here describes the number of decimal places upto which you want to get the value .
return 0;
}
#包括
#包括
int main()
{
双a=12.1649232848373633242;
双b=1.234;
双c;
setbuf(标准输出,空);
c=fmod(a,b);
此处格式说明符中的printf(“%.13f”,c);//.13描述了要获取值的小数位数。
返回0;
}
首先,任何严格的fmod实现都将以单精度/双精度/任意精度回答最接近余数的浮点,就像以无限精度执行除法一样。
(注意:感谢@EricPostpischil)
不过,那太晚了。二进制浮点内部表示法0.01并不像您已经知道的那样精确地表示1/100
让我们看看误差是如何累积的
你想知道除法的余数,比如说a%b=c
您有不精确的表示法a1和b1,并且您知道这些表示法的错误界限:a1=a+ea1
,abs(ea1)
,b1=b+eb1
,abs(eb1)
关于a1%b1=c1
(精确的操作),c1=c+ec1
这是关于错误界限abs(ec1)
,你能说些什么
a = q * b + c.
a1 = q1 * b1 + c1.
a+ea1 = (q+eq1)*(b+eb1) + (c+ec1).
ea1 = eq1*(b+eb1) + q*eb1 + ec1.
ec1 = ea1 - q*eb1 - eq1*(b+eb1).
ec >= max( ea , abs(q)*eb , eq*abs(b) , eq*eb).
ec <= ea + abs(q)*eb + eq*abs(b) + eq*eb.
不要尝试余数
对商进行四舍五入而不是截断的fmod
变体,这将使问题接近完美的平局(当精确除法a/b是1/2的倍数时)
通过仔细分析误差范围,您可以回答ec
的估计值,并确定商q
四舍五入可能不正确的坏情况(当a1/b1
接近整整数时),或abs(q)*eb
达到1,或ea>=b
在坏情况下,您可以安排引发异常,并以更高的精度重新生成a1
和b1
,但在边缘情况下c=0
,即使具有任意精度,也无法保证收敛性。首先,任何严格的fmod实现都将以单精度/双精度/任意精度回答最接近余数的浮点,就像以无限精度执行除法一样。
(注意:感谢@EricPostpischil)
不过,那太晚了。二进制浮点内部表示法0.01并不像您已经知道的那样精确地表示1/100
让我们看看误差是如何累积的
你想知道除法的余数,比如说a%b=c
您有不精确的表示法a1和b1,并且您知道这些表示法的错误界限:a1=a+ea1
,abs(ea1)
,b1=b+eb1
,abs(eb1)
关于a1%b1=c1
(精确的操作),c1=c+ec1
这是关于错误界限abs(ec1)
,你能说些什么
a = q * b + c.
a1 = q1 * b1 + c1.
a+ea1 = (q+eq1)*(b+eb1) + (c+ec1).
ea1 = eq1*(b+eb1) + q*eb1 + ec1.
ec1 = ea1 - q*eb1 - eq1*(b+eb1).
ec >= max( ea , abs(q)*eb , eq*abs(b) , eq*eb).
ec <= ea + abs(q)*eb + eq*abs(b) + eq*eb.
不要尝试余数
对商进行四舍五入而不是截断的fmod
变体,这将使问题接近完美的平局(当精确除法a/b是1/2的倍数时)
通过仔细分析误差范围,您可以回答ec
的估计值,并确定商q
四舍五入可能不正确的坏情况(当a1/b1
接近整整数时),或abs(q)*eb
达到1,或ea>=b
在坏情况下,您可以安排引发异常,并以更高的精度重新生成a1
和b1
,但在边缘情况下c=0
,即使具有任意精度,也无法保证收敛性。您所说的“精确”是什么意思;精确还是近似?我认为是精确还是正确的方法。你说的“精确”是什么意思;精确还是近似?我认为是精确还是任何合适的方法。fmod
的原型是double fmod(double x,double y)代码>。我不认为将结果强制转换为double
可以实现任何效果(而且我对C中的浮点运算了解得比我想的多)。@PascalCuoq是的,绝对是的,先生,实际上我认为它的结果可能与系统有关,所以我直接进行了值强制转换,甚至没有考虑这种方法。无论如何,谢谢你的建议,更新了我的答案::)@PascalCuoq我无法完全理解OP的问题,但我试着回答他的部分,“有没有合适的方法来做到这一点?”fmod
的原型是double-fmod(double-x,double-y)代码>。我不认为这是可以的