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.
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. Если получить только первую цифру —
— 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 за подсказки и краткое решение задачи о палиндроме в примечаниях ниже.
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
Объяснение:
- При делении отрицательного числа на положительное, получится отрицательное число
- Можно предположить, что правильный ответ
-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) на целое и дробное
Например, положительное или отрицательное значение значения 171 Новинка! Сохраняйте вопросы или ответы и организуйте свой любимый контент. Как получить числа после запятой? Например, если у меня 3 Имейте в виду, что это не поможет вам решить проблемы с округлением чисел с плавающей запятой. То есть вы можете получить: Или немного отличается от ожидаемого 0,55. 9 Использовать мод: 4 Как насчет: Или, используя numpy: 0 Использование десятичного числа Как отмечает в комментариях, сначала вам придется преобразовать собственные 5 Простой подход для вас: 14 Попробуйте по модулю: Чтобы он работал как с положительными, так и с отрицательными числами:
попробуйте выход 0,5499999999999998 выход 0,45000000020000 импорт
исходное значение = 5,55
целое = math.floor(orig) # целое = 5.0
frac = orig — целое # frac = 0,55 1 аналогично принятому ответу, еще более простой подход с использованием строк будет 3 1 Просто используя простой оператор деление ‘/’ и деление пола ‘//’ , вы можете легко получить дробную часть любого заданного числа с плавающей запятой. Иногда нули в конце имеют значение 1 Другой пример использования modf Это решение, которое я пробовал: Числа с плавающей запятой не сохраняются в десятичном формате (с основанием 10). Прочтите документацию по Python, чтобы понять, почему. Поэтому получать представление base10 из числа с плавающей запятой нецелесообразно. Теперь есть инструменты, которые позволяют хранить числовые данные в десятичном формате. Ниже приведен пример использования библиотеки Используйте пол и вычтите результат из исходного числа: 4 Пример: Это даст вам два числа после запятой, 55 из этого примера. Если вам нужно одно число, вы уменьшаете на 10 приведенные выше расчеты или увеличиваете в зависимости от того, сколько чисел вы хотите после запятой. 2 Это определенно сработало 1 Другим вариантом может быть использование модуля Если вы хотите упростить/изменить/исследовать выражение, это объяснено на верхней правой панели regex101.com. Если вы хотите, вы также можете посмотреть по этой ссылке, как это будет соответствовать некоторым примерам входных данных. Как избавиться от дополнительных плавающих чисел в вычитании Python? Вы можете использовать это: 2 Это только если вы хотите получить первое десятичное число Или вы можете попробовать это необходимо проверить скорость Пример: 0,12635712300004798 1 Проще, если ввод представляет собой строку, мы можем использовать функцию split() , если вы хотите сделать числовой тип
print(int(after_coma)) # 456 1 О чем: Выход: , так как раунд отправляется на длину строки. ), мы можем просто минус 2, чтобы не считать «0. 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. Как получить числа после запятой?
Узнать больше. 5.55
, как мне получить .55
? 5,55 % 1
0,550000000001
>>> импортировать математику
>>> дробь, целое = math.modf(2.5)
>>> гидроразрыв
0,5
>>> целиком
2.0
а = 1,3927278749291
б = а - интервал (а)
б
>> 0,39272787492910011
import numpy
а = 1,3927278749291
б = а - numpy.fix (а)
из стандартной библиотеки, вы можете сохранить исходную точность и избежать проблем с округлением с плавающей запятой: >>> from decimal import Decimal
>>> Десятичный('4.20') % 1
Десятичный ('0,20')
float
в строки. number_dec = str(number-int(number))[1:]
5,55%1 = 0,54999999999999982
абс(х)%1
. Для отрицательных чисел без abs
все пойдет не так. 5,55 % 1
-5,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
>>> n=5,55
>>> если "." в строке (п):
... напечатать "."+str(n).split(".")[-1]
...
0,55
число = 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,0124584
# [0] десятичное, [1] целое
результат = modf (число)
печать (результат [0])
# вывод = 0124584
печать (результат [1])
# вывод = 1
число = 45,7234
(целое, дробь) = (int(num), int(str(num)[(len(str(int(num)))+1):]))
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
импорт математики
х = 5,55
распечатать ((math.floor (x * 100)% 100))
импорт математики
х = 1245342664,6
print((math.floor(x*1000)%1000) //100)
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
Источник
номер = 5,55
int(str(число).split('.')[1])
print(int(float(input()) * 10) % 10)
num = float(input())
b = число - число (число)
с = б * 10
печать (целое (с))
Использование математического модуля
с этажа импорта математики
защита get_decimal (число):
'''возвращает номер - этаж числа'''
вернуть номер-этаж(номер)
n = 765,126357123
get_decimal(n)
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
decimal = input("Введите десятичное число: ") #123.456
# разделить 123,456 точкой = ['123', '456']
after_coma = decimal.split('.')[1]
# поскольку берется только индекс 1, то '456'
print(after_coma) # '456'
a = 12,587
b = float('0.' + str(a).split('.')[-1])
а = 1,234
б = а - интервал (а)
длина = len (стр (а))
раунд(b, длина-2)
Печать (B)
0,2339999999999999
Раунд (B, длина 2)
0,234