Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как получить целую часть веществ. числа, Borland C++ 3.0 
:(
    Опции темы
Frekenbok
Дата 6.1.2007, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: 1
Всего: 1



Привет всем!
Вот проблемка возникла на пустом месте... Помогите, пожалуйста.
Есть у меня переменная  num типа double. Мне нужно получить целую часть числа или округлить "вниз". Вроде бы для этого существует функция floor, что меня очень радовало. Но на деле оказалось, что если num=1.0, то floor(num)=0.0, а мне нужно 1.0! 
Был у меня и другой вариант: извлечь целую и дробную части fract=modf(num, &intnum), но в этом случае если num=1.0, то получается fract=1.0, а intnum=0.0. Почему так?
Если просто выводить printf("%.0lf",num), то он сам округляет, и получается не то, что нужно.
На всякий случай поясню, как получаю num, может, это имеет значение, и где-то происходят какие-то округления и обрезания (в С ведь вечно так  smile ):
Код

double grad=0.0, radn=0.0, num=0.0, min=0.0,ho;
scanf("%lf",&grad);
   radn=M_PI/180.0*grad;
   num=radn*6.0/M_PI;

Для grad ввожу значения 30, 45 и др.
Нужно, чтобы для num=1.0 (1.1, 1.2,...,1.8,1.9) на экран вывелось 1, для num=2.0 (2.1, 2.2,...,2.8,2.9) вывелось 2 и т.п. (надеюсь, понятно  smile )
P.S.Задачка на самом деле про то, как по углу часовой стрелки определить, сколько часов и минут на часах.
PM MAIL   Вверх
jonie
Дата 6.1.2007, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



привести типы просто может?  smile должно работать... ну с руганью компиляторов некоторых....
Код

double f=1.0;
int n = f;

ЗЫ: не проверял - под рукой компилятора нет. Но сколь память не изменяет...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
WERITAS
Дата 6.1.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 2.5.2005
Где: Москва

Репутация: нет
Всего: 5



А другие функции округления не пробовали? round например?


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
ILAgent
Дата 6.1.2007, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 1.3.2006

Репутация: нет
Всего: нет



Так можно, наверное:
Код

num=( (num-floor(num))==1 )?num:floor(num);

PM MAIL   Вверх
nickless
Дата 6.1.2007, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(Frekenbok @ 6.1.2007,  13:35)
Вроде бы для этого существует функция floor, что меня очень радовало. Но на деле оказалось, что если num=1.0, то floor(num)=0.0, а мне нужно 1.0! 

floor() работает правильно, проблема в том, что ввиду двоичного представления чисел в компьютере num не может быть равен точно 1.0, только что-то вроде 0.9999999999954 (твой случай) или 1.000000000121, аналогично для modf()
В принципе это не должно сильно мешать, но если в результате будут заметные ошибки, попробуй отлавливать такие места примерно так: 
Код
double eps = 0.000001;
if ((num > 1.0 - eps) && (num < 1.0 + eps))
{
    ...
}



--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Dov
Дата 6.1.2007, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Код

...
int num;
...
num = int(radn*6.0/M_PI);
...
printf("%d", num);


Это сообщение отредактировал(а) Dov - 6.1.2007, 17:12


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Frekenbok
Дата 7.1.2007, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: 1
Всего: 1



Цитата(WERITAS @  6.1.2007,  14:42 Найти цитируемый пост)
А другие функции округления не пробовали? round например? 
В том то и дело, что в моем древнем Борланде такой функции еще нет, поэтому и весь сыр-бор...  smile 

Цитата(jonie @  6.1.2007,  14:40 Найти цитируемый пост)
double f=1.0;
int n = f;
Так не получается.

Цитата(Dov @  6.1.2007,  17:10 Найти цитируемый пост)
Код

num = int(radn*6.0/M_PI);
И так тоже.

Цитата(nickless @  6.1.2007,  16:31 Найти цитируемый пост)
ввиду двоичного представления чисел в компьютере num не может быть равен точно 1.0, только что-то вроде 0.9999999999954 (твой случай) или 1.000000000121
Вот это в самую точку. Были у меня подозрения, но в окошке Watch мой num так убедительно был равен 1.0! Да, не стоит доверять глазам своим.
Только если делать так:
Цитата(nickless @  6.1.2007,  16:31 Найти цитируемый пост)
if ((num > 1.0 - eps) && (num < 1.0 + eps))
то вместо 1.0 мне придется подставлять как раз целую часть числа num, ведь у меня num может быть равен и 2.0, и 3.0 и т.д. И началась песня сначала... А так вообще работает, спасибо.
Но это меня натолкнуло на такой вариант решения: округлить мой num до 0.000001. А для этого использую чью-то чужую умную мысль. Получилось примерно вот что:
Код

double eps=0.000001;
num=floor(num/eps+0.5)*eps; // округляем до 0.000001
intnum=(int)num; // теперь берем целую часть

Вот хорошо бы такие вещи просматривать в дебаггере типа ассемблерного, только как это сделать? Я подозреваю, что надо воспользоваться дизассемблером и там просмотреть ЕХЕ-шник. Вот только где взять этот дизассемблер и какой лучше? Посоветуйте что-нибудь. Или можно как-нибудь еще просмотреть ячейки памяти со значением num (причем "до" и "после", пошагово)?
PM MAIL   Вверх
Dov
Дата 7.1.2007, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Цитата(Frekenbok @  7.1.2007,  11:34 Найти цитируемый пост)
Так не получается.

Цитата(Frekenbok @  7.1.2007,  11:34 Найти цитируемый пост)
И так тоже.

Что у тебя не получается, сказать можешь или это секрет.  smile 



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Frekenbok
Дата 8.1.2007, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: 1
Всего: 1



Dov, я понимаю, что выглядит все логично, взял int-ом обрезал и все. Но на практике не всегда действует. У меня Borland Turbo C++ 3.0. При значении num==1.0 (int)num получается равен 0. А все потому, что я не просто присваиваю num единицу, эта единица у меня получается в результате вычислений (см. первое сообщение), т.е. цитирую еще раз:

Цитата(nickless @  6.1.2007,  16:31 Найти цитируемый пост)
ввиду двоичного представления чисел в компьютере num не может быть равен точно 1.0, только что-то вроде 0.9999999999954 (твой случай) или 1.000000000121

При использовании (int)num результат получается неверным, т.е. не тем, что мне надо.
PM MAIL   Вверх
W4FhLF
Дата 8.1.2007, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Borland Turbo C++ 3.0 поддерживает inline asm вставки? Тогда сделай что-то вроде этого:

Код

float f;
unsigned int x;
__asm
{
fld f
fistp x
};



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nickless
Дата 8.1.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



W4FhLF, какая разница, это не от компилятора зависит, а от процессора


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Daevaorn
Дата 8.1.2007, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(nickless @  8.1.2007,  19:26 Найти цитируемый пост)
какая разница, это не от компилятора зависит, а от процессора 

от процессора зависит, поддерживает ли компилятор inline assembler?smile
PM MAIL WWW   Вверх
nickless
Дата 8.1.2007, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(Daevaorn @ 8.1.2007,  17:28)
от процессора зависит, поддерживает ли компилятор inline assembler?smile

Нет, тут весь топик идет речь о том, что floor(f) может быть равен 0.0, даже если f==1.0


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
W4FhLF
Дата 8.1.2007, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(nickless @  8.1.2007,  18:26 Найти цитируемый пост)
W4FhLF, какая разница, это не от компилятора зависит, а от процессора


Ты бы для начала постарался понять, что такое вещественное число в памяти(в этом тебе поможет моя статья: http://hunger.ru/articles/num), а потом посмотрел бы, что значит команда fist, но я не буду томить и скажу тебе, что эта команда округляет в большую сторону вещественное значение и записывает его в память.


Это сообщение отредактировал(а) W4FhLF - 8.1.2007, 18:54


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nickless
Дата 8.1.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(W4FhLF @ 8.1.2007,  17:52)
Ты бы для начала постарался понять, что такое вещественное число в памяти(в этом тебе поможет моя статья: http://hunger.ru/articles/num), а потом посмотрел бы, что значит команда fist

Спасибо, я знаю.
Между прочим fist округляет не в большую сторону, а в зависимости от fps status word, но и это не поможет округлить 0.9999999999 _вниз_ (человеку надо округлять в меньшую сторону) и получить 1


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0578 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.