【问题标题】:std::mt19937 gives the same random float for identical first float numbers ex(1.2, 1.5)std::mt19937 为相同的第一个浮点数 ex(1.2, 1.5) 给出相同的随机浮点数
【发布时间】:2020-12-20 20:35:25
【问题描述】:

我有这个看起来像这样的随机浮点函数:

float randomFloat(float input)
{
    std::mt19937 mt;
    mt.seed(input);
    std::uniform_real_distribution<float> dt(-1,1);

    return dt(mt);
}

如您所见,该函数接受输入并返回介于 -1 和 1 之间的输出

但我的问题是,当我给出输入浮点数时,如果点左侧的数字相同。示例:(1.2, 1.52, 1.658, 1.01...) 随机浮点数将给出相同的值,(为糟糕的英语道歉)

所以一个 1.5 的输入和另一个 1.2 的输入将给出相同的返回值,而一个 1.5 的输入和另一个 2.5 的输入将给出不同的值。我该如何解决这个问题?

请记住,我并没有试图准确地获得 randomFloat,我的问题有点复杂,但如果我能就这个特定问题获得帮助,其他一切都会很容易,以及我说的原因这是我不希望答案告诉我使用 random_device 或 mt 应该播种一次...我已经知道,this 是我正在研究的,如果你真的想知道的话。

谢谢!

【问题讨论】:

  • 嗯。我从来没有注意到你可以用float 播种。
  • 您每次都传递相同的种子(截断后),因此您得到相同的序列 - 这是预期的。

标签: c++ random mt19937


【解决方案1】:

预期的种子值是一个无符号的整数类型;传递float 实际上只是传递所述float 的截断整数值。

您可以从signature of seed, which returns result_typethe documentation of result_type 推导出这个:

result_type - 引擎生成的整数类型。如果这不是无符号整数类型,则结果未定义。

【讨论】:

  • 回答了这个问题。你不能真正用浮动播种。
  • 所以我无法使用浮点数作为种子?
  • @user4581301:是的。我想如果他们需要 API 接受float 他们可以向上转换为double 并乘以10000(或其他)以使用小数点后的一些值,但是即使这样,它也是一个糟糕的设计(你总是会冒着丢弃数据的风险,要么是由于量级较高端的溢出,要么是较低端的未使用精度。
  • @Ronaldjoe:我猜你可以使用one of these options 将其转换为保留更多信息的整数?这不是 API 的预期用途。
  • @Ronald “所以我无法使用浮点数作为种子?” - 当然可以 - 你已经在这样做了;它只是被截断。但是,您可以使用浮点数的不同部分进行播种,例如将句点之前的部分作为种子的一部分,将剩余的位作为第二部分,或者您可以将浮点数分解成若干位的块并用这些进行播种。等等等等。另见en.cppreference.com/w/cpp/numeric/random/seed_seq
【解决方案2】:

std::mt19937 的结果类型是 std::uint_fast32_t,这也是种子的参数类型,所以浮点数会被截断。

【讨论】:

    猜你喜欢
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 2018-05-14
    • 2015-03-08
    • 2010-12-14
    • 2019-11-28
    相关资源
    最近更新 更多