“LlFrand”的版本间的差异
(创建页面,内容为“{{LSL Header|ml=*}}{{LSLC|Keywords}}{{LSLC|Flow Control}}{{LSLC|}} {{函数详情 |函数名 = Function: float llFrand( float mag ); |参数= 参数:float mag…”) |
|||
(未显示同一用户的1个中间版本) | |||
第4行: | 第4行: | ||
{{函数详情 | {{函数详情 | ||
|函数名 = Function: float llFrand( float mag ); | |函数名 = Function: float llFrand( float mag ); | ||
− | |参数= 参数:float mag – | + | |参数= 参数:float mag – 任何有效的浮点值 |
− | |返回值= | + | |返回值= 返回值:返回一个在[0.0,mag]或(mag,0.0].[1]范围内的伪随机浮点数 |
− | |注意事项= | + | |注意事项=随机数生成器不是熵的来源。 |
− | + | 随机数序列在整个模拟器过程中是共享的,而不是独立的种子。因此,伪随机数的产生不适合任何需要完全可预测或完全不可预测结果的应用。 | |
− | + | 应该记住,当把一个整数作为mag传递给llFrand时,它将被隐式地类型转换为一个float。 | |
− | + | 范围[-224,+224]之外的许多整数不能用浮点表示(这是浮点类型的固有限制);例如,在该范围之外不会出现奇数整数。因此,当将得到的浮点数转换为整数时,不可能生成大于224+1的均匀分布值,也不可能生成大于9*223+1或总计约7500万个不同的整数。可能需要两个llFrand调用来获得所需的整数范围;请参见下面的示例 | |
第26行: | 第26行: | ||
} | } | ||
− | // | + | // 有时在给定的范围内得到一个随机整数是有用的。这是一个令人惊讶的棘手和情绪化的话题,并引起了无休止的讨论关于脚本编制组。在使用llFrand时,概率错误的主要原因是在范围的边缘有一个不同的箱子大小。 |
− | |||
− | |||
− | |||
// | // | ||
− | // | + | // 正如括号符号所示,[0.0,mag),该函数包含0.0,不包含输入的值。因为LSL浮点数只是实数的一个子集,并且没有无限的粒度,所以这个模式适用于任何大于float t = 1.175494351e-38的浮点数;在这个值上,函数将只返回0。当浮点数超过这个值时,就会出现数学错误。 |
− | |||
− | |||
− | |||
− | |||
− | |||
// Random integer generator: | // Random integer generator: | ||
第42行: | 第34行: | ||
// original function posted by Hg Beeks | // original function posted by Hg Beeks | ||
− | // | + | // 返回一个最小到最大范围内的伪随机整数。 |
− | // | + | // 基本原理: |
− | // | + | // 将范围扩展1.0,以确保两端相对于范围中部的间距相等,然后使用整数强制转换向零进行四舍五入。 |
− | |||
− | |||
− | // | + | // 注意: |
− | // | + | // 此函数未检查范围,如果最大值<最小值,则会失败 |
integer random_integer(integer min, integer max) | integer random_integer(integer min, integer max) | ||
第78行: | 第68行: | ||
<pre> | <pre> | ||
− | // | + | // 生成具有大于1600万可能值的均匀分布整数的例子;特别是,这段代码将生成500,000,000个可能的值,范围从0到499,999,999(包括499,999,999)。 |
− | |||
− | |||
// | // | ||
− | // | + | // 该方法不针对大于16,777,216(2^24)的数使用llFrand(),而是使用(integer)llFrand(a)*b + (integer)llFrand(b)的格式将该范围划分为两个都小于该值的数,其中a*b给出了所需的范围。 |
− | |||
− | |||
− | |||
// | // | ||
− | // | + | // 对于质数范围,或者质数因子大于2^24的范围,应该使用拒绝方案(使用此方法生成略高于目标范围的数字,并拒绝它,如果它超过最大值,则生成一个新的数字)。 |
− | |||
− | |||
default | default | ||
第101行: | 第84行: | ||
</pre> | </pre> | ||
− | + | 下面的代码为随机负整数提供了最大的可能性(例如,适合用作通道号) | |
<pre> | <pre> | ||
integer rand = 0x80000000 | (integer)llFrand(65536) | ((integer)llFrand(65536) << 16); | integer rand = 0x80000000 | (integer)llFrand(65536) | ((integer)llFrand(65536) << 16); | ||
第110行: | 第93行: | ||
// Contributed by Mephistopheles Thalheimer | // Contributed by Mephistopheles Thalheimer | ||
− | // | + | // 这是一个随机数测试器,旨在快速直观地解释和证明为什么一些随机整数函数不起作用。一般来说,对于任何随机数生成器,如果你能看到一个模式出现,那么很有可能,这个函数不是随机的。 |
− | |||
− | |||
− | |||
− | // | + | // 给出的测试用例“silly_random_integer(..)”显示可能发生的陷阱类型。从表面上看,它似乎是一个不错的候选人。我认为是这样的,事实上在讨论中也提出过这个问题,但是,稍微考虑一下就会发现,第一个和最后一个bin只从浮动空间的一半收集四舍五入的结果,其余的是整数。因此,y在输出中表示不足,并且发生器有缺陷。 |
− | |||
− | |||
− | |||
− | |||
− | |||
第204行: | 第179行: | ||
<pre> | <pre> | ||
− | // | + | //指数分布 |
// | // | ||
// Contributed by Pat Perth on October 5th 2013 | // Contributed by Pat Perth on October 5th 2013 | ||
// No rights reserved | // No rights reserved | ||
// | // | ||
− | // | + | // 返回一个期望值为mean_value的指数分布随机数 |
// | // | ||
// Reference: Wikipedia article "Exponential distribution", in particular the section | // Reference: Wikipedia article "Exponential distribution", in particular the section | ||
第216行: | 第191行: | ||
// http://en.wikipedia.org/wiki/Exponential_distribution (visited on October 5th 2013) | // http://en.wikipedia.org/wiki/Exponential_distribution (visited on October 5th 2013) | ||
// | // | ||
− | // | + | // 指数分布通常是模拟等待时间的一种合适方法类似于“x秒后< >发生”。例如,如果您想“大约每7天”触发一次阵雨,使用time_between_rain = random_exponent (7.0 * 24.0 * 60.0 * 60.0);在llSleep(…)或llSetTimerEvent(…)调用中。 |
− | |||
− | |||
// | // | ||
− | // | + | // 请注意返回值中的负号 |
− | |||
− | |||
− | |||
− | |||
float random_exponential(float mean_value) | float random_exponential(float mean_value) |
2020年5月25日 (一) 09:32的最新版本
首页 | 函数 | 事件 | 类型 | 操作符 | 常数 | Flow Control | Script Library | Categorized Library | Tutorials |
函数名 |
---|
Function: float llFrand( float mag ); |
参数:float mag – 任何有效的浮点值 |
返回值:返回一个在[0.0,mag]或(mag,0.0].[1]范围内的伪随机浮点数 |
注意事项 |
---|
随机数生成器不是熵的来源。
随机数序列在整个模拟器过程中是共享的,而不是独立的种子。因此,伪随机数的产生不适合任何需要完全可预测或完全不可预测结果的应用。 应该记住,当把一个整数作为mag传递给llFrand时,它将被隐式地类型转换为一个float。 范围[-224,+224]之外的许多整数不能用浮点表示(这是浮点类型的固有限制);例如,在该范围之外不会出现奇数整数。因此,当将得到的浮点数转换为整数时,不可能生成大于224+1的均匀分布值,也不可能生成大于9*223+1或总计约7500万个不同的整数。可能需要两个llFrand调用来获得所需的整数范围;请参见下面的示例 |
示例 |
---|
// *near* 50:50 chance of "Heads" vs. "Tails" integer coin_toss() { if (llFrand(1.0) < 0.5) return TRUE; return FALSE; } // 有时在给定的范围内得到一个随机整数是有用的。这是一个令人惊讶的棘手和情绪化的话题,并引起了无休止的讨论关于脚本编制组。在使用llFrand时,概率错误的主要原因是在范围的边缘有一个不同的箱子大小。 // // 正如括号符号所示,[0.0,mag),该函数包含0.0,不包含输入的值。因为LSL浮点数只是实数的一个子集,并且没有无限的粒度,所以这个模式适用于任何大于float t = 1.175494351e-38的浮点数;在这个值上,函数将只返回0。当浮点数超过这个值时,就会出现数学错误。 // Random integer generator: // Contributed by Mephistopheles Thalheimer, // original function posted by Hg Beeks // 返回一个最小到最大范围内的伪随机整数。 // 基本原理: // 将范围扩展1.0,以确保两端相对于范围中部的间距相等,然后使用整数强制转换向零进行四舍五入。 // 注意: // 此函数未检查范围,如果最大值<最小值,则会失败 integer random_integer(integer min, integer max) { return min + (integer)(llFrand(max - min + 1)); } say(string message) { llSay(0, message); } default { touch_start(integer total_number) { // *near* 50:50 chance of "Heads" vs. "Tails" if (coin_toss()) say("Heads"); else say("Tails"); integer n1 = random_integer(2, 8); // Return a random number between 2 and 8 say("I chose a " + (string)n1); } } // 生成具有大于1600万可能值的均匀分布整数的例子;特别是,这段代码将生成500,000,000个可能的值,范围从0到499,999,999(包括499,999,999)。 // // 该方法不针对大于16,777,216(2^24)的数使用llFrand(),而是使用(integer)llFrand(a)*b + (integer)llFrand(b)的格式将该范围划分为两个都小于该值的数,其中a*b给出了所需的范围。 // // 对于质数范围,或者质数因子大于2^24的范围,应该使用拒绝方案(使用此方法生成略高于目标范围的数字,并拒绝它,如果它超过最大值,则生成一个新的数字)。 default { state_entry() { integer rand = (integer)llFrand(500)*1000000 + (integer)llFrand(1000000); llOwnerSay("Here's a random number between 0 and 499,999,999 inclusive: " + (string)rand); } } 下面的代码为随机负整数提供了最大的可能性(例如,适合用作通道号) integer rand = 0x80000000 | (integer)llFrand(65536) | ((integer)llFrand(65536) << 16); // Simple integer random number tester // Contributed by Mephistopheles Thalheimer // 这是一个随机数测试器,旨在快速直观地解释和证明为什么一些随机整数函数不起作用。一般来说,对于任何随机数生成器,如果你能看到一个模式出现,那么很有可能,这个函数不是随机的。 // 给出的测试用例“silly_random_integer(..)”显示可能发生的陷阱类型。从表面上看,它似乎是一个不错的候选人。我认为是这样的,事实上在讨论中也提出过这个问题,但是,稍微考虑一下就会发现,第一个和最后一个bin只从浮动空间的一半收集四舍五入的结果,其余的是整数。因此,y在输出中表示不足,并且发生器有缺陷。 integer random_integer(integer min, integer max) { return min + (integer)llFrand(max - min + 1); } integer silly_random_integer(integer min, integer max) { return min + (integer)(llRound(llFrand(max - min))); // Looks good, but does not work } say(string message) { llSay(0, message); } // Simple integer random number tester // Contributed by Mephistopheles Thalheimer list bins; integer MIN = 2; // The minimum integer you want integer MAX = 5; // The maximum integer you want integer NUMBER_OF_TRIES = 10000; // The bigger the better.. but slower default { state_entry() { say("Bin tester ready."); bins = []; } touch_start(integer total_number) { say("Started, be patient"); integer i; integer r; integer range = MAX - MIN; for (i = 0; i <= range; ++i) { bins += [ 0 ]; } integer v; integer out_of_range; for (i = 0; i < NUMBER_OF_TRIES; ++i) { // Replace the next line with the function you are testing r = silly_random_integer(MIN, MAX); // Note the output on the next line has about 0.5 expected hits on the first and last bin // r = random_integer(MIN, MAX); if (r > MAX || r < MIN) { out_of_range++; } else { v = llList2Integer(bins, r - MIN); bins = llListReplaceList(bins, [++v], r - MIN, r - MIN); } } for (i = 0; i <= range; ++i) { say("Bin #" + (string)(i + MIN) + " = " + (string)llList2Integer(bins, i)); } say("Number out of range = " + (string)out_of_range); } } //指数分布 // // Contributed by Pat Perth on October 5th 2013 // No rights reserved // // 返回一个期望值为mean_value的指数分布随机数 // // Reference: Wikipedia article "Exponential distribution", in particular the section // entitled "Generating exponential variates" at // // http://en.wikipedia.org/wiki/Exponential_distribution (visited on October 5th 2013) // // 指数分布通常是模拟等待时间的一种合适方法类似于“x秒后< >发生”。例如,如果您想“大约每7天”触发一次阵雨,使用time_between_rain = random_exponent (7.0 * 24.0 * 60.0 * 60.0);在llSleep(…)或llSetTimerEvent(…)调用中。 // // 请注意返回值中的负号 float random_exponential(float mean_value) { return -mean_value * llLog(llFrand(1.0)); } |
相关函数 |
---|
llListRandomize |
相关事件 |
---|
无 |