【问题标题】:How can I intentionally create random floating point / decimal precision errors in java?如何在java中故意创建随机浮点/小数精度​​错误?
【发布时间】:2021-04-17 01:48:55
【问题描述】:

我的目标是生成所有具有小数精度错误的随机数。

以下是我想生成的数字类型的一些示例:

1.8181818723678589
1.2727272510528564
0.444444477558136

这是我尝试过的策略。

parseFloat("4.01500000000000000001"); BigDecimal.valueOf(ThreadLocalRandom.current().nextFloat()).multiply(BigDecimal.valueOf(ThreadLocalRandom.current().nextFloat())).doubleValue();

我尝试过的所有事情都没有创建一个与我正在寻找的数字相似的数字。

【问题讨论】:

  • 所以基本上,你希望小数位先规则一段时间,然后变得不规则?
  • @Sweeper 我认为所有这些数字都有某种小数点错误。我最初是通过测试不同的触摸事件(例如 Touch.radiusX Touch.radiusY)发现这些数字的。我想学习如何在数学上为这些事件创建类似的舍入误差。
  • 听起来您正在使用某种 UI 框架?如果您可以查看他们的源代码,您应该能够确切地看到radiusXradiusY 是如何计算的。无论如何,一般来说,错误会累积,所以只要你做足够的计算,你就会看到它们。尝试将一百个 0.1 加在一起(全部为 floats),得到 10.000002。这是你想要的那种错误吗?不要使用BigDecimal,因为它准确地表示 - 与您想要的相反。
  • @Sweeper 我通过按我的屏幕从移动设备上的 Chrome 获取这些数字。我在下面放了一个链接。 developer.mozilla.org/en-US/docs/Web/API/Touch/radiusX 我还会检查铬源,看看这是如何计算的。

标签: java random floating-point double precision


【解决方案1】:

假设确切的值实际上意味着是:

  • 1.81 重复
  • 1.27 重复
  • 0.4 次重复

请注意,在每个数字中,大约有 7 或 8 个数字是“正确的”,总共大约 18 个数字。 floats 通常精确到 7 到 8 位,doubles 通常精确到 18 位左右,所以我怀疑这些数字实际上是 floats(或 32 位浮点数),得到了“加宽” " 成为doubles

1.81 重复是 20/11,所以我尝试了:

float i = 20f/11f;
double d = i;
System.out.println(d);

这将准确打印您看到的值 - 1.8181818723678589。

1.27 重复是 14/11,0.4 重复是 4/9。您可以自己尝试这两种方法。它们都会产生您想要的数字。这强烈表明错误是通过将float 扩大到 64 位产生的。

【讨论】:

  • 太棒了!谢谢。
猜你喜欢
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多