python — Вычисление цифры после точки

Вопрос задан

Изменён 5 лет 4 месяца назад

Просмотрен 5k раз

Какие есть варианты реализации вычисления цифры числа после .?

Например, для ввода 1.89 результат 8.

  • python
  • python-3.x

4

Примерно так: http://ideone.com/SMFYJc

x = 1.89
print(int(x % 1 * 10))

Только не забываем про погрешность. Возможно, стоит что-нибудь (в зависимости от диапазона чисел) добавить, чтобы получать правильные результаты.

Если числа могут быть отрицательными, следует использовать abs: http://ideone.

com/Zuzvb2

x = -1.89
print(int(abs(x) % 1 * 10))

4

Вместо велосипедов или волшебства (даже если они с первого взгляда кажутся вполне рабочими) есть стандартная для многих языков функция modf, которая разделяет число на целую и дробную части.

import math
print(math.modf(3.1415))
print(math.modf(-3.0009))
print(math.modf(7))
>>> (0.14150000000000018, 3.0)
>>> (-0.0009000000000001229, -3.0)
>>> (0.0, 7.0)

Что в дальнейшем делать с дробной частью, зависит уже от конкретной задачи. Если нужно округлить до 1 значимой цифры — round. Если получить только первую цифру —

int(f * 10)print(int(0.14150000000000018 * 10))

Независимо от выбранного метода получения дробной части, вас на этом пути может подстеречь ошибка округления, из-за которой вы можете получить не совсем ожидаемые результаты:

numb = 3. 3
frac, integral = math.modf(numb)
print(frac)
print(frac * 10)
>>> 0.2999999999999998
>>> 2.9999999999999982

Одним из способов избавления от этого может стать модуль decimal:

from decimal import Decimal
numb = 3.3
decim = Decimal(str(numb))
print(decim - decim.to_integral_exact())
>>> 0.3

Еще можно округлить до нужной цифры:

numb = 3.3
frac, integral = math.modf(numb)
print(round(frac, 1))
>>> 0.3

1

Насколько я понял вопрос:

num = 1.89
mant = str(float(num))
mant = int(mant[mant.find('.')+1:])
print(mant) #print 89

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

python — Целочисленное деление отрицательных целых чисел

Вопрос задан

Изменён 2 года 2 месяца назад

Просмотрен 12k раз

Вопрос возник при решении задачи о палиндроме. Вот решение

def palindrom(param):
    #  convert to str
    word = str(param)
    #   in cycle char by char comparing from start and from end to middle of the word
    return True if word[:len(word)//2] == word[:-len(word)//2-1:-1] else False
if palindrom(input("give me a word: ")):
    print("Палиндром")
else:
    print("Та ну не")

которое работает для слов четной длины, и не работает для слов с нечтным количеством символов.
Оказалось, что 7//2==3, а -7//2==-4
то есть задачу то я решил:

return  word[:len(word)//2] == word[:-(len(word)//2)-1:-1] 

но почему так реализовано целочисленное деление? Хотелось бы -7//2 ==-3.
Какой тут глубинный смысл? А то ведь

7//2  + (- 7//2)  == -1 
7//2 - 7//2  ==  0

P.S.: признателен gil9red за подсказки и краткое решение задачи о палиндроме в примечаниях ниже.

P.P.S.: что интересно, операции побитового двоичного сдвига тоже соблюдают данное правило:

 7>>1 == 3
-7>>1 == -4
  • python

4

Дело в том, как определяется целочисленное деление.

Определение

Разделить целое число a на целое число b!=0 с остатком — это значит

найти такие два целых q и r, которые удовлетворяют следующим условиям:

1) a = b * q + r;

2) 0 <= r < |b|.

Тогда из определения будет:

-7 // 2 = -4

Объяснение:

  1. При делении отрицательного числа на положительное, получится отрицательное число
  2. Можно предположить, что правильный ответ -3, но в этом случае умножив -3 * 2 мы получим -6. Чтобы получить исходное -7 нужно к результату прибавить число -1, но остаток не может быть отрицательным по определению(r>=0). По этому в данном случае остаток равен 1 и частное равно -4.

3

Вот что у меня получилось. Как оказалось законы математики и формула в Python по вычислению остатка разные. Общая формула a%b=r (a=b*q+r), где q неполное частное, r остаток. Для математики, в которой по правилам остаток не может быть отрицательным:

-19%5=1 (-19=5*(-4)+1)
19%-5=4 (-21=5*(-5)+4)
-19%-5=1 (-19=(-5)*4+1)
-5%19=14 (-5=19*(-1)+14)
5%-19=5 (5=(-19)*0+5)
-5%-19=14 (-5=(-19)*1+14)

Для Python, где остаток может быть отрицательным:

-19%5=1 (-19=5*(-4)+1) сходится
19%-5=-1 (19=(-5)*(-4)-1) не сходится
-19%-5=-4  (-19=(-5)*3-4) не сходится
-5%19=14  (-5=19*(-1)+14) сходится
5%-19=-14  (5=(-19)*(-1)-14) не сходится
-5%-19=-5  (-5=(-19)*0-5) не сходится

Итого: неполное частное «q» округляется в меньшую целую сторону, так же как и с делением нацело. Т.е. если у вас одно число помещается в другом -3,XX раза, берется -4, если 3,XX раза, берется 3, если 0,xx раз, берется 0. Моя логика так нарисовала)

2

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

python — Разбиение числа на целую и десятичную части

Я придумал два оператора, которые могут делить положительные и отрицательные числа на целые и дробные без ущерба для точности (битовое переполнение) и скорости.

В качестве примера, положительное или отрицательное значение значения 100.1323 будет разделено на:
100,1323 -> ( 100 , 0,1323 )
-100,1323 -> ( -1006,
-100, -0,1323 )

Код

 # Разделить число (x) на целое и дробное
i = int(x) # Получить целое число
f = (x*1e17 - i*1e17) / 1e17 # Получить дробь
 

Speedtest

Тест производительности показывает, что два оператора работают быстрее, чем math.modf , если они не помещены в свои собственные функции или методы.

test.py :

 #!/usr/bin/env python
импортировать математику
импорт cProfile
""" Получить производительность обоих операторов и math.modf """
X = -100.1323 # Число, которое нужно разделить на целое и дробное
ПЕТЛИ = диапазон(5 * 10 ** 6) # Количество петель
определение сценария_a():
    """ Получить исполнение операторов """
    для _ в петлях:
        я = int(X) # -100
        f = (X*1e17-i*1e17)/1e17 # -0,1323
определение сценария_b():
    """ Проверяет скорость операторов, когда целое число должно быть с плавающей запятой. 
        ПРИМЕЧАНИЕ. Единственная разница между этим и math.modf заключается в точности """
    для _ в петлях:
        я = int(X) # -100
        i, f = float(i), (X*1e17-i*1e17)/1e17 # (-100,0, -0,1323)
определение сценария_c():
    """ Проверяет скорость операторов в функции """
    деф модф(х):
        я = интервал (х)
        вернуть i, (x*1e17-i*1e17)/1e17
    для _ в петлях:
        i, f = modf(X) # (-100, -0,1323)
определение сценария_d():
    """ Проверяет скорость math.modf """
    для _ в петлях:
        f, i = math.modf(X) # (-0,13230000000000075, -100,0)
определение сценария_e():
    """ Проверяет скорость math.modf, когда целая часть должна быть целочисленной """
    для _ в петлях:
        f, i = math.modf(X) # (-0,13230000000000075, -100,0)
        я = интервал (я) # -100
если __name__ == '__main__':
    cProfile.run('scenario_a()')
    cProfile.run('scenario_b()')
    cProfile.run('scenario_c()')
    cProfile.run('scenario_d()')
    cProfile.run('scenario_e()')
 

Результат:

 4 вызова функции за 1,357 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 1,357 1,357 <строка>:1(<модуль>)
        1 1,357 1,357 1,357 1,357 test. py:11(scenario_a)
        1 0,000 0,000 1,357 1,357 {встроенный метод builtins.exec}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
         4 вызова функций за 1,858 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 1,858 1,858 <строка>:1(<модуль>)
        1 1,858 1,858 1,858 1,858 test.py:18(scenario_b)
        1 0,000 0,000 1,858 1,858 {встроенный метод builtins.exec}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
         5000004 вызовов функций за 2,744 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 2,744 2,744 <строка>:1(<модуль>)
        1 1,245 1,245 2,744 2,744 test.py:26(scenario_c)
  5000000 1,499 0,000 1,499 0,000 тест.py:29(modf)
        1 0,000 0,000 2,744 2,744 {встроенный метод builtins.exec}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof. Profiler'}
         5000004 вызовов функций за 1,904 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 1,904 1,904 <строка>:1(<модуль>)
        1 1,073 1,073 1,904 1,904 test.py:37(scenario_d)
        1 0,000 0,000 1,904 1.904 {встроенный метод builtins.exec}
  5000000 0,831 0,000 0,831 0,000 {встроенный метод math.modf}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
         5000004 вызовов функций за 2,547 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 2,547 2,547 <строка>:1(<модуль>)
        1 1,696 1,696 2,547 2,547 test.py:43(scenario_e)
        1 0,000 0,000 2,547 2,547 {встроенный метод builtins.exec}
  5000000 0,851 0,000 0,851 0,000 {встроенный метод math.modf}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
 

Использовать расширение C/C++

Я попытался скомпилировать два оператора с поддержкой C/C++, и результат был даже лучше. С помощью модуля расширения Python можно было получить метод, который был быстрее и точнее, чем math.modf .

math3.pyx :

 def modf(номер):
    cdef float num = <число с плавающей точкой>
    cdef int i =  число
    вернуть i, (число*1e17 - i*1e17) / 1e17
 

См. Основы Cython

test.py :

 #!/usr/bin/env python
импортировать математику
импорт cProfile
импортировать math3
""" Получить производительность обоих операторов и math.modf """
X = -100.1323 # Число, которое нужно разделить на целые числа и дроби
ПЕТЛИ = диапазон(5 * 10 ** 6) # Количество петель
определение сценария_a():
    """ Проверяет скорость операторов в функции, использующей поддержку C/C++ """
    для _ в петлях:
        i, f = math3.modf(X) # (-100, -0,1323)
определение сценария_b():
    """ Проверяет скорость math.modf """
    для _ в петлях:
        f, i = math.modf(X) # (-0,13230000000000075, -100,0)
если __name__ == '__main__':
    cProfile. run('scenario_a()')
    cProfile.run('scenario_b()')
 

Результат:

 5000004 вызовов функций за 1,629 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 1,629 1,629 <строка>:1(<модуль>)
        1 1.100 1.100 1.629 1.629 test.py:10(scenario_a)
        1 0,000 0,000 1,629 1,629 {встроенный метод builtins.exec}
  5000000 0,529 0,000 0,529 0,000 {math3.modf}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
         5000004 вызовов функций за 1,802 секунды
   Упорядочено: стандартное имя
   ncalls tottime percall cumtime percall имя файла:lineno(функция)
        1 0,000 0,000 1,802 1,802 <строка>:1(<модуль>)
        1 1,010 1,010 1,802 1,802 test.py:16(scenario_b)
        1 0,000 0,000 1,802 1,802 {встроенный метод builtins.exec}
  5000000 0,791 0,000 0,791 0,000 {встроенный метод math.modf}
        1 0.000 0.000 0.000 0.000 {метод 'отключить' объектов '_lsprof.Profiler'}
 

ПРИМЕЧАНИЕ

Операторы могут выполняться быстрее по модулю, но модуль нельзя использовать для разделения отрицательных чисел на целые и дробные части.

 i, f = int(x), x*1e17%1e17/1e17 # Деление числа (x) на целое и дробное
 

Например, положительное или отрицательное значение значения 100.1323 будет разделен по адресу:
100.1323 -> ( 100 , 0,1323 )
-100,1323 -> ( -100 , 0,867777 9000.
, 0,86777777 9000.
, 0,86777777 9000. , 0,8677777 9000., 0,8677777 9000.1009. Как получить числа после запятой?

171

Новинка! Сохраняйте вопросы или ответы и организуйте свой любимый контент.
Узнать больше.

Как получить числа после запятой?

Например, если у меня 5.55 , как мне получить .55 ?

  • Python
  • с плавающей запятой
  • десятичный

3

 5,55 % 1
 

Имейте в виду, что это не поможет вам решить проблемы с округлением чисел с плавающей запятой. То есть вы можете получить:

 0,550000000001
 

Или немного отличается от ожидаемого 0,55.

9

Использовать мод:

 >>> импортировать математику
>>> дробь, целое = math.modf(2.5)
>>> гидроразрыв
0,5
>>> целиком
2.0
 

4

Как насчет:

 а = 1,3927278749291
б = а - интервал (а)
б
>> 0,39272787492910011
 

Или, используя numpy:

 import numpy
а = 1,3927278749291
б = а - numpy.fix (а)
 

0

Использование десятичного числа из стандартной библиотеки, вы можете сохранить исходную точность и избежать проблем с округлением с плавающей запятой:

 >>> from decimal import Decimal
>>> Десятичный('4.20') % 1
Десятичный ('0,20')
 

Как отмечает в комментариях, сначала вам придется преобразовать собственные float в строки.

5

Простой подход для вас:

 number_dec = str(number-int(number))[1:]
 

14

Попробуйте по модулю:

 5,55%1 = 0,54999999999999982
 

Чтобы он работал как с положительными, так и с отрицательными числами: попробуйте абс(х)%1 . Для отрицательных чисел без abs все пойдет не так.

5,55 % 1

выход 0,5499999999999998

-5,55 % 1

выход 0,45000000020000 импорт исходное значение = 5,55 целое = math.floor(orig) # целое = 5.0 frac = orig — целое # frac = 0,55

1

аналогично принятому ответу, еще более простой подход с использованием строк будет

 def number_after_decimal (number1):
    число = ул (число1)
    если 'e-' в числе: # научное обозначение
        number_dec = format(float(число), '. %df'%(len(number.split(".")[1].split("e-")[0])+int(number.split('e -')[1])))
    Элиф "." in number: # быстрая проверка десятичного числа
        number_dec = число.split(".")[1]
    вернуть number_dec
 

3

 >>> n=5,55
>>> если "." в строке (п):
... напечатать "."+str(n).split(".")[-1]
...
0,55
 

1

Просто используя простой оператор деление ‘/’ и деление пола ‘//’ , вы можете легко получить дробную часть любого заданного числа с плавающей запятой.

 число = 5,55
результат = (число/1) - (число//1)
печать (результат)
 

Иногда нули в конце имеют значение

 В [4]: ​​def split_float(x):
   ...: '''разбить число с плавающей запятой на части до и после десятичной дроби'''
   ...: до, после = str(x).split('.')
   ...: вернуть int(before), (int(after)*10 if len(after)==1 else int(after))
   . ..:
   ...:
В [5]: split_float(105.10)
Аут[5]: (105, 10)
В [6]: split_float(105.01)
Аут[6]: (105, 1)
В [7]: split_float(105.12)
Аут[7]: (105, 12)
 

1

Другой пример использования modf

 из модуля математического импорта
число = 1,0124584
# [0] десятичное, [1] целое
результат = modf (число)
печать (результат [0])
# вывод = 0124584
печать (результат [1])
# вывод = 1
 

Это решение, которое я пробовал:

 число = 45,7234
(целое, дробь) = (int(num), int(str(num)[(len(str(int(num)))+1):]))
 

Числа с плавающей запятой не сохраняются в десятичном формате (с основанием 10). Прочтите документацию по Python, чтобы понять, почему. Поэтому получать представление base10 из числа с плавающей запятой нецелесообразно.

Теперь есть инструменты, которые позволяют хранить числовые данные в десятичном формате. Ниже приведен пример использования библиотеки Decimal .

 из десятичного импорта *
х = десятичный ('0,341343214124443151466')
str(x)[-2:] == '66' # Верно
у = 0,341343214124443151466
str(y)[-2:] == '66' # Ложь
 

Используйте пол и вычтите результат из исходного числа:

 >> import math # дает вам пол. 
>> t = 5,55 # Дайте переменную 5,55
>> x = math.floor(t) #floor возвращает t, округленное до 5..
>> z = t - x #z = 5,55 - 5 = 0,55
 

4

Пример:

 импорт математики
х = 5,55
распечатать ((math.floor (x * 100)% 100))
 

Это даст вам два числа после запятой, 55 из этого примера. Если вам нужно одно число, вы уменьшаете на 10 приведенные выше расчеты или увеличиваете в зависимости от того, сколько чисел вы хотите после запятой.

2

 импорт математики
х = 1245342664,6
print((math.floor(x*1000)%1000) //100)
 

Это определенно сработало

1

Другим вариантом может быть использование модуля re с re.findall или re.search :

 import re.
def get_decimcal(n: с плавающей запятой) -> с плавающей запятой:
    return float (re. search (r'\.\d+', str (n)). группа (0))
def get_decimcal_2(n: с плавающей запятой) -> с плавающей запятой:
    return float (re.findall (r'\.\d+', str (n)) [0])
def get_int(n: float) -> int:
    вернуть целое (п)
печать (get_decimcal (5,55))
печать (get_decimcal_2 (5,55))
печать (get_int (5.55))
 

Выход

 0,55
0,55
5
 

Если вы хотите упростить/изменить/исследовать выражение, это объяснено на верхней правой панели regex101.com. Если вы хотите, вы также можете посмотреть по этой ссылке, как это будет соответствовать некоторым примерам входных данных.


Источник

Как избавиться от дополнительных плавающих чисел в вычитании Python?

Вы можете использовать это:

 номер = 5,55
int(str(число).split('.')[1])
 

2

Это только если вы хотите получить первое десятичное число

 print(int(float(input()) * 10) % 10)
 

Или вы можете попробовать это

 num = float(input())
b = число - число (число)
с = б * 10
печать (целое (с))
 

Использование математического модуля

необходимо проверить скорость

 с этажа импорта математики
защита get_decimal (число):
    '''возвращает номер - этаж числа'''
    вернуть номер-этаж(номер)
 

Пример:

 n = 765,126357123
get_decimal(n)
 

0,12635712300004798

1

 def дробная_часть (числитель, знаменатель):
    # Работаем с числителем и знаменателем, чтобы
# оставить только дробную часть частного
если знаменатель == 0:
      вернуть 0
  еще:
       return (числитель/знаменатель)-(числитель//знаменатель)
 
print(fractional_part(5, 5)) # Должно быть 0
print(fractional_part(5, 4)) # Должно быть 0,25
print(fractional_part(5, 3)) # Должно быть 0,66. ..
print(fractional_part(5, 2)) # Должно быть 0,5
print(fractional_part(5, 0)) # Должно быть 0
print(fractional_part(0, 5)) # Должно быть 0
 

Проще, если ввод представляет собой строку, мы можем использовать функцию split()

 decimal = input("Введите десятичное число: ") #123.456
# разделить 123,456 точкой = ['123', '456']
after_coma = decimal.split('.')[1]
# поскольку берется только индекс 1, то '456'
print(after_coma) # '456'
 

, если вы хотите сделать числовой тип print(int(after_coma)) # 456

 a = 12,587
b = float('0.' + str(a).split('.')[-1])
 

1

О чем:

 а = 1,234
б = а - интервал (а)
длина = len (стр (а))
раунд(b, длина-2)
 

Выход:
Печать (B)
0,2339999999999999
Раунд (B, длина 2)
0,234

, так как раунд отправляется на длину строки. ), мы можем просто минус 2, чтобы не считать «0.