为什么我的表达给出错误答案?

时间:2012-09-14 07:19:01

标签: java android floating-point seekbar

在这种情况下,我的'f'值总是从88到108,我需要将该值映射到我的搜索栏范围,从0到200

除了f = 88.1,88.2,89.1; 89.2 ......等等之外,我在这里提出的表达式对所有值都很好。

String value = b.getText().toString();

    float f= Float.parseFloat(value);


    int progress = (int) (f-(float)88.0)*10;
    s.setProgress( progress);

我在搜索栏中设置了我的进度,然后我恢复了我的f值并设置了文本视图

float channel = (float) ((float)88.0 + ((float)progress/10));
            String mytext=Float.toString(channel);
            t.setText(mytext);

但textview显示0.1比我原来的值少;如88.2显示f = 88.1,88.1显示f = 88.0等等......

有人可以帮我解决这个问题吗?

我得到了解决方案并且我将其标记为正确,但是有人可以告诉我为什么会发生这种奇怪的事情吗?

2 个答案:

答案 0 :(得分:2)

你有没有试过检查相反的情况。多个乘以10然后减去880以查看问题是否仍在此处。

int progress = (int) ((f*10) - 880);

答案 1 :(得分:0)

二进制浮点并不完全代表所有值。特别是,值88.1,88.2,89.1和89.2在二进制浮点中不可表示。相反,任何计算或转换的精确数学结果都是这些值之一,而是产生一个接近精确结果的二进制浮点值。

在通常的默认模式下,返回最接近精确结果的可表示结果。 (这是针对每个执行的操作。当您进行多次算术运算时,舍入到可表示结果的效果可能会复合,产生更大的差异。)有时可表示的结果大于精确结果,有时则更少。

因此,您的对象f不包含88.1,88.2,89.1或89.2。它包含一些略高或略低的其他值。当你减去88并乘以10时,你可能正好有1或2,如果舍入的效果恰好已经取消并给你一个确切的结果,但你可能有一个略高于1或2的值或一个值略低于1或2。

然后使用(int)强制转换将该值转换为整数。此转换截断;它不圆。因此,如果该值略低于1,则转换的结果为0。

如果您希望转换为整数而不是截断,则可以添加.5:int progress = (int) ((f-88.f)*10 + .5);。 (如果你想在平局的情况下舍入方向,当到最近的整数的距离完全相等时,你必须使用不同的解决方案。)

此舍入将缓解您在此问题中询问的特定问题,但可能仍会出现伪影。例如,如果f非常接近某个值,如88.15,则将其舍入以产生1(对于.1)或2(对于.2)的进度,然后从该进度重构f可能会产生88.2,即使f稍微接近到88.1(略低于88.15)或者可能产生88.1,即使f略微接近88.2(略高于88.15)。