Здравствуйте, netch80, Вы писали:
N>Например, тем, что M_PI может пострадать при компиляции от конверсии из текстового вида в плавучку и дать ошибку в каком-то знаке после запятой.
Ну так ты и сравнивай его на равенство с таким пострадавшим от того же компилятора M_PI. А на то, что какое-либо значение, в том числе 180.0, одинаково пострадает от двух разных компиляторов, я бы полагаться не стал.
Здравствуйте, igna, Вы писали:
I>Ну так ты и сравнивай его на равенство с таким пострадавшим от того же компилятора M_PI. А на то, что какое-либо значение, в том числе 180.0, одинаково пострадает от двух разных компиляторов, я бы полагаться не стал.
То, что компилятор один и тот же, ещё ничего не гарантирует.
using System;
static class Program
{
static void Main()
{
Console.WriteLine((int) (195.95f * 100)); // 19594float f = 195.95f;
Console.WriteLine((int) (f * 100)); // 19595
}
}
Ты не понял, речь о программном сравнении, причем допустимом только в случае отсутствия вычислений. В твоем примере программного сравнения вообще нет, сравнивает человек, зато есть вычисление.
Если это С++, то надо было просто заюзать Boost.Units, и путаница просто не смогла бы возникнуть. Это также куда лучшее решение чем incrementallyRotateQuarterTurn/rotateByDegrees/rotateByRadians.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, jazzer, Вы писали:
MC>>>И как ты этот факт собираешься использовать? Сравнивать некое значение с константой 180? Чем это будет отличаться от сравнения с константой M_PI?
J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему....
I>Сравнивать вычисленные значения нельзя, присвоенные — можно (если осторожно). И то, и другое относится как к сравнению со 180.0, так и к сравнению с M_PI.
Так и представил себе пользователя, вбивающего в окошечко "угод" пи с точностью до хз какого знака после запятой (ему ведь еще откуда-то надо знать, как именно выглядит M_PI на этой конкретной машине) А программа потом радостно сравнивает и говорит пользователю: "Не, это нифига не пи, ты в 54-м знаке ошибся!"
I>Пока ты оставался с целочисленным 180, у тебя была хоть какая-то (полувразумительная) почва под ногами, после того, как ты перешел к значению с плавающей запятой 180.0, в пользу градусов остался пожалуй единственный аргумент: некоторое удобство при отладке. Но оно сильно субъективно, а тормоза при вычислениях объективны.
Если бы это была "какая-то полувразумительная почва под ногами", то тогда в IrfanView, например, не было бы Lossless Jpeg Operation в виде поворота на углы, кратные 90 градусам (или 100 градам, или еще чему угодно, но только не целому числу радиан). Радианы нафиг никому не нужны, не удобны они для практических геометрических задач. Это в абстрактной математике есть совершенно точное число пи, и все формулы замечательно с ними записываются (и там действительно пофиг, радианы это или градусы или еще что), а у нас в компах с этим полная труба, и нам совсем не пофиг.
Например, если у тебя есть прямоугольный треугольник (т.е. с углом в 90 градусов), то ты можешь применять простейшие формулы из теоремы Пифагора и простейшие деления для поиска всяких синусов углов. А для произвольных углов (и для любых углов в радианах) тебе придется поднимать всю тяжелую артиллерию тригонометрии, потому что сравнивать с M_PI — дело неблагодарное.
Я вообще не понимаю, с чем ты споришь.
Твой аргументы аналогичны "для возведения в степень есть страшные формулы, вот и давайте юзать их, а то, что для возведения в степени двойки есть чудесная операция битового сдвига — тем хуже для нее"
ЗЫ Сейчас посмотрел историю — спор с этим аргументом затеял не ты, а netch80 — ну, значит, последний комментарий предназначается ему
Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.
Т.е. если у тебя в программе есть поле ввода, откуда ты читаешь число с плавающей запятой, то 180 всегда будет точно 180 (буду рад услышать аргументацию, почему оно не может быть таковым), а вот с пи тебе придется туго.
Естественно, если ты над этими 180 будешь потом изгаляться, в результате у тебя в общем случае получится не точно 180, но если ты берешь как есть — оно будет точным, и в этом нет никакой разницы с целыми числами.
Поправь меня, если это не так.
Здравствуйте, jazzer, Вы писали:
J>Я вообще не понимаю, с чем ты споришь. J>Твой аргументы аналогичны "для возведения в степень есть страшные формулы, вот и давайте юзать их, а то, что для возведения в степени двойки есть чудесная операция битового сдвига — тем хуже для нее" :xz: J>ЗЫ Сейчас посмотрел историю — спор с этим аргументом затеял не ты, а netch80 — ну, значит, последний комментарий предназначается ему :shuffle:
Ты гонеш, кросавчег (tm)
Я утверждал совсем не это, а то, что
1) градусы удобны для выделения случая "кратно 90" (как и ты), но при этом не обязательно требовать их целочисленности, если эти кратные 90 значения явно сгенерированы
2) переводить в градусы только ради градусов смысла нет
3) в задаче автопилота точность значений вообще дальше третьего знака нереальна
Как из этого можно сделать вывод, что я предлагаю отказаться от простых путей, где они есть, и начать намеренно усложнять — я не знаю. Наверно, для этого нужен какой-то особый скилл неадекватных выводов:)
А остальное — возражения на отдельные утверждения, которые при в общем правильной общей мысли загоняют её в какие-то крайне нелепые стороны. Если ты из возражений на отдельные частные утверждения делаешь вывод о том, что я тебе тотально противоречу — что ж, придётся повторить вывод про "особый скилл" ;))
J>Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.
Угу. Только вот я для проверки аккуратности плавучки нарисовал маленький кусочек кода:
и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386.
Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать.
J>Т.е. если у тебя в программе есть поле ввода, откуда ты читаешь число с плавающей запятой, то 180 всегда будет точно 180 (буду рад услышать аргументацию, почему оно не может быть таковым), а вот с пи тебе придется туго. J>Естественно, если ты над этими 180 будешь потом изгаляться, в результате у тебя в общем случае получится не точно 180, но если ты берешь как есть — оно будет точным, и в этом нет никакой разницы с целыми числами. J>Поправь меня, если это не так.
Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать.
Здравствуйте, netch80, Вы писали:
N>Я утверждал совсем не это, а то, что
ОК, нет проблем. С этой финальной формулировкой спорить не буду, она совпадает с моей (тем более что с ее отдельными положениями я уже соглашался выше)
Есил ты ее на самом деле всегда и подразумевал — ну, значит, я ее не воспринял
J>>Насчет значений с плавающей запятой — есть радикальная разница в представлении 180 и M_PI: 180 всегда представлена точно, а пи так представлена быть не может в принципе, и ты всегда будешь иметь дело с обрезаниями.
N>Угу. Только вот я для проверки аккуратности плавучки нарисовал маленький кусочек кода:
N>
N>и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386. N>Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать.
Я думаю, ты сам понимаешь, что это все — прогулки по саду граблей.
Вот пример оных: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Здесь, оно, конечно, действительно тепличный случай, с точными коэффициентами и умножением на 2 (когда в представлении меняется только экспонента, а мантисса остается той же самой). Но, скажем, для углов типа пи/3 (которые все еще точны в градусной мере), мне кажется, уже никаких гарантий дать нельзя.
N>Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать.
Пис, браза!
Здравствуйте, Mr.Cat, Вы писали:
MC>Здравствуйте, jazzer, Вы писали: J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему.... MC>Вот ведь как — достаточно обвинить оппонента в невежестве и его сообщения можно не читать. Да?
Ну вот если ты все мои сообщения в этой ветке прочитал, ты все еще продолжаешь настаивать, что сравнивать с пи — это хорошая идея?
Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее): http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Если ты все это уже знал и все равно ответил то, что ответил — ну, значит, я не понял, что ты имеешь в виду и как ты собираешься от этих эффектов уходить, прошу прощения.
Здравствуйте, Mr.Cat, Вы писали:
MC>Здравствуйте, jazzer, Вы писали: J>>Иди почитай где-нть про сравнение чисел с плавающей запятой на равенство, в сети море информации на эту тему.... MC>Вот ведь как — достаточно обвинить оппонента в невежестве и его сообщения можно не читать. Да?
Здравствуйте, jazzer, Вы писали:
N>>и как ты думаешь, что он мне выдал? он мне выдал все три равенства. Фря/7.2/i386. N>>Так что несмотря на то, что ты прав в общем — слишком легко нарваться на "тепличный" случай, когда можно даже на равенство сравнивать. J>Я думаю, ты сам понимаешь, что это все — прогулки по саду граблей.
Я-то понимаю. Я на подобные грабли наступал регулярно и в более извращённой форме. Но на практике постоянно встречаешь ситуации, когда заведомо грабельные решения работают, потому что именно в данном случае грабли не встретились. Вот это — неприятно.
J>Вот пример оных: J>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Ну это уже вообще-то диверсия компилятора. Даже если стандарт такое допускает, я бы за такое написание компилятора бил ногами.
J>Здесь, оно, конечно, действительно тепличный случай, с точными коэффициентами и умножением на 2 (когда в представлении меняется только экспонента, а мантисса остается той же самой). Но, скажем, для углов типа пи/3 (которые все еще точны в градусной мере), мне кажется, уже никаких гарантий дать нельзя.
Это ты про радианы и попытки на их основании вычислить точный угол? Ну я как раз такого пути не предлагаю — точный угол надо определять только по градусам.
N>>Ну кто бы спорил, я подтвержу. Только это не единственный вывод, который тут можно и нужно делать. J>Пис, браза! :beer:
Здравствуйте, jazzer, Вы писали:
J>Так и представил себе пользователя, вбивающего в окошечко "угод" пи с точностью до хз какого знака после запятой ...
Ну, собственно, в первом моем сообщении в этой теме я сразу написал:
... это преобразование нужно выполнять только при вводе информации от пользователя, внутри программа должна иметь дело только с радианами.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Курилка, Вы писали:
К>>Здравствуйте, jazzer, Вы писали:
J>>>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее): J>>>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18 К>>Я так понимаю имелоь в виду всёж http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17?
J>ну, 17-й очевиден и его все знают (я так думаю), а 18-й гораздо прикольнее, согласись, и больше подходит к примеру netch80.
Здравствуйте, Курилка, Вы писали:
J>>ну, 17-й очевиден и его все знают (я так думаю), а 18-й гораздо прикольнее, согласись, и больше подходит к примеру netch80.
К>только единичек там я не вижу.
единички выделены:
#include <cmath>
void foo(double x, double y)
{
if (cos(x) != cos(y)) {
std::cout << "Huh?!?\n"; // ← you might end up here when x == y!!
}
}
int main()
{
foo(1.0, 1.0);return 0;
}
Здравствуйте, wallaby, Вы писали:
W>Здравствуйте, jazzer, Вы писали:
J>>Robert C. Martin's Clean Code Tip #12: Eliminate Boolean Arguments J>>http://www.informit.com/articles/article.aspx?p=1392524
W>Так много слов для одной простой мысли: W>Вместо одной функции с булевым аргументом часто правильнее использовать две функции.
а я не согласен.
там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.
правильно — делать правильную функциональную декомпозицию.
Здравствуйте, jazzer, Вы писали: J>Ну вот если ты все мои сообщения в этой ветке прочитал, ты все еще продолжаешь настаивать, что сравнивать с пи — это хорошая идея?
Я продолжаю настаивать, что градусы не лучше радианов.
J>Вот замечательный пример фейерверков, которые бывают при сравнении плавающих чисел (там вообще аргументы — единички, все еще проще и нагляднее): J>http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Восхитительно. Как видишь, от погрешности вычислений ты не защищен даже в простейших случаях и даже если у тебя входные данные точно представимы в соответствующих типах данных. Ты все еще настаиваешь, что 180.0 лучше, чем M_PI?
Я соглашусь, что градусы хороши как минимум в 2 случаях:
1. В качестве формата входных/выходных данных — когда они вводятся пользователем или выдаются пользователю — это то, о чем ты пишешь здесь: http://rsdn.ru/forum/philosophy/3535040.1.aspx
. И то:
1.1 Только за счет наличия особых точек: 45, 90, 180, ну и т.п.
1.2 Не всегда, т.к. иногда лучше вместо особой точки сделать "отдельную кнопку", например, выделить в меню 2 "поворота на пи-пополам" и один "поворот на угол".
1.3 Нужно задуматься, о предметной области и откуда пользователь берет вводимые значения — из головы или, скажем, из вывода какого-нибудь символьного пакета, который выдает ему значения в формате "пи-пополам плюс е-в-кубе".
2. Когда возможны целочисленные вычисления. Тогда угол, наверное, удобнее представлять градусами, чем какими-нибудь процентами от пи.
Здравствуйте, igna, Вы писали:
J>>То же, кстати, относится к доброй половине финансовых программ, где цены, вроде как, не целые, но из лучше хранить как целые или как пару целых.
I>Кстати, а что, все же есть финансовые программы, которые хранят цены как float? Никогда подобными вещами не занимался, но вроде это расхожий пример неправильного выбора типа.
Все зависит от конкретной задачи.
Если допустима погрешность — то почему бы и нет?
А погрешность полностью недопустима только в программах вещущих учет денег в той или иной форме. Потому что несовпадение общей суммы и подсуммы любой части однозначно является некорректным поведением.
Для программ же анализа финансовых данных, погрешность вополне может быть допустима.
Здравствуйте, _pk_sly, Вы писали:
__>там ниже пишут про функции с WinAPI с пятью параметрами TRUE — что, правильнее сделать 32 функции? — это бред.
Нет, просто вместо булевских параметров сделать енумы.
__>правильно — делать правильную функциональную декомпозицию.
"правильно — делать правильно" — с этим, наверное, все согласны