Android(大)在浮点值产品上失败
情况很戏剧性...我必须在 5 天后解决这个问题,但我却出不去。
问题是:作为产品的简单操作总是会产生错误的结果。为什么?
代码摘录:
//all vars are float
// resultVec is a vector [3]
// Rs is a vector [3]
// accelerationvalues is a vector [3]
resultVec[0]=Rs[0]*accelerationvalues[0]+Rs[1]*accelerationvalues[1]+Rs[2]*accelerationvalues[2];
//debug to print result
Log.d("e", "("+Rs[0]+")*("+accelerationvalues[0]+")+("+Rs[1]+")*("+accelerationvalues[1]+")+("+Rs[2]+")*("+accelerationvalues[2]+")="+(resultVec[0]));
这是 Log Cat 结果: 但你可以简单地尝试一下这是错误的:在谷歌上搜索
(0.040147018)*(-0.9942854)+(0.9984244)*(-0.32688835)+(0.039202508)*(9.343558)
,你会发现真正的结果是 8.67678679 × 10-9 ,与其他结果非常不同..这个错误总是在我重复出现执行程序,有时符号也有区别!
问题是什么?
我已经想尽办法解决了! (一些发布在下面):
- 将 Rs 和加速度值保存在数组列表中并在列表器外部执行计算。没有结果。
- 将 float 转换为 double,没有结果。
- 还有许多其他
方式此问题仅在 resultVec[0]
和 resultVec[1]
中出现,而 resultVec[2]
计算得很好。
the situation is drammatic... It's 5 days that i must resolve this problem and i can't get out.
The problem: a simple operation as a product make always wrong result. Why?
Extract of the code:
//all vars are float
// resultVec is a vector [3]
// Rs is a vector [3]
// accelerationvalues is a vector [3]
resultVec[0]=Rs[0]*accelerationvalues[0]+Rs[1]*accelerationvalues[1]+Rs[2]*accelerationvalues[2];
//debug to print result
Log.d("e", "("+Rs[0]+")*("+accelerationvalues[0]+")+("+Rs[1]+")*("+accelerationvalues[1]+")+("+Rs[2]+")*("+accelerationvalues[2]+")="+(resultVec[0]));
And this is the Log Cat result:
But you can simply try that this is wrong: search on google
(0.040147018)*(-0.9942854)+(0.9984244)*(-0.32688835)+(0.039202508)*(9.343558)
And you'll find that the true result is 8.67678679 × 10-9 that is very different from the other..This error is repeated always i execute the programm, some time the difference is in the sign too!
What is the problem?
I've tried all the way to solve it! (some are posted below):
You can find the full source here.
- save Rs and accelerationvalues in an arraylist and perform calculation outside the listner. No result.
- Convert float to double, no result.
- Many others ways
P.S. This problem occour only for resultVec[0]
and resultVec[1]
, instead resultVec[2]
is well calculated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你正在乘以浮点数,一路向下累积舍入误差。使用双精度并不能解决根本问题,即二进制计算机无法准确表示十进制浮点数。
阅读此内容: http://download.oracle.com/ docs/cd/E19957-01/806-3568/ncg_goldberg.html 了解问题的概述。
您可能会发现需要使用 BigDecimal 类执行计算。
you're multiplying floating point numbers, accumulating rounding errors all the way down. Using double-precision won't solve the underlying issue, which is that binary computers cannot accurately represent decimal floating point numbers.
Read this: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html for an overview of the problem.
You'll likely find you need to perform the calculations using the BigDecimal class.
这不是安卓的错,而是你设计应用程序的方式的问题。
在普通的 Java 应用程序中执行此操作:
如您所见,第一个打印输出与 Google 的相同,第二个打印输出是您的应用程序的值。
为了解决这个问题,我认为您应该在声明的每个变量中使用 double 而不是 float,例如:accelerationvalues 和 resultVec。
This is not android's fault, it is how you designed the app.
Execute this in a plain Java application:
As you can see, the first one is the same as Google's, and the second printout is your app's value.
To solve this, I think you should use double instead of float in every variable you declared, e.g.:
accelerationvalues
andresultVec
.我认为你应该使用 double 类型而不是 float
I think that you should to use double type instead of float
您可能会遇到浮点值精度有限的问题。为了确认这一点,您可以将
float
更改为double
或使用BigDecimal
。You might be running into the limited precision of floating point values. In order to confirm this you can change the
float
intodouble
or useBigDecimal
.