Здравствуйте, Аноним, Вы писали:
А>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.
А>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double
тут срабатывает такая чуча: double хранится в своем внутренном виде — этот вид имеет определенную погрешность. дргое число тоже. при умножении получается допустим x^2 — производная 2x — значит умножение двух double c погрешностью delta даст погрешность в два delta.
это лишь простое объяснение, тут действует еще и множители — 10 — незаметную погрешность сделает заметной.
если делаешь для бухгалтерии, то лучше работать со своими числами — long для целой части, char для копеек, определишь для них операции — и вперед с песней
Re[2]: visual c++ неправельно умножает
От:
Аноним
Дата:
27.08.04 08:01
Оценка:
Здравствуйте, ilnar, Вы писали:
I>Здравствуйте, Аноним, Вы писали:
А>>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.
А>>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double
I>тут срабатывает такая чуча: double хранится в своем внутренном виде — этот вид имеет определенную погрешность. дргое число тоже. при умножении получается допустим x^2 — производная 2x — значит умножение двух double c погрешностью delta даст погрешность в два delta. I>это лишь простое объяснение, тут действует еще и множители — 10 — незаметную погрешность сделает заметной. I>если делаешь для бухгалтерии, то лучше работать со своими числами — long для целой части, char для копеек, определишь для них операции — и вперед с песней
Большое спасибо. более разумное объяснение — конкретно тип double считаю редко — обычно получаю с БД готовые числа которые просто вывожу.
но вот услышал такое что это еще может зависить от сопроцессора и самого процессора — вроде как в АМД нет таких глюков — пробоволось правдо на юниксе -может быть выключить /включить сопроцессор для пущей верности — есть гденибудь галочка в visual c++/
А> double d_v=133.20; А> double d_y=10; А> long l_v=(long)(d_v*100); А>- получается 13319
Дело в том, что вещественное число 133.2 не имеет конечного двоичного представления. Для машины это бесконечная дробь, часть знаков которой хранится, а отброшенные и составляют ту самую погрешность. После умножения на 10, число не становится целым, а по прежнему имеет хвост из девяток (в десятичном представлении). Преобразование (long) просто отбрасывает дробную часть Вашего числа и оставляет целую, а она равна 13319, за которой следует .9999999
Вам следует использовать функции округления при преобразовании вещественных чисел к целым типам, а не просто преобразование типов.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, ilnar, Вы писали:
I>>Здравствуйте, Аноним, Вы писали:
А>>>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.
А>>>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double
I>>тут срабатывает такая чуча: double хранится в своем внутренном виде — этот вид имеет определенную погрешность. дргое число тоже. при умножении получается допустим x^2 — производная 2x — значит умножение двух double c погрешностью delta даст погрешность в два delta. I>>это лишь простое объяснение, тут действует еще и множители — 10 — незаметную погрешность сделает заметной. I>>если делаешь для бухгалтерии, то лучше работать со своими числами — long для целой части, char для копеек, определишь для них операции — и вперед с песней
А>Большое спасибо. более разумное объяснение — конкретно тип double считаю редко — обычно получаю с БД готовые числа которые просто вывожу. А>но вот услышал такое что это еще может зависить от сопроцессора и самого процессора — вроде как в АМД нет таких глюков — пробоволось правдо на юниксе -может быть выключить /включить сопроцессор для пущей верности — есть гденибудь галочка в visual c++/
да нет, это зависит от формата представления double. сопроцессор разных фирм может скорее всего делать только корректировку учитывая погрешности
Здравствуйте, Аноним, Вы писали:
А>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.
А>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double
Если нет проблем с английским посмотри в google статью What Every Computer Scientist Should Know About Floating-Point Arithmetic
Про все подробно написано — На сайте gcc рекомендуется прочитать всем кто хочет отправить bug report по поводу float.
А про различия intel и AMD — результаты должны совпадать до бита — на то и стандарт IEEE есть -см книгу
Здравствуйте, Аноним, Вы писали:
А>но вот услышал такое что это еще может зависить от сопроцессора и самого процессора — вроде как в АМД нет таких глюков — пробоволось правдо на юниксе -может быть выключить /включить сопроцессор для пущей верности — есть гденибудь галочка в visual c++/
Нет тут никаких "глюков". Совершенно аналогичные явления ты будешь наблюдать на любой двоичной машине, использующей для представления вещественных чисел двоичный плавающий формат. В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления). Поэтому ожидать какой-то абсолютной точности от соотвествующих вычислений не приходится уже потому, что ты использовал число, дробная часть которого равна '0.2'.
АТ>В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления).
думаю это не совсем правда.
можно придумать такое предстваление, в котором это число будет точно представлятся в двоичном формате.
хотя, уонечно, вещественные числа подразумевают бесконечность между двумя любыми числами.
а современные процессора, к сожалению, далеки(бесконечно) от операция с бесконечностями
Здравствуйте, alekzander, Вы писали:
АТ>>В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления). A>думаю это не совсем правда.
Это правда.
A>можно придумать такое предстваление, в котором это число будет точно представлятся в двоичном формате.
Я имел в виду вполне конкретный формат — двоичную дробь (по аналогии с десятичной дробью). В этом формате запись данного числа бесконечна. Соответственно, любой формат, основанный на "вырезании" некоторого конечного кусочка из этой бесконечной дроби, будет по определению неточным.
А придумать другой формат разумеется можно. Но это уже совсем другая опера.