Здравствуйте, Adriano, Вы писали:
A>Всем привет!
A>В примре две функции good и bad. В good получаем правильный результат, в bad — неправильный.
A>Вопрос: как правильно работать с double что бы не терять биты на границах 0.5?
А почему вы решили, что биты теряются на границе 0.5? И что значит "граница 0.5"?
Здравствуйте, Adriano, Вы писали:
A>Всем привет!
A>В примре две функции good и bad. В good получаем правильный результат, в bad — неправильный.
... A>Вопрос: как правильно работать с double что бы не терять биты на границах 0.5?
Использовать atod вместо atof. Тогда в промежуточных вычислениях не будет округления до float.
Здравствуйте, telek1024, Вы писали:
T>А почему вы решили, что биты теряются на границе 0.5? И что значит "граница 0.5"?
Я плаваю в этой теме
T>Мне кажется, что для начала вам нужно почитать документацию о том, как хранятся вещественные числа в памяти. Начните отсюда: http://en.wikipedia.org/wiki/IEEE_754-1985
Я понимаю, что не все десятичные дроби можно представить в двоичной системе.
T>Или ещё можно написать std::setprecision(20) вместо std::setprecision(3)и посмотреть, что выведет программа.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, Adriano, Вы писали:
A>>Как быть если нужна точность 3 знака после запятой? U>у вас ведь есть функция good U>чем она вас не устраивает?
1. Мне не понятно почему bad работает неправильно. В каком месте ошибка?
2. atof используется очень часто ( и в сторонних библиотеках), возникает вопрос: "округлять" каждый double?
Здравствуйте, Adriano, Вы писали:
A>Здравствуйте, telek1024, Вы писали:
T>>Или ещё можно написать std::setprecision(20) вместо std::setprecision(3)и посмотреть, что выведет программа.
A>Если установить точность — 4, то все правильно:
Так я сказал про 20 Поставьте 20 и поймёте, почему при 3 — неправильно, а при 4 правильно.
A>Как быть если нужна точность 3 знака после запятой?
Не использовать числа с плавающей точкой.
Я подозреваю, что у вас там деньги или котировки. Ни double, ни float для этого не подходят. Напишите свой класс, который будет точно хранить десятичные знаки или возьмите готовую реализацию. Пример запроса для поиска: http://www.google.ru/search?q=C%2B%2B+BigDecimal
Здравствуйте, telek1024, Вы писали:
A>>Если установить точность — 4, то все правильно:
T>Так я сказал про 20 Поставьте 20 и поймёте, почему при 3 — неправильно, а при 4 правильно.
A>>Как быть если нужна точность 3 знака после запятой? T>Не использовать числа с плавающей точкой.
Библиотеки разрабатываются другим отделом и заставить их переписать все с использованием decimal не так то просто.
Также используется питон:
с++ double -> Python double -> c++ double
В питоне есть модуль decimal, на моем примере питоновский decimal в 2000 раз медленнее чем double, говорят что он хранит число как список из integer.
вас тяжело понять что для вас правильно. а что неправильно
попробуйте описать задачу подробнее
что вы вычисляете? почему работая с типом double вам приходится сохранять лишь три знака после запятой? как преобразование из произвольного числа для вас правильное? A>1. Мне не понятно почему bad работает неправильно. В каком месте ошибка?
возможная ошибка в print_mid_bid_ask A>2. atof используется очень часто ( и в сторонних библиотеках), возникает вопрос: "округлять" каждый double?
ваша задача неясна. почему другие функции работают с double, а не с округленным число?
если нужны только три знака после запятой, то делают так:
double xNew = ((int)(x*1000))/1000.0;
то есть отбрасываю все остальные цифры A>Хочу узнать, так сказать, best practices
если возникает потребность в числах определенной природы, то используют другие типы, такие как money, rational (p\q)
Здравствуйте, Adriano, Вы писали:
A>Здравствуйте, telek1024, Вы писали:
A>>>Если установить точность — 4, то все правильно:
T>>Так я сказал про 20 Поставьте 20 и поймёте, почему при 3 — неправильно, а при 4 правильно.
A>>>Как быть если нужна точность 3 знака после запятой? T>>Не использовать числа с плавающей точкой.
A>Библиотеки разрабатываются другим отделом и заставить их переписать все с использованием decimal не так то просто.
Придётся. Так как тип используется не по назначению.
Или писать обёртку.
A>Также используется питон: A>с++ double -> Python double -> c++ double
A>В питоне есть модуль decimal, на моем примере питоновский decimal в 2000 раз медленнее чем double, говорят что он хранит число как список из integer.
Мир не совершенен. double работает быстро, но портит младшие разряды. decimal — медленно, но не портит результат.
Здравствуйте, uzhas, Вы писали: U>если нужны только три знака после запятой, то делают так: U>double xNew = ((int)(x*1000))/1000.0; U>то есть отбрасываю все остальные цифры