Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. запуск скомпилированного exe-шника дает 3759.97 Меня сейчас не интересует, какой именно должен быть результат (тему округлений подробно разбирали в другой ветке) и что в этой формуле плохо (с темой неточности представления плавающей точки знаком). Меня интересует, чтобы результат был одинаков. Функция проработала 8 лет, давая одинаковый результат, теперь дает разный. Точного момента поломки отследить не могу, из подозрительных действий на машине ставился только офис ХР (потом снесен). Может он и заменил какую-то библиотеку, я бы понял, если бы на разных компах вдруг оказались разные результаты. Но почему на одной и той же машине? Ведь библиотеки, по идее, должны быть одними и теми же! Есть у кого какие идеи? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 22:17 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Бывает :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 00:08 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
У меня XP SP2 тоже выдает ххх.97 компилированый проэкт ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 00:14 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Инфо на всякий случай: в VB и VBA функция Round(1.5,0) = 2 и Round(2.5,0) = 2 То есть, Round() – это банковское округление, а не арифметическое. Соответственно: Round(1.235,2) = 1.24 и Round(1.245,2) = 1.24 Если нужно оставить такое банковское округление, и получить однозначность в IDE и скомпилированного варианта, то округлите, например, сначала до 3-х знаков, а затем до 2-х: Round(Round(YourDoubleValue,3),2). Вместо 3 можно использовать 4…12. Если же требуется арифметическое округление, то можно, например, так: MsgBox --FormatNumber(4436.7705 - 4436.7705 / (1# + 0.18) * 0.18, 2) или MsgBox --Format(4436.7705 - 4436.7705 / (1# + 0.18) * 0.18, "#0.00") Впрочем, с подобным округлением были разные варианты реализации в разных версиях OLEAUT32.dll – то банковское, то арифметическое, поэтому для арифметического округления я использую свою пользовательскую функцию, которая в раз 14 быстрее, чем приведенные выше: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 00:59 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
В примерах вместо двойного минуса лучше применять CDbl() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 01:02 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
ZVI, Спасибо, но речь не об этом. Сейчас эту функцию можно было бы доработать как угодно, но в том-то и дело, что она теперь выдает результаты не те, что раньше, то есть некоторые РАНЕЕ рассчитанные документы теперь расчитываются по-другому, и кое-где не сходятся копейки. Уточню - скомпилированный экзешник работает как и раньше, а вот в IDE стали выдаваться несколько другие результаты. Вы полагаете, это может быть связано с OLEAUT32.dll? Но я нашел эту библиотеку только в system32 и в dllcache - файлы идентичны. P.S. Переустановка студии не помогла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 01:28 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Shocker.Pro, Варианты решения Вашей проблемы я привел - проверьте, начиная с Round(Round(YourDoubleValue,3),2). У меня все эти варианты выдают одно и то же значение и в IDE и после компилирования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 01:46 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
ZVIShocker.Pro, Варианты решения Вашей проблемы я привел - проверьте, начиная с Round(Round(YourDoubleValue,3),2). У меня все эти варианты выдают одно и то же значение и в IDE и после компилирования. Приложил код и EXE - проверьте, все ли так, как ожидалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 02:02 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
ZVIShocker.Pro, Варианты решения Вашей проблемы я привел - проверьте, начиная с Round(Round(YourDoubleValue,3),2). У меня все эти варианты выдают одно и то же значение и в IDE и после компилирования. Да, они выдают .98 в обоих случаях. Но. Мне нужно, чтобы было .97 (чтобы сохранить совместимость со старыми документами). Я еще не разбирался досконально (это потребует больших усилий на автоматизацию проверки на сотнях примеров), но мне кажется, что дело не столько в банковском/арифметическом округлении пятерки, сколько в нюансах сложения двух чисел с плавающей точкой в каком-нибудь последнем знаке. Что отчасти подтверждается тем, что если в моем примере заменить (1+0.18) на (1.18), то результат получается уже другой. Поэтому хотелось бы восстановить работоспособность системы, а потом неспеша спуститься с горы заняться созданием одноззначности формулы (раз уж выявилось такое узкое место). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 02:13 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Про банковское округление я упомянил на всякий случай. Это не причина Вашей проблемы. Причина описана здесь: http://support.microsoft.com/kb/78113/ru] Результаты арифметических операций с плавающей точкой в Excel могут быть неточными Более точный вариант округления как раз выдает EXE вариант, а Вам, получается, нужен менее точный, который подставляет IDE. Убедиться в том, что шалит именно C:\WINDOWS\system32\oleaut32.dll поможет такой код: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. IDE выдаст 3759.98, а EXE 3759.97 Полагаю, что у Вас всегда так и было, просто не нарывались на пораженные точки округления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 03:04 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
Думаю, теперь понятно, что проблема - в округлении промежуточных результатов вычислений. Можно воспроизвести в IDE алгоритм вычислений и округлений EXE. Разбейте выражение на 2 части в соответствии с порядком вычислений: Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 03:36 |
|
||
|
Поломалось округление Double (о черт!)
|
|||
|---|---|---|---|
|
#18+
ZVIПолагаю, что у Вас всегда так и было, просто не нарывались на пораженные точки округления. Не было, даю зуб! за один день всплыло сразу три несовпадающих документа, уж на протяжении нескольких лет я бы это отловил! С остальным поэкспериментирую, спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 10:20 |
|
||
|
|

start [/forum/topic.php?fid=60&msg=36344739&tid=2160344]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
35ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
2ms |
| others: | 251ms |
| total: | 396ms |

| 0 / 0 |
