(双)算术不准确 [英] (double) aithmetic not accurate

查看:72
本文介绍了(双)算术不准确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我做了以下功能,用来驱动步进电机



Hello everyone,
I made the following function, which i use to drive stepper motor

int16 position2steps(double position)
{
   int16 steps = 0;
   if(!strcmp("HALF", step_mode))
      steps = (position / half_angle);
   else
      steps = (position / step_angle);
   return steps;
}



假设这个初始条件[step_angle = 1.8和half_angle = 0.9]

现在如果(position = 0.9和step_mode =一半)这个函数应该返回1



但是如果我经常使用这个函数它会给1一段时间然后它返回0因为值= 0.99然后转换为int = 0



i想知道是什么问题以及如何避免它



谢谢提前,

z3ngew


suppose this initial condition [ step_angle = 1.8 and half_angle = 0.9]
Now if (position = 0.9 and step_mode = half) this function should return 1

but if i use this function frequently it give 1 for some time but then it return 0 because the value = 0.99 and then converted to int = 0

i would like to know what is the problem and how to avoid it

Thanks in advance,
z3ngew

推荐答案

Quote:

但如果我经常使用这个函数它会给1一段时间,但它会返回0

but if i use this function frequently it give 1 for some time but then it return 0





这是一个非常奇怪的评论,因为它应该总是返回相同输入的相同输出。



然而,并非所有数字都可以精确地表示为双精度数。这意味着你最终得到了一些东西。因此,2个数字的除法或乘法有时会产生少量错误的结果。



将double转换为int时,必须预料到这一点。你可以通过允许误差来做到这一点。



一种常见的方法是添加一个小值。例如





This is a very strange comment because it should always return the same output for the same input.

Nevertheless not all numbers can be exactly represented as a double. This means you end up with something close. For this reason the division or multiplication of 2 numbers sometimes produces a result that appears wrong by a small amount.

When converting a double to an int you must anticipate this. You do this by allowing a margin of error.

A common way is to add a small value. For example

steps = (position / half_angle) + 0.001;


浮点数不能准确地表示每个实数,只有少数几个。如果你说例如d = 1.333那么d将包含一个接近1.333但不完全是1.333的浮点值,因为它无法准确表示。 0.1和0.9和1.8也是如此。对于远离零的值(正方向或负方向),此误差更大,整个零件中使用的位数越多,小数部分的精度就越低。这里我们已经有一个小错误,我们没有对数字做任何事情,只是将它存储为浮点数。想象一下,如果你有很多浮点值在你想要使用的实数(如1.8和0.9)的表示中已经有一点误差,然后你执行加法,减法,除法等操作,会发生什么。这些错误累积起来并随着(随机数量)时间逐渐变大。



在这种情况下,正确的解决方案是使用整数(定点算术 [ ^ ])。

定点实现: ^ ]
Floating point numbers can not accurately represent every real numbers, just a few of them. If you say for example d=1.333 then d will contain a floating point value that is near to 1.333 but isn't exactly 1.333 because it can not be accurately represented. The same is true to 0.1 and 0.9 and 1.8. This error is larger for values that are further from zero (either in positive or negative direction), the more digits you use in the whole part the less precision you have in the fractional part. Here we already have a small error and we did nothing with the number, just stored it as floating point. Imagine what happens if you have a lot of floating point values that already have a bit of error in the representation of the real numbers you want to use (like 1.8 and 0.9) and then you perform operations like addition, substraction, division,... These errors accumulate and with (random amount of) time they usually grow larger.

In this case a correct solution would be using integers (Fixed point arithmetic[^]).
Fixed point implementation: Fixed Point Class[^]


如果要舍入到最接近的整数,请在转换为整数之前将值0.5添加到结果中。如果要向下舍入,请添加一个小值(例如,在您的情况下为0.01)。



问题是大多数有理数不能使用浮点数精确表示点数。如果您想了解更多信息,可以从维基百科上的浮点数文章开始[ ^ ]。
If you want to round to the nearest integer, add a value of 0.5 to the result before converting to an integer. If you want to round down, add a small value (e.g. 0.01 in your case).

The problem is that most rational numbers can't be represented exactly using floating point numbers. If you want to know more, you may start at the Wikipedia article on Floating point[^].


这篇关于(双)算术不准确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆