uniform(0, 1)
สามารถผลิต 0
แต่มันจะไม่เคย1
ผลิต
เอกสารบอกคุณว่าปลายทางb
จะถูกรวมอยู่ในค่าที่ผลิต:
ค่าสิ้นจุดอาจจะหรืออาจจะไม่ได้รวมอยู่ในช่วงขึ้นอยู่กับจุดลอยปัดเศษในสมการb
a + (b-a) * random()
ดังนั้นสำหรับuniform(0, 1)
สูตรที่0 + (1-0) * random()
ง่าย1 * random()
ขึ้นจะต้องมีความสามารถในการผลิต1
อย่างแน่นอน ที่จะเกิดขึ้นถ้าrandom.random()
เป็น 1.0 exactly. However,
สุ่ม () *never* produces
1.0`
การอ้างถึงrandom.random()
เอกสาร :
ส่งคืนตัวเลขทศนิยมแบบสุ่มถัดไปในช่วง [0.0, 1.0)
สัญกรณ์[..., ...)
หมายความว่าค่าแรกเป็นส่วนหนึ่งของค่าที่เป็นไปได้ทั้งหมด แต่ค่าที่สองไม่ใช่ random.random()
ประสงค์ที่มากที่สุดค่าการผลิตอย่างใกล้ชิด1.0
เพื่อ float
ชนิดของ Python คือค่าคะแนนลอยตัว IEEE 754 base64ซึ่งเข้ารหัสเศษส่วนไบนารีจำนวนหนึ่ง(1/2, 1/4, 1/5 ฯลฯ ) ที่ประกอบขึ้นเป็นค่าและค่าที่random.random()
ผลิตนั้นเป็นผลรวมของ การสุ่มเลือกเศษส่วน 53 รายการดังกล่าวจาก2 ** -1
(1/2) ถึง2 ** -53
(1/9007199254740992)
แต่เพราะมันสามารถผลิตค่ามากใกล้เคียงกับ1.0
ร่วมกับการปัดเศษข้อผิดพลาดที่เกิดขึ้นเมื่อคุณคูณลอย nubmers จุดคุณสามารถผลิตb
สำหรับบางค่าของและa
b
แต่0
และ1
ไม่ได้อยู่ในค่าเหล่านั้น
โปรดทราบว่าrandom.random()
สามารถผลิต 0.0 ดังนั้นa
จะรวมอยู่ในค่าที่เป็นไปได้สำหรับrandom.uniform()
( a + (b - a) * 0 == a
) เสมอ เนื่องจากมี2 ** 53
ค่าที่แตกต่างกันที่random.random()
สามารถสร้าง (การรวมที่เป็นไปได้ทั้งหมดของ 53 เศษส่วนไบนารี) มีเพียง 1 ใน2 ** 53
(ดังนั้น 1 ใน 9007199254740992) โอกาสที่เกิดขึ้น
ดังนั้นค่าได้สูงสุดที่random.random()
สามารถผลิตเป็น1 - (2 ** -53)
; เพียงเลือกค่าเล็ก ๆ ที่เพียงพอb - a
เพื่อให้สามารถปัดเศษเพื่อเตะเมื่อคูณด้วยrandom.random()
ค่าที่สูงกว่า ที่มีขนาดเล็กb - a
มีมากขึ้นโอกาสที่จะเกิดขึ้นว่า:
>>> import random, sys
>>> def find_b():
... a, b = 0, sys.float_info.epsilon
... while random.uniform(a, b) != b:
... b /= 2
... else:
... return b
...
>>> print("uniform(0, {0}) == {0}".format(find_b()))
...
uniform(0, 4e-323) == 4e-323
หากคุณเข้าชมb = 0.0
เราได้แบ่ง 1,023 ครั้งค่าข้างต้นหมายความว่าเราโชคดีหลังจากหน่วยงาน 1,019 แห่ง ค่าสูงสุดที่ฉันพบจนถึงขณะนี้ (การเรียกใช้ฟังก์ชันข้างต้นในลูปด้วยmax()
) คือ8.095e-320
(1008 ดิวิชั่น) แต่อาจมีค่าสูงกว่า มันคือเกมแห่งโอกาส :-)
นอกจากนี้ยังสามารถเกิดขึ้นได้หากมีไม่กี่ขั้นตอนโดยสิ้นเชิงระหว่างa
และb
เช่นเมื่อa
และb
มี exponent สูงและดังนั้นอาจปรากฏเป็น appart ไกล ค่าจุดลอยตัวยังคงเป็นเพียงการประมาณและจำนวนค่าที่สามารถเข้ารหัสนั้นมี จำกัด ตัวอย่างเช่นมีเพียงเศษส่วนไบนารีที่แตกต่างกันเพียง 1 ส่วนเท่านั้นsys.float_info.max
และsys.float_info.max - (2 ** 970)
ดังนั้นจึงมีโอกาส 50-50 random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
สร้างsys.float_info.max
:
>>> a, b = sys.float_info.max - (2 ** 970), sys.float_info.max
>>> values = [random.uniform(a, b) for _ in range(10000)]
>>> values.count(sys.float_info.max) # should be roughly 5000
4997
X ~ U(0,1)
จากนั้นP(X=x)
เป็นเกือบ 0 แน่นอนสำหรับค่าทั้งหมดของ x (นี่เป็นเพราะมีค่าที่เป็นไปได้มากมายในช่วงเวลา) หากคุณกำลังมองหา 0 หรือ 1 คุณควรใช้ฟังก์ชั่นที่แตกต่างกันตัวอย่างเช่นrandom.choice