Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
magicofwater
0 / 0 / 0
Регистрация: 11.06.2014
Сообщений: 5
#1

LONG VS DOUBLE / INT VS FLOAT - C++

11.06.2014, 12:31. Просмотров 779. Ответов 19
Метки нет (Все метки)

Всем доброго времени суток!
Объясните пожалуйста почему при следующем коде
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
int main()
{
            long e;
            long a = 196;
            double b = a/60.0;
            cout << "a = " << a << endl;
            cout << "b = " << b << endl;
            long c = static_cast<int>(b); // отбрасывание дробной части
            cout << "c = " << c << endl;
            double d = (b - c) * 60;
            cout << d << endl;
            e = d;
            cout << e << endl;
        return 0;
}
Результат d = 16 (так правильно), а результат e = 15???
Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.06.2014, 12:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос LONG VS DOUBLE / INT VS FLOAT (C++):

Размер для данных (int, char, long, double, short, unsigned, float) - C++
Напишите программу, которая будет определять размер для данных (int, char, long, double, short, unsigned, float) и выводить информацию (о...

Создать динамический массив, любого простого типа (например: int, long, float, double) - C++
1. Создать проект, который содержит консольную программу Win32. 2. Создать динамический массив, любого простого типа (например: int,...

Напишите программу, которая будет определять размер для данных (int, char, long, double, short, unsigned, float) и выводить информацию - C++
1. Какие типы данных лучше всего использовать для хранения следующих значений: а) возраст человека в текущем году; б) вес человека в...

Long float и double - C++
В чем отличие long float от double?

Преобразовать 2 числа int в 1 число float(double) | double int1.int2 - C++
Всем привет. Изучая азы C++, столкнулся с такой проблемой. Есть два значения типа int, их необходимо преобразовать в одно значение типа...

Double, int , long double - C++
Как вычислить диапазоны типов вручную указанных в название темы?

19
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:01 #2
Это особенности поведения даблов. Суть в том, что если d = 15.99999999999 вследствие потери точности, то при выведении его как дабла, он округлится нормально, а при выведении как инта целая часть отбросится и будет 15. Приводить к целому типу лучше, прибавляя какое-нибудь небольшое число, например, 0.000000001, чтобы избежать таких потерь в точности

Добавлено через 2 минуты
Вместо e = d надо сделать e = d + 0.000001. Да и
static_cast<int>(b) лучше заменить на static_cast<int>(b + 0.0000001)
0
magicofwater
0 / 0 / 0
Регистрация: 11.06.2014
Сообщений: 5
11.06.2014, 13:04  [ТС] #3
Я думал об этом. Но если выполнить действия
a = 196
b = 196/60=3,266667
c = 3
d = (3,266667 - 3) * 60 = 16.00002
Что больше 16. Соответсвенно, если следовать Вашей версии, то ответ должен быть 16.
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:17 #4
Вы не совсем правильно оцениваете точность операций. Дабл хранит, если не ошибаюсь, около 20 знаков после запятой, округляя только последний. При этом, в нескольких последних знаках могут быть ошибки. В частности,
C++
1
2
cout.precision(20);
cout << d << endl;
выводит
15.999999999999996447
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
11.06.2014, 13:20 #5
Цитата Сообщение от tehnar5 Посмотреть сообщение
около 20 знаков после запятой
Википедия: Число двойной точности
1
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:21 #6
Цитата Сообщение от Croessmah Посмотреть сообщение
Википедия: Число двойной точности
Согласен, был не совсем прав, но суть это не меняет, с округлением надо быть осторожнее.
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 13:24 #7
Цитата Сообщение от tehnar5 Посмотреть сообщение
Приводить к целому типу лучше, прибавляя какое-нибудь небольшое число, например, 0.000000001,
0.5
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:29 #8
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Сообщение от tehnar5
Приводить к целому типу лучше, прибавляя какое-нибудь небольшое число, например, 0.000000001,
0.5
Нет же, тут цель - обрубить дробную часть, а не округлить число по правилам округления

Добавлено через 53 секунды
Да и Ваш способ и для округления не годится для случая отрицательных чисел
0
magicofwater
0 / 0 / 0
Регистрация: 11.06.2014
Сообщений: 5
11.06.2014, 13:32  [ТС] #9
ЭТО РАБОТАЕТ
Вместо e = d надо сделать e = d + 0.000001.
ЭТО НЕ РАБОТАЕТ
Да и static_cast<int>(b) лучше заменить на static_cast<int>(b + 0.0000001)
Почему 0.5, а не 0.6, 0.00001, 0.3?
А более надежные способы есть? Или всегда прибавлять 0.000001 и не задумываться?
0
Renji
1963 / 1361 / 307
Регистрация: 05.06.2014
Сообщений: 3,893
11.06.2014, 13:38 #10
А более надежные способы есть? Или всегда прибавлять 0.000001 и не задумываться?
floor - округление вниз, ceil - округление вверх, round - к ближайшему целому. Иначе - шаманить с флагами процессора, через ассемблерные вставки.
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:42 #11
Цитата Сообщение от magicofwater Посмотреть сообщение
ЭТО НЕ РАБОТАЕТ
Да и static_cast<int>(b) лучше заменить на static_cast<int>(b + 0.0000001)
В данном конкретном случае не работает, так как проблема была только с переменной d. Никаких более надежных способов я не знаю, кроме способа создать свою собственную функцию
C++
1
2
3
4
5
int toInt(double a)
{
    return int(a + 0.0000001);
    return static_cast<int>(a + 0.0000001);
}
Выбирайте любой из двух return-ов, они оба делают, по сути, одно и то же

Добавлено через 2 минуты
Цитата Сообщение от Renji Посмотреть сообщение
floor - округление вниз
Только он тоже возвращает float/double, не знаю, могут ли быть проблемы или нет, но мало ли...
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 13:45 #12
Цитата Сообщение от magicofwater Посмотреть сообщение
Почему 0.5
По правилам округления - все что больше 0.5 округлится вверх, все что меньше вниз.
Если надо строго вверх или вниз - fllor и ceil как уже подсказали.

Цитата Сообщение от tehnar5 Посмотреть сообщение
Да и Ваш способ и для округления не годится для случая отрицательных чисел
округление по модулю пока не отменили.
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
11.06.2014, 13:49 #13
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
округление по модулю пока не отменили.
В смысле? Как ни крути, -0.7 должно округляться до -1, если по правилам, а Вы хотите округлить до нуля, так как int(-0.2) == 0
0
Renji
1963 / 1361 / 307
Регистрация: 05.06.2014
Сообщений: 3,893
11.06.2014, 13:52 #14
Только он тоже возвращает float/double, не знаю, могут ли быть проблемы или нет, но мало ли...
Проблемы у вас были потому что 196/60.0 дало бесконечную дробь, а число разрядов в double конечно. В принципе можно обойти если использовать числа в формате числитель/знаменатель, но не уверен что они есть в стандартной библиотеке. floor же дает целое число, с ним проблем быть не должно. При условии что оно в int влезает.
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 13:54 #15
Цитата Сообщение от tehnar5 Посмотреть сообщение
В смысле?
-(0.7+0.5)
0
11.06.2014, 13:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.06.2014, 13:54
Привет! Вот еще темы с ответами:

Shot int b long double - C++
есть задание нужно поменять местами значения бит в заданном количестве пар бит. Номера бит в парах задаются с клавиатуры. используя shot...

float double int - C++
Доброй ночи, препод совсем запарил, то ему не так, то ему не эдак. // 8.2.cpp: определяет точку входа для консольного приложения. // ...

Как написать такое явное преобразование из double в unsigned long int - C++
как написать такое явное преобразование из double в unsigned long int??? спасибо всем кто поможет...

ОШИБКА [Error] cannot convert 'int*' to 'float*' for argument '1' to 'void Syma(float*,int*,int) - C++
Какая то проблема с указателями,незнаю,не хочет щитать суму парних чисел в второй подпрограме.Извиниет за ошибки.Не владею руским.Помогите...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru