Re: visual c++ неправельно умножает
От: babur Россия  
Дата: 27.08.04 08:37
Оценка: 1 (1)
А> double d_v=133.20;
А> double d_y=10;
А> long l_v=(long)(d_v*100);
А>- получается 13319
Дело в том, что вещественное число 133.2 не имеет конечного двоичного представления. Для машины это бесконечная дробь, часть знаков которой хранится, а отброшенные и составляют ту самую погрешность. После умножения на 10, число не становится целым, а по прежнему имеет хвост из девяток (в десятичном представлении). Преобразование (long) просто отбрасывает дробную часть Вашего числа и оставляет целую, а она равна 13319, за которой следует .9999999

Вам следует использовать функции округления при преобразовании вещественных чисел к целым типам, а не просто преобразование типов.

Успехов,
Данил
visual c++ неправельно умножает
От: Аноним  
Дата: 27.08.04 07:33
Оценка:
пишу

double d_v=133.20;
double d_y=10;
long l_v=(long)(d_v*100);

printf("%ld",l_v);

— получается 13319
в отладке смотрю l_v=13319.9999999998 сразу после умножения

double d_v=133.20;
double d_y=10;
long l_v=(long)(d_v*100);

в отладке отрабатывает и l_v = 13320 — как и должно быть
в релизе отрабатывает и l_v = 13319 — как не должно быть


подобных глюков нет если 250.20 умножать на 100

может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.

а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double
Re: visual c++ неправельно умножает
От: Аноним  
Дата: 27.08.04 07:41
Оценка:
Читай про форматы вещественных чисел и про вещественную арифметику.
Re: visual c++ неправельно умножает
От: ilnar Россия  
Дата: 27.08.04 07:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.


А>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь 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++/
Re[3]: visual c++ неправельно умножает
От: ilnar Россия  
Дата: 27.08.04 08:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, ilnar, Вы писали:


I>>Здравствуйте, Аноним, Вы писали:


А>>>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.


А>>>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double


I>>тут срабатывает такая чуча: double хранится в своем внутренном виде — этот вид имеет определенную погрешность. дргое число тоже. при умножении получается допустим x^2 — производная 2x — значит умножение двух double c погрешностью delta даст погрешность в два delta.

I>>это лишь простое объяснение, тут действует еще и множители — 10 — незаметную погрешность сделает заметной.
I>>если делаешь для бухгалтерии, то лучше работать со своими числами — long для целой части, char для копеек, определишь для них операции — и вперед с песней

А>Большое спасибо. более разумное объяснение — конкретно тип double считаю редко — обычно получаю с БД готовые числа которые просто вывожу.

А>но вот услышал такое что это еще может зависить от сопроцессора и самого процессора — вроде как в АМД нет таких глюков — пробоволось правдо на юниксе -может быть выключить /включить сопроцессор для пущей верности — есть гденибудь галочка в visual c++/

да нет, это зависит от формата представления double. сопроцессор разных фирм может скорее всего делать только корректировку учитывая погрешности
Re: visual c++ неправельно умножает
От: little_alex  
Дата: 27.08.04 14:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>может я отстал от матиматики — или это теория вероятности — как бухгалтерам объяснить Т.О.


А>а все же раскажите эту особенность — а то вот пишу думаю — что так все стабилно — а тут какая-то матиматика не такая , кук умножать теперь double



Если нет проблем с английским посмотри в google статью What Every Computer Scientist Should Know About Floating-Point Arithmetic
Про все подробно написано — На сайте gcc рекомендуется прочитать всем кто хочет отправить bug report по поводу float.
А про различия intel и AMD — результаты должны совпадать до бита — на то и стандарт IEEE есть -см книгу
Re[2]: visual c++ неправельно умножает
От: Lorenzo_LAMAS  
Дата: 27.08.04 14:16
Оценка:
Увы, page not found
Of course, the code must be complete enough to compile and link.
Re[3]: visual c++ неправельно умножает
От: Lorenzo_LAMAS  
Дата: 27.08.04 14:17
Оценка:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
Of course, the code must be complete enough to compile and link.
Re[3]: visual c++ неправельно умножает
От: Андрей Тарасевич Беларусь  
Дата: 28.08.04 19:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>но вот услышал такое что это еще может зависить от сопроцессора и самого процессора — вроде как в АМД нет таких глюков — пробоволось правдо на юниксе -может быть выключить /включить сопроцессор для пущей верности — есть гденибудь галочка в visual c++/


Нет тут никаких "глюков". Совершенно аналогичные явления ты будешь наблюдать на любой двоичной машине, использующей для представления вещественных чисел двоичный плавающий формат. В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления). Поэтому ожидать какой-то абсолютной точности от соотвествующих вычислений не приходится уже потому, что ты использовал число, дробная часть которого равна '0.2'.
Best regards,
Андрей Тарасевич
Re[4]: visual c++ неправельно умножает
От: alekzander  
Дата: 28.08.04 22:53
Оценка:
АТ>В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления).
думаю это не совсем правда.
можно придумать такое предстваление, в котором это число будет точно представлятся в двоичном формате.
хотя, уонечно, вещественные числа подразумевают бесконечность между двумя любыми числами.
а современные процессора, к сожалению, далеки(бесконечно) от операция с бесконечностями
Re[5]: visual c++ неправельно умножает
От: Андрей Тарасевич Беларусь  
Дата: 29.08.04 00:04
Оценка:
Здравствуйте, alekzander, Вы писали:

АТ>>В частности, в твоем примере ты использовал число '133.2'. Это число в принципе невозможно представить точно в двоичном плавающем формате (при ограниченной длине представления).

A>думаю это не совсем правда.

Это правда.

A>можно придумать такое предстваление, в котором это число будет точно представлятся в двоичном формате.


Я имел в виду вполне конкретный формат — двоичную дробь (по аналогии с десятичной дробью). В этом формате запись данного числа бесконечна. Соответственно, любой формат, основанный на "вырезании" некоторого конечного кусочка из этой бесконечной дроби, будет по определению неточным.

А придумать другой формат разумеется можно. Но это уже совсем другая опера.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.