การแบ่งตัวเลขออกเป็นส่วนจำนวนเต็มและทศนิยม


คำตอบ:


143

ใช้math.modf:

import math
x = 1234.5678
math.modf(x) # (0.5678000000000338, 1234.0)

2
สมบูรณ์แบบ! ใช้งานได้ดีกับเนกาทีฟด้วย! ขอบคุณ
ดับเบิ้ลเอเอ

1
หลังจากใช้ math.modf (x) ฉันจะจัดการกับค่าผลลัพธ์ได้อย่างไร ตัวอย่างเช่นถ้าฉันมอบหมาย 1234.0 เป็นตัวแปรฉันจะทำได้อย่างไร?
hakiko

3
Dec, int = math.modf (1234.5678)
gbtimmon

19
อย่าใช้intเป็นชื่อตัวแปรเพราะจะลบล้างintฟังก์ชัน
Holloway

2
@Trengot - ใช้int_ถ้าคุณต้องมีตัวแปรที่เมื่ออ่านออกเสียงเรียกว่า "int"
ArtOfWarfare

62

เราสามารถใช้ฟังก์ชันในตัวที่ไม่มีชื่อเสียง Divmod:

>>> s = 1234.5678
>>> i, d = divmod(s, 1)
>>> i
1234.0
>>> d
0.5678000000000338

4
ให้ผลลัพธ์ที่เป็นไปได้สำหรับตัวเลขเชิงลบ: divmod(-4.5,1)ให้ -5.0 และ 0.5 การใช้divmod(-4.5, -1)ให้ 4.0 และ -0.5
Holloway

@ ฮอลโลว์มันไม่ได้ตั้งใจมันมาจากกฎทางคณิตศาสตร์: en.wikipedia.org/wiki/Floor_and_ceiling_functions :)
Sviatoslav V.

46
>>> a = 147.234
>>> a % 1
0.23400000000000887
>>> a // 1
147.0
>>>

ถ้าคุณต้องการให้ส่วนจำนวนเต็มเป็นจำนวนเต็มไม่ใช่จำนวนทศนิยมให้ใช้int(a//1)แทน ในการรับทูเปิลในข้อความเดียว:(int(a//1), a%1)

แก้ไข: โปรดจำไว้ว่าส่วนทศนิยมของตัวเลขทศนิยมเป็นค่าประมาณดังนั้นหากคุณต้องการแสดงเป็นมนุษย์คุณต้องใช้ไลบรารีทศนิยม


5
ทำให้เกิดความสับสนเล็กน้อยผลการค้นหาสำหรับตัวเลขที่ติดลบ, และ-2.25 // 1 == -3.0 -2.25 % 1 == 0.75นี่อาจเป็นสิ่งที่ OP ต้องการเนื่องจากส่วน int + ส่วนทศนิยมยังคงเท่ากับค่าเดิม ในทางตรงกันข้ามmath.modf(-2.25) == (-0.25, -2.0).
Andrew Clark

@ แอนดรู - จุดดี! ฉันคิดว่าคำตอบของ @mhyfritz นั้นดีกว่า แต่อย่างใด!
แม็ค

ดี - ฉันคิดว่านี่จะเป็นวิธีที่เร็วที่สุดสำหรับสิ่งที่แสดงไว้ที่นี่โดยคำนึงถึงข้อแม้ของ Andrew Clark สำหรับตัวเลขเชิงลบ
jacanterbury

14
intpart,decimalpart = int(value),value-int(value)

ใช้ได้กับจำนวนบวก


In [1]: value = 1.89 In [2]: intpart,decimalpart = int(value),value-int(value) In [3]: intpart Out [3]: 1 In [4]: decimalpart Out [4]: 0.8899999999999999
iMom0

1
@ iMom0 - ดูdocs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.htmlและคำถามมากมายในไซต์นี้เกี่ยวกับความแม่นยำของจุดลอยตัว
Mark Ransom

7

ตัวแปรนี้ช่วยให้ได้รับความแม่นยำที่ต้องการ:

>>> a = 1234.5678
>>> (lambda x, y: (int(x), int(x*y) % y/y))(a, 1e0)
(1234, 0.0)
>>> (lambda x, y: (int(x), int(x*y) % y/y))(a, 1e1)
(1234, 0.5)
>>> (lambda x, y: (int(x), int(x*y) % y/y))(a, 1e15)
(1234, 0.5678)


1

นี่คือวิธีที่ฉันทำ:

num = 123.456
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1])

4
ขึ้นอยู่กับกรณีการใช้งานสิ่งนี้อาจใช้ไม่ได้กับตัวเลขที่มีศูนย์หลังตำแหน่งทศนิยม (เช่น 123.0456)
จอน

คุณพูดถูก: ขึ้นอยู่กับกรณีการใช้งาน หากคุณลองใช้ 123.0456 ผลลัพธ์คือ int_part = 123 และ decimal_part = 456 ในกรณีการใช้งานของฉันฉันพบว่า "การลบเป็นศูนย์" มีประโยชน์ :)
holydrinker

0

หากคุณไม่สนใจที่จะใช้ NumPy ให้ทำดังนี้

In [319]: real = np.array([1234.5678])

In [327]: integ, deci = int(np.floor(real)), np.asscalar(real % 1)

In [328]: integ, deci
Out[328]: (1234, 0.5678000000000338)

0

ฉันได้มาพร้อมกับสองคำสั่งที่สามารถแบ่งจำนวนบวกและลบออกเป็นจำนวนเต็มและเศษส่วนโดยไม่ลดทอนความแม่นยำ (บิตล้น) และความเร็ว

x = 100.1323 # A number to be divided into integers and fractions

# The two statement to divided a number into integers and fractions
i = int(x) # A positive or negative integer
f = (x*1e17-i*1e17)/1e17 # A positive or negative fraction

เช่น100.1323-> 100, 0.1323หรือ-100.1323-> -100,-0.1323

ทดสอบความเร็ว

การทดสอบประสิทธิภาพแสดงให้เห็นว่าทั้งสองคำสั่งเร็วกว่า math.modfตราบใดที่ไม่ได้ใส่ไว้ในฟังก์ชันหรือวิธีการของตนเอง

test.py:

#!/usr/bin/env python
import math
import cProfile

""" Get the performance of both statements and math.modf. """

X = -100.1323 # The number to be divided into integers and fractions
LOOPS = range(5*10**6) # Number of loops

def scenario_a():
    """ The integers (i) and the fractions (f)
        come out as integer and float. """
    for _ in LOOPS:
        i = int(X) # -100
        f = (X*1e17-i*1e17)/1e17 # -0.1323

def scenario_b():
    """ The integers (i) and the fractions (f)
        come out as float.
        NOTE: The only difference between this
              and math.modf is the accuracy. """
    for _ in LOOPS:
        i = int(X) # -100
        i, f = float(i), (X*1e17-i*1e17)/1e17 # (-100.0, -0.1323)

def scenario_c():
    """ Performance test of the statements in a function. """
    def modf(x):
        i = int(x)
        return i, (x*1e17-i*1e17)/1e17

    for _ in LOOPS:
        i, f = modf(X) # (-100, -0.1323)

def scenario_d():
    for _ in LOOPS:
        f, i = math.modf(X) # (-100.0, -0.13230000000000075)

def scenario_e():
    """ Convert the integer part to real integer. """
    for _ in LOOPS:
        f, i = math.modf(X) # (-100.0, -0.13230000000000075)
        i = int(i) # -100

if __name__ == '__main__':
    cProfile.run('scenario_a()')
    cProfile.run('scenario_b()')
    cProfile.run('scenario_c()')
    cProfile.run('scenario_d()')
    cProfile.run('scenario_e()')

เอาท์พุต:

         4 function calls in 1.312 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.312    1.312 <string>:1(<module>)
        1    1.312    1.312    1.312    1.312 test.py:10(scenario_a)
        1    0.000    0.000    1.312    1.312 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         4 function calls in 1.887 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.887    1.887 <string>:1(<module>)
        1    1.887    1.887    1.887    1.887 test.py:18(scenario_b)
        1    0.000    0.000    1.887    1.887 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 2.797 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.797    2.797 <string>:1(<module>)
        1    1.261    1.261    2.797    2.797 test.py:27(scenario_c)
  5000000    1.536    0.000    1.536    0.000 test.py:31(modf)
        1    0.000    0.000    2.797    2.797 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 1.852 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.852    1.852 <string>:1(<module>)
        1    1.050    1.050    1.852    1.852 test.py:38(scenario_d)
        1    0.000    0.000    1.852    1.852 {built-in method builtins.exec}
  5000000    0.802    0.000    0.802    0.000 {built-in method math.modf}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 2.467 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.467    2.467 <string>:1(<module>)
        1    1.652    1.652    2.467    2.467 test.py:42(scenario_e)
        1    0.000    0.000    2.467    2.467 {built-in method builtins.exec}
  5000000    0.815    0.000    0.815    0.000 {built-in method math.modf}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

บันทึก:

คำสั่งสามารถทำได้เร็วขึ้นด้วยโมดูโล แต่ไม่สามารถใช้โมดูโลเพื่อแบ่งตัวเลขเชิงลบออกเป็นส่วนจำนวนเต็มและเศษส่วนได้

i, f = int(x), x*1e17%1e17/1e17 # x can not be negative
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.