在这种情况下,我的'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等等......
有人可以帮我解决这个问题吗?
我得到了解决方案并且我将其标记为正确,但是有人可以告诉我为什么会发生这种奇怪的事情吗?
答案 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)。