Android(大)在浮点值产品上失败

发布于 2024-12-14 05:19:35 字数 1244 浏览 0 评论 0原文

情况很戏剧性...我必须在 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 ,与其他结果非常不同..这个错误总是在我重复出现执行程序,有时符号也有区别!

问题是什么?

我已经想尽办法解决了! (一些发布在下面):

您可以在这里找到完整的源代码。< /a>

  1. 将 Rs 和加速度值保存在数组列表中并在列表器外部执行计算。没有结果。
  2. 将 float 转换为 double,没有结果。
  3. 还有许多其他

方式此问题仅在 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:
enter image description here
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.

  1. save Rs and accelerationvalues in an arraylist and perform calculation outside the listner. No result.
  2. Convert float to double, no result.
  3. Many others ways

P.S. This problem occour only for resultVec[0] and resultVec[1], instead resultVec[2] is well calculated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月下凄凉 2024-12-21 05:19:35

你正在乘以浮点数,一路向下累积舍入误差。使用双精度并不能解决根本问题,即二进制计算机无法准确表示十进制浮点数。

阅读此内容: 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.

老旧海报 2024-12-21 05:19:35

这不是安卓的错,而是你设计应用程序的方式的问题。

在普通的 Java 应用程序中执行此操作:

public class ArithmTest {

    public static void main(String[] args) {
        double d1 = (0.040147018)*(-0.9942854)+(0.9984244)*(-0.32688835)+(0.039202508)*(9.343558);
        System.out.println(d1);

        float f1 = 0.040147018f;
        float f2 = -0.9942854f;

        float f3 = 0.9984244f;
        float f4 = -0.32688835f;

        float f5 = 0.039202508f;
        float f6 = 9.343558f;

        System.out.println(f1*f2 + f3*f4 + f5*f6);

    }
}

如您所见,第一个打印输出与 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:

public class ArithmTest {

    public static void main(String[] args) {
        double d1 = (0.040147018)*(-0.9942854)+(0.9984244)*(-0.32688835)+(0.039202508)*(9.343558);
        System.out.println(d1);

        float f1 = 0.040147018f;
        float f2 = -0.9942854f;

        float f3 = 0.9984244f;
        float f4 = -0.32688835f;

        float f5 = 0.039202508f;
        float f6 = 9.343558f;

        System.out.println(f1*f2 + f3*f4 + f5*f6);

    }
}

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 and resultVec.

策马西风 2024-12-21 05:19:35

我认为你应该使用 double 类型而不是 float

I think that you should to use double type instead of float

安稳善良 2024-12-21 05:19:35

您可能会遇到浮点值精度有限的问题。为了确认这一点,您可以将 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 into double or use BigDecimal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文