Jak uzyskać liczby po przecinku?

Odpowiedzi:

28

Łatwe podejście dla Ciebie:

number_dec = str(number-int(number))[1:]
lllluuukke
źródło
31
Ćwiczenie dla czytelnika: spraw, by działało dla liczb większych lub równych 10
intuicyjnie
11
number_dec = str(number-int(number)).split('.')[1]
Ryan Allen
28
Głosuj przeciw, ponieważ jest to niepotrzebnie skomplikowane podejście. Odpowiedź, której szukałem, była następną odpowiedzią, 5.55 % 1która jest również bardziej użyteczną odpowiedzią - można zastosować podejście dzielenia modulo w wielu językach, podczas gdy powyższa odpowiedź jest specyficzna dla Pythona.
Gulasz
3
UWAGA: To rozwiązanie zwraca ciąg znaków zawierający kropkę ( .55), czego możesz się nie spodziewać ze względu na tytuł pytania!
T. Christiansen
9
str(5.55 - int(5.55))[1:]zwraca .5499999999999998zamiast .55wymienionego w pytaniu.
Cristian Ciupitu
201
5.55 % 1

Pamiętaj, że nie pomoże ci to w problemach z zaokrąglaniem zmiennoprzecinkowym. To znaczy, możesz otrzymać:

0.550000000001

Lub w przeciwnym razie trochę poniżej 0,55, którego oczekujesz.

jer
źródło
7
Co do tego modf, może też wkręcić precyzję: math.modf(5.55)zwróci (0.5499999999999998, 5.0).
bereal
1
czy ktoś wie, która operacja byłaby szybsza, ta metoda opisana powyżej, czy: float b = a - int (a)? Podejrzewam później, ale chciałem sprawdzić, czy jest potwierdzenie
hokkuk
5
Na Raspberry Pi ta metoda x%1była prawie dwukrotnie szybsza niż metody x-int(x)i modf(x)[0](czasy 980ns, 1,39us i 1,47us uśrednione dla 1000000 uruchomień). Moja wartość xzawsze była pozytywna, więc nie musiałem się o to martwić.
coderforlife
Zdecydowanie praca modułu jest szybsza. Nie musi wyszukiwać nazw. Natomiast wywołanie funkcji int wyszukuje zmienne globalne.
Enrico Borba
mieć ochotę nie tylko na frac ()
mckenzm
155

Użyj modf :

>>> import math
>>> frac, whole = math.modf(2.5)
>>> frac
0.5
>>> whole
2.0
Anthony V
źródło
2
Dobre rozwiązanie, ale math.modf(2.53) = (0.5299999999999998, 2.0)oczekiwana odpowiedź to 0,53
Lord Loh.
4
@LordLoh. dzieje się tak z powodu zaokrąglania zmiennoprzecinkowego i będzie miało miejsce w przypadku każdej metody.
Rena
@LordLoh. Spróbuj użyć round (0.5299999999999998, 2), aby uzyskać 0.53 Innym sposobem jest użycie pakietu dziesiętnego z dziesiętnego. docs.python.org/2/library/decimal.html
SirJ
57

Co powiesz na:

a = 1.3927278749291
b = a - int(a)

b
>> 0.39272787492910011

Lub używając numpy:

import numpy
a = 1.3927278749291
b = a - numpy.fix(a)
Jim Brissom
źródło
33

Używając decimalmodułu z biblioteki standardowej, możesz zachować oryginalną precyzję i uniknąć problemów z zaokrąglaniem zmiennoprzecinkowym:

>>> from decimal import Decimal
>>> Decimal('4.20') % 1
Decimal('0.20')

Jak zauważa kindall w komentarzach, musisz najpierw przekonwertować natywne s na ciągi znaków.float

intuicyjnie
źródło
Z korzyścią dla oryginalnego pytającego: zmiennoprzecinkowe muszą zostać przekonwertowane na łańcuchy, zanim będzie można je przekonwertować na liczby dziesiętne. Więc jeśli masz n = 5.55, n jest liczbą zmiennoprzecinkową i powinieneś zrobić, Decimal(str(n)) % 1aby uzyskać część ułamkową. (Nie jest to konieczne, jeśli masz liczbę całkowitą, ale to nie boli.)
kindall
2
@intuited: Nie musi to być dziesiętne, działa również dla float: 10.0/3 % 1przynajmniej w moim systemie
aherok
2
Możesz użyć from_float zamiast używać łańcucha. d = Decimal.from_float (1.2)
Matthew Purdon
@intuited Jak uzyskać część dziesiętną jako liczbę całkowitą? Próbowałem metod to_integer (), ale typ jest nadal Decimal.
D1X
1
@MatthewPurdon - Jeśli użyjesz Decimal.from_float(1.2)(które można teraz zapisać jako Decimal(1.2)), będziesz mieć zaokrąglone problemy, których próbowała uniknąć ta odpowiedź.
John Y
7

Wypróbuj Modulo:

5.55%1 = 0.54999999999999982
Juri Robl
źródło
5

podobnie jak przyjęta odpowiedź, jeszcze prostszym podejściem byłoby użycie łańcuchów

def number_after_decimal(number1):
    number = str(number1)
    if 'e-' in number: # scientific notation
        number_dec = format(float(number), '.%df'%(len(number.split(".")[1].split("e-")[0])+int(number.split('e-')[1])))
    elif "." in number: # quick check if it is decimal
        number_dec = number.split(".")[1]
    return number_dec
yosemite_k
źródło
number = 5.55; "." in numberdaje TypeError: argument of type 'float' is not iterable. A co byś zrobił, gdybyś number = 1e-5?
Mark Dickinson
@mark pytanie brzmi: Jak uzyskać liczby po przecinku? więc użytkownik oczekuje liczby zmiennoprzecinkowej w notacji dziesiętnej (nie naukowej), dodałem też blok dla notacji naukowej
yosemite_k
Liczba to liczba; jest to tylko reprezentacja liczby, która może być zapisana w notacji naukowej. Więc „float w notacji dziesiętnej” nie ma tu większego sensu; zanim Python to zobaczy, jest to tylko float; Python nie posiada żadnej wiedzy o tym, w jakim formacie został pierwotnie wyrażony. Mój number = 1e-5przykład odnosi się równie dobrze do number = 0.00001: strreprezentacja liczby jest w notacji naukowej. Będziesz mieć do czynienia z e+, jak i e-, nawiasem mówiąc.
Mark Dickinson
4
import math
orig = 5.55
whole = math.floor(orig)    # whole = 5.0
frac = orig - whole         # frac = 0.55
Kevin Lacquement
źródło
>>> frac 0.5499999999999998
macm
4
>>> n=5.55
>>> if "." in str(n):
...     print "."+str(n).split(".")[-1]
...
.55
ghostdog74
źródło
2
Jest to w porządku w przypadku liczb z odmian ogrodowych, ale nie działa tak dobrze w przypadku liczb wystarczająco dużych (lub małych), aby wymagać notacji naukowej.
kindall
2

Oto rozwiązanie, które wypróbowałem:

num = 45.7234
(whole, frac) = (int(num), int(str(num)[(len(str(int(num)))+1):]))
kurian
źródło
2

Czasami liczą się zera końcowe

In [4]: def split_float(x):
   ...:     '''split float into parts before and after the decimal'''
   ...:     before, after = str(x).split('.')
   ...:     return int(before), (int(after)*10 if len(after)==1 else int(after))
   ...: 
   ...: 

In [5]: split_float(105.10)
Out[5]: (105, 10)

In [6]: split_float(105.01)
Out[6]: (105, 1)

In [7]: split_float(105.12)
Out[7]: (105, 12)
George Fisher
źródło
co to robi dla 0,000005?
Aditya Patnaik
2

Używając prostego dzielenia przez operatora „/” i podziału „//” , można łatwo uzyskać część ułamkową dowolnej liczby zmiennoprzecinkowej.

number = 5.55

result = (number/1) - (number//1)

print(result)
Sony
źródło
1

Użyj podłogi i odejmij wynik od oryginalnej liczby:

>> import math #gives you floor.
>> t = 5.55 #Give a variable 5.55
>> x = math.floor(t) #floor returns t rounded down to 5..
>> z = t - x #z = 5.55 - 5 = 0.55

źródło
5
Jeśli masz zamiar import math, dlaczego po prostu nie użyć math.modf()?
ire_and_curses,
@ire_and_curses: Podaję alternatywne rozwiązanie problemu.
1
floor robi to samo, co rzutowanie na int, więc może zastąpić math.floor (t) int (t)
QuantumKarl
@QuantumKarl Nie, są różne. math.floor(-1.1) == -2ale int(-1.1) == -1. Chociaż w przypadku tego pytania użycie intjest bardziej poprawne.
Lambda Fairy
1

Liczby zmiennoprzecinkowe nie są przechowywane w formacie dziesiętnym (podstawa 10). Przeczytaj dokumentację Pythona na ten temat, aby upewnić się, dlaczego. Dlatego uzyskanie reprezentacji o podstawie 10 z liczby zmiennoprzecinkowej nie jest zalecane.

Teraz są narzędzia, które umożliwiają przechowywanie danych liczbowych w formacie dziesiętnym. Poniżej przykład z wykorzystaniem Decimalbiblioteki.

from decimal import *

x = Decimal('0.341343214124443151466')
str(x)[-2:] == '66'  # True

y = 0.341343214124443151466
str(y)[-2:] == '66'  # False
jpp
źródło
1

Przykład:

import math
x = 5.55
print((math.floor(x*100)%100))

To da ci dwie liczby po przecinku, 55 z tego przykładu. Jeśli potrzebujesz jednej liczby, zmniejsz o 10 powyższe obliczenia lub zwiększ w zależności od tego, ile liczb chcesz po przecinku.

Szczery
źródło
Jest to miłe, ponieważ zwraca wartość nieułamkową, ale przerywa na liczbach ujemnych
Meow
Niestety przez większość czasu nie działa. @Meow
Markiz Lorne,
1
import math

x = 1245342664.6
print( (math.floor(x*1000)%1000) //100 )

To zdecydowanie zadziałało

Ali
źródło
co oznacza operator //?
l --''''''--------- '' '' '' '' '' ''
0

Co powiesz na:

a = 1.234
b = a - int(a)
length = len(str(a))

round(b, length-2)

Wynik:
print(b)
0.23399999999999999
round(b, length-2)
0.234

Ponieważ runda jest wysyłana do długości ciągu liczb dziesiętnych („0,234”), możemy odjąć 2, aby nie policzyć „0” i obliczyć żądaną liczbę miejsc dziesiętnych. Powinno to działać w większości przypadków, chyba że masz dużo miejsc po przecinku, a błąd zaokrąglania podczas obliczania b koliduje z drugim parametrem rundy.

MH
źródło
Jakieś wyjaśnienie?
0

Możesz spróbować tego:

your_num = 5.55
n = len(str(int(your_num)))
float('0' + str(your_num)[n:])

Wróci 0.55.

Ashkan Mirzaee
źródło
0
number=5.55
decimal=(number-int(number))
decimal_1=round(decimal,2)
print(decimal)
print(decimal_1)

wyjście: 0,55

Sanchit Aluna
źródło
0

Zobacz, co często robię, aby uzyskać liczby po przecinku w Pythonie 3:

a=1.22
dec=str(a).split('.')
dec= int(dec[1])
Suraj Rao
źródło
0

Jeśli używasz pand:

df['decimals'] = df['original_number'].mod(1)
erickfis
źródło
0

Inną opcją byłoby użycie remodułu z re.findalllub re.search:

import re


def get_decimcal(n: float) -> float:
    return float(re.search(r'\.\d+', str(n)).group(0))


def get_decimcal_2(n: float) -> float:
    return float(re.findall(r'\.\d+', str(n))[0])


def get_int(n: float) -> int:
    return int(n)


print(get_decimcal(5.55))
print(get_decimcal_2(5.55))
print(get_int(5.55))

Wynik

0.55
0.55
5

Jeśli chcesz uprościć / zmodyfikować / zbadać wyrażenie, zostało to wyjaśnione w prawym górnym panelu regex101.com . Jeśli chcesz, możesz również obejrzeć w tym linku , jak to będzie się zgadzać z niektórymi przykładowymi danymi wejściowymi.


Źródło

Jak pozbyć się dodatkowych liczb zmiennoprzecinkowych w odejmowaniu w Pythonie?

Emma
źródło
0

Odkryłem, że naprawdę duże liczby z naprawdę dużymi częściami ułamkowymi mogą powodować problemy podczas używania modulo 1 do uzyskania ułamka.

import decimal

>>> d = decimal.Context(decimal.MAX_PREC).create_decimal(
... '143000000000000000000000000000000000000000000000000000000000000000000000000000.1231200000000000000002013210000000'
... )
...
>>> d % 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>]

Zamiast tego złapałem integralną część i odjąłem ją najpierw, aby uprościć resztę.

>>> d - d.to_integral()
Decimal('0.1231200000000000000002013210')
Droogans
źródło
0

Kolejny przykład użycia modf

from math import modf
number = 1.0124584

# [0] decimal, [1] integer
result = modf(number)
print(result[0])
# output = 0124584
print(result[1])
# output = 1
camilom108
źródło
0

Rozwiązaniem jest użycie modulo i zaokrąglanie.

import math

num = math.fabs(float(5.55))
rem = num % 1

rnd_by =   len(str(num)) - len(str(int(num))) - 1

print(str(round(rem,rnd_by)))

Twój wynik wyniesie 0,55

Gideon Antwi
źródło
0

Możesz użyć tego:

number = 5.55
int(str(number).split('.')[1])
Mario Monroy
źródło
-2

Kolejnym szalonym rozwiązaniem jest (bez konwersji w string):

number = 123.456
temp = 1

while (number*temp)%10 != 0:
    temp = temp *10
    print temp
    print number

temp = temp /10
number = number*temp
number_final = number%temp
print number_final
Romulus
źródło