Как проверить, является ли огромное число с плавающей запятой целым числом?

#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/vC1OG

4. @AndreyT: Да…. Я это сделал. Он печатает что-то другое … которое больше не является плавающим.. Спасибо..

5. @Nawaz: Не плавающее? Совсем наоборот, оно по сути плавающее. С вашими числами произошло именно то, что происходит с числами с плавающей запятой: поскольку ширина мантиссы ограничена, число округляется.