1

Я хочу, чтобы мой код не принимал почти целое число для целого числа. Например, 58106601358565889 имеет в качестве корня квадратного 241,053,109.00000001659385359763188, но когда я использовал следующее логическое испытание, 58106601358565889 обмануть меня, думая, что это идеальный квадрат:Отличие больших целых чисел от близких целых чисел в python

a = 58106601358565889 
b = math.sqrt(a) 
print(b == int(b)) 

точность не обязательно проблема, потому что если я перепроверить, я получаю правильный (False) вывод:

print(a == b**2) 

что бы быть лучше, чтобы проверить истинный против почти целого? Math.sqrt похоронен в другом определении в моем коде, и я хотел бы избежать необходимости вставлять квадрат квадратного квадрата, если это возможно. Прошу прощения, если это не очень хороший вопрос; Я новичок в python.

+0

Должно ли оно возвращать 'true' то, что вы хотите? – styvane

+0

Он должен возвращать False, если мое понимание верное – Backtrack

+0

Первая печать (b == int (b)) Я хочу быть ложной. – Jeptha

ответ

0
import numpy as np 
import math 
from decimal import * 

a = 58106601358565889 
b = np.sqrt(a) 
c = math.sqrt(a) 
d = Decimal(58106601358565889).sqrt() 


print(d) 
print(int(d)) 

print(c) 
print(int(c)) 

print(b) 
print(int(b)) 

о/р

241053109.0000000165938535976 
241053109 
241053109.0 
241053109 
241053109.0 
241053109 

Я бы сказал, использование decimal.

Ожидаемый код:

from decimal import * 
d = Decimal(58106601358565889).sqrt() 
print(d == int(d)) 

о/р

False 
+0

'Десятичный' по-прежнему выполняет вычисления с ограниченной (хотя и настраиваемой) точностью. Выполнение всей вашей математики в «Десятичной» просто откладывает проблему до еще больших размеров ввода, если вы не выполните дополнительную настройку и вторичные проверки. – user2357112

+0

Спасибо, Десятичный сделал трюк. Я не знал об этом. – Jeptha

+0

Спасибо user2357112, мне нужно будет изучить пределы точности для 'Десятичный'. – Jeptha

0

Это не точность int, что проблема - это ограниченная точность поплавков

>>> import math 
>>> math.sqrt(58106601358565889) 
241053109.0 
>>> math.sqrt(58106601358565889) - 241053109 
0.0 

Я думаю, что двойная проверка будет очевидным решением

+0

Итак, может быть, нужна двойная проверка? – Jeptha

+0

@ Jeptha: двойная проверка не достаточно хороша; у него свои проблемы. Например, он не работает на 'a = 100000000000000000001 ** 2'. – user2357112

+0

@ Jeptha, любые поплавки, большие, чем это всегда будут интегральными. Возможно, вы можете просто проверить '(a == b * b)' –

1

Это не вопрос отличая целые числа от нецелых чисел, потому что b действительно является целым числом *. Точность поплавка Python недостаточно, чтобы представить квадратный корень из a достаточным количеством цифр, чтобы получить какой-либо его дробный компонент. Вторая проверка вы сделали:

print(a == b**2) 

печатает только False, потому что в то время как b является целым числом, b**2 еще не a.

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

* как в 0 дробная часть, не как в isinstance(b, int).

+0

Спасибо, что указали это; это было плохое предположение с моей стороны. – Jeptha

0

Вы также можете посмотреть на gmpy2 библиотеке. Он имеет функцию для вычисления целочисленного квадратного корня, а также целочисленного квадратного корня плюс остаток. Нет прецизионных ограничений.

>>> import gmpy2 
>>> gmpy2.isqrt(58106601358565889) 
mpz(241053109) 
>>> gmpy2.isqrt_rem(58106601358565889) 
(mpz(241053109), mpz(8)) 
>>> 

Отказ от ответственности: Я поддерживаю gmpy2.

Смежные вопросы