#c #c #floating-point #type-conversion
#c #c #число с плавающей запятой #преобразование типов
Вопрос:
У меня есть очень большое число с плавающей запятой (около 20 цифр), и я хочу проверить, является ли оно целым числом или нет. Например, если у меня есть число, подобное 154.0, то это целое число, в то время как 154.123123 не является целым числом.
Мне нужно проверить наличие очень больших чисел с плавающей запятой (20 цифр или более), что означает, что я не могу сначала преобразовать его в длинный тип данных long и посмотреть, совпадают ли они оба. Пожалуйста, подтолкните меня в правильном направлении. Я был бы признателен за ответы только на C / C . Спасибо! 🙂
Ответ №1:
Ну, что такое «огромное»? Если число действительно огромное в том смысле, что количество цифр больше числа, представимого мантиссой вашего числа с плавающей запятой, то ваше число с плавающей запятой всегда является целым числом.
Например, формат двойной точности IEEE 754 имеет 52-битную мантиссу, которой достаточно примерно для 16 десятичных разрядов. Если ваши числа состоят из 20 десятичных разрядов, то любая попытка втиснуть такие числа в double
приведет к округлению, эффективно превращая ваши числа в «целые числа».
Вы упоминаете, что ваши числа слишком велики, чтобы вписаться в long long
тип данных. Если вы имеете в виду 64-разрядный long long
тип данных, то это автоматически означает, что ваши числа настолько велики, что в них никогда не будет дробной части, когда они представлены типичным double
типом, т. Е. они всегда будут «целыми числами», если представлены double
значениями.
P.S. Вы используете какой-то экзотический тип с плавающей запятой с очень широкой мантиссой?
Комментарии:
1. @AndreyT : Это очень интересно. И это тоже кажется вполне очевидным. Спасибо, что указали на это. 🙂 И означает ли это, что нет способа сохранить число с плавающей запятой с мантиссой, содержащей более 15 цифр? Я бы предпочел не использовать строки, поскольку это усложнило бы арифметические операции. Есть ли КАКОЙ -нибудь способ выполнить то, что мне нужно сделать?
2. @Anubhav: Зачем вам это нужно? Какому приложению требуется точность более 20 цифр?
3. @Oli — Мне нужно проверить очень большое число (хранящееся в double), является ли оно квадратом или нет. Что я делаю, так это вычисляю его квадратный корень и проверяю, является ли это целым числом. Сам квадратный корень очень огромен. Есть ли какое-либо решение этой проблемы?
4. @Anubhav: Проблема здесь в том, что ваше «очень огромное число», возможно, уже было округлено до того, как вы попытаетесь извлечь из него квадратный корень. В общем, вам, вероятно, лучше найти себе библиотеку с большим целым числом для выполнения подобных задач.
5. Да, я думаю, что так! Я должен изучить библиотеку GMP сейчас! К вашему сведению, это была проблема проекта Euler 94, которую я пытался решить ! 🙂
Ответ №2:
Просто проверьте, является ли x == floor(x)
?
Комментарии:
1. @Nawaz: Это работает. Все числа, которые вы тестировали, являются целыми числами по причинам, которые я описал в своем ответе.
2. @Nawaz: Откуда вы знаете, что ваше первое значение может быть выражено именно как
long double
?3. @Nawaz: Тем не менее, то, что вы передаете, является «целым числом». Добавьте print out
d
в своюis_integer
функцию, чтобы увидеть, что вы действительно передаете. Взгляните: ideone.com/vC1OG4. @AndreyT: Да…. Я это сделал. Он печатает что-то другое … которое больше не является плавающим.. Спасибо..
5. @Nawaz: Не плавающее? Совсем наоборот, оно по сути плавающее. С вашими числами произошло именно то, что происходит с числами с плавающей запятой: поскольку ширина мантиссы ограничена, число округляется.