C 什么是记录十进制数的最好方法?

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

我的问题是从mod计算中得到最准确的结果,我得到了一个余数答案来进行另一个舍入计算,所以我确实需要一个准确的结果来这样做

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)。我不认为这是可以的