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

Поиск:

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


Опытный
**


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

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



Мне кажется, в данной задаче суть в ошибках округления. Чтобы их уменьшить, можно воспользоваться тем, что в часах для угловой стрелки 360 угловых градусов соответствуют 12 временным часам или 720 временным минутам. Поэтому можно использовать такой вариант:
Код

    int SumMin=int(2*grad);
    int Ho=SumMin/60, Min=SumMin%60;

PM MAIL   Вверх
W4FhLF
Дата 8.1.2007, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


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

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



Цитата(nickless @  8.1.2007,  19:08 Найти цитируемый пост)
Между прочим fist округляет не в большую сторону, а в зависимости от fps status word, но и это не поможет округлить 0.9999999999 _вниз_ (человеку надо округлять в меньшую сторону) и получить 1


Да, уточнил, я думал на флаг RC ориентируется только fistp. А как это округлить 0.9999999 в меньшую сторону и получить при этом 1? Что-то мне неясно. 

Кстати, вот пример округления до ближайшего целого, это поможет избавиться от погрешности с которой сопроцессор представляет числа в памяти:

Код

#include <stdio.h>

int main()
{
    float f;
    unsigned int x;
    unsigned short int y;
    f = 0.999999;
    __asm {
        and y,0xFFFF
        fstcw word ptr[y]
        and word ptr[y],0xFFCF
        fldcw word ptr[y]
        fld f
        fistp dword ptr[x]
    };
    return 0;
}


На выходе в x имеем 1. 




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


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


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

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



1)  можно тупо изобрести велосипед
Код

double round(double x)
{
  double fl = floor(x);
  double cl = ceil(x);
  if( (cl - x) < (x - fl) ) { // если x ближе к cl, чем к floor
      return cl;
  } 
  return fl;
}


2) достать нормальный компилятор.



--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Anikmar
Дата 9.1.2007, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Можно так:

floor(num+0.1);

или

floor (num+0.01)
PM MAIL ICQ   Вверх
Frekenbok
Дата 10.1.2007, 04:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Anikmar @  9.1.2007,  19:55 Найти цитируемый пост)
Можно так:
floor(num+0.1);

А если число будет 1.954187? Тогда floor(num+0.1) будет равно 2. А надо 1.
PM MAIL   Вверх
codelord
Дата 10.1.2007, 07:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 777
Регистрация: 7.5.2005
Где: ты моя темноглаза я где?!

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



Frekenbok, а вариант 
Mayk, чем не устраивает?


--------------------
Доступен поиск по исходным кодам в GOOGLE.
http://www.google.com/codesearch
PM MAIL   Вверх
Frekenbok
Дата 10.1.2007, 07:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(codelord @  10.1.2007,  07:03 Найти цитируемый пост)
а вариант 
Mayk, чем не устраивает? 

Все-таки в 1 случае из 25 вывел неверно  smile 
Можно ли просмотреть значения переменных С++ в дебаггере наподобие ассемблера? чтобы видно было, какое число получается в ячейке памяти?

W4FhLF, кстати, твой вариант не сработал, надо как-то подгонять под мои данные, наверное. У меня double num вместо float f. Не знаю, имеет ли это значение, наверное, да. До программирования сопроцессора еще не дошло дело. Пока только процессор.

Добавлено @ 07:36 
А почему, кстати, в моем варианте число именно меньше 1 (0.99999999), а не больше (1.000000000024)? В скобках я к примеру указываю.  smile 

PM MAIL   Вверх
W4FhLF
Дата 10.1.2007, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


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

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



Цитата(Frekenbok @  10.1.2007,  07:34 Найти цитируемый пост)
W4FhLF, кстати, твой вариант не сработал, надо как-то подгонять под мои данные, наверное. У меня double num вместо float f. Не знаю, имеет ли это значение, наверное, да. До программирования сопроцессора еще не дошло дело. Пока только процессор.



Ну имеет конечно, double занимает 8 байт, а float 4. Так вот попробуй:

Код

int main()
{
    
    double f; // 8 байт.
    unsigned long int x; // 8 байт.
    unsigned short int y; // 2 байта для регистра сопроцессора CWR.
    f = 1.954187;
    __asm {
        fstcw word ptr[y] // Сохранение регистра в память.
        xor word ptr[y],0x400 // Устанавливаем десятый бит. Флаг RC будет равен 01, это говорит сопроцессору, что при сохранении 
                  //нужно округлять числа в меньшую сторону
        fldcw word ptr[y] // Загружаем регистр снова
        fld f // Кладём значение f на вершину стека сопроцессора.
        fistp qword ptr[x] // Сохраняем в переменную x округлённое до меньшего целого значение с вершины стека.
    };
    return 0;
}


На выходе в x получаем 1. Что и требовалось доказатьsmile

Добавлено @ 08:11 
Цитата(Frekenbok @  10.1.2007,  07:34 Найти цитируемый пост)
А почему, кстати, в моем варианте число именно меньше 1 (0.99999999), а не больше (1.000000000024)? В скобках я к примеру указываю.


А оно почти всегда будет чуть меньше, кроме тех случаев, когда ты сохраняешь периодичную, с точки зрения двоичной системы, дробь(0.125 или 8.625 например). Это погрешность при переводе десятичных дробей в двоичные. 

Это сообщение отредактировал(а) W4FhLF - 10.1.2007, 08:35


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 777
Регистрация: 7.5.2005
Где: ты моя темноглаза я где?!

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



Цитата

Нужно, чтобы для num=1.0 (1.1, 1.2,...,1.8,1.9) на экран вывелось 1, для num=2.0 (2.1, 2.2,...,2.8,2.9) вывелось 2 и т.п.

ну вот от меня еще вроде работает, надеюсь и у тебя тоже будет.
Код

long double round2(long double x)
{
 long double fl = floor(x);
 long double cl = ceil(x);
  if((cl - x)  <0.0999 ) { // погрешность выставлял на 0.1
      return cl;
  } 
  return fl;
}


Добавлено @ 08:21 
Цитата

Можно ли просмотреть значения переменных С++ в дебаггере наподобие ассемблера? чтобы видно было, какое число получается в ячейке памяти?

наведи каретку на переменную и ctrl + f5 по моему вроде так smile


--------------------
Доступен поиск по исходным кодам в GOOGLE.
http://www.google.com/codesearch
PM MAIL   Вверх
Frekenbok
Дата 16.1.2007, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(W4FhLF @  10.1.2007,  08:10 Найти цитируемый пост)
А оно почти всегда будет чуть меньше, кроме тех случаев, когда ты сохраняешь периодичную, с точки зрения двоичной системы, дробь(0.125 или 8.625 например). Это погрешность при переводе десятичных дробей в двоичные. 

Тогда получается, что если у меня число 0.999999, то мне, наоборот, надо округлять "вверх"!  smile  Я-то думала, что если у меня в окне Watch num=1.0, то он будет ну не меньше 1. Получается, я всех ввела в заблуждение. Sorry.  Поэтому вариант W4FhLF с асм-вставкой работает правильно, но мне не подходит. 
А вот вариант codelord то, что надо. Спасибо.

Цитата(codelord @  10.1.2007,  08:13 Найти цитируемый пост)
наведи каретку на переменную и ctrl + f5
В Turbo C++ 3.0 не работает.
Вообще, всем спасибо за помощь. Думаю, тему можно закрыть  smile 


PM MAIL   Вверх
Frekenbok
Дата 16.1.2007, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Ln78 @  8.1.2007,  19:32 Найти цитируемый пост)
Мне кажется, в данной задаче суть в ошибках округления. Чтобы их уменьшить, можно воспользоваться тем, что в часах для угловой стрелки 360 угловых градусов соответствуют 12 временным часам или 720 временным минутам. Поэтому можно использовать такой вариант:

код C++
1:
2:

    int SumMin=int(2*grad);
    int Ho=SumMin/60, Min=SumMin%60;


Кстати, очень хороший вариант. Только по условию задачи угол в радианах. Я ввожу в градусах, чтобы потом легче было сопоставить угол и время. Отсюда и вылезают всякие погрешности округления smile 
PM MAIL   Вверх
xKrIvEdKox
Дата 31.5.2009, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



x:=round(x*100)/100; 
smile 
PM MAIL   Вверх
Dmi3ev
Дата 1.6.2009, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



удалил...

Это сообщение отредактировал(а) Dmi3ev - 1.6.2009, 01:00


--------------------

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.0979 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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