|
непонятки с округлением
|
|||
---|---|---|---|
#18+
День добрый. запускаю скрипт: Код: plaintext 1. 2. 3. 4. 5.
Код: plaintext
проверяю вручную в командном окне фокса: Код: plaintext 1.
Vfp9 ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 15:00 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
quxix, Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 15:10 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
AmKadquxix, Код: plaintext 1.
? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 15:26 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
AmKad, Это на всякий случай, что округление суммы и округление слагаемых не одно и тоже :) Как-то сталкивался с такой проблемой, только вот сейчас не помню как вышел из такой ситуации. Я бы начал с того что поигрался бы с настройками сделать Set Decimals to и поставить значение большее 2. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 15:34 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
quxix, Жаль что фокса нет под рукой, так бы сам попробовал :) ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 15:39 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
AmKadAmKad, Это на всякий случай, что округление суммы и округление слагаемых не одно и тоже :) Как-то сталкивался с такой проблемой, только вот сейчас не помню как вышел из такой ситуации. Я бы начал с того что поигрался бы с настройками сделать Set Decimals to и поставить значение большее 2. Про округление суммы и округление суммы слагаемых и так ясно :) Вопрос по работе фокса. Из Help: Команда SET DECIMALS определяет минимальное количество отображаемых десятичных знаков Поигрался.При увеличении порог уменьшается->выходим раньше. Интересует,округление только до двух десятичных. *** Поигрался на oracle на интервале до 100000-всё пучком нигде не выбрасывает. Так что, что-то с непониманием настроек фокса,кто бы указал ... ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 16:04 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
quxix Команда SET DECIMALS определяет минимальное количество отображаемых десятичных знаков Поигрался.При увеличении порог уменьшается->выходим раньше. Если из цикла выходит раньше ввиду того что поменяли set decimals, может быть и стоит не нее обратить внимание? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 16:24 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
сделай так Код: plaintext 1. 2. 3. 4. 5. 6. 7.
его плючит, когда-то проскакивала информация, сейчас лень искать ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 16:36 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
Вы путаете понятия "хранение числа" и "отображение числа". Ваша ошибка в том, что Вы считатете, что число s в момент срабатывания условия ТОЧНО равно значению 18593.25. На самом деле это не так. В памяти компьютера оно представлено приблизительно Добавьте Вашу проверку еще одной строчкой Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
Вы увидите, что в момент возникновения проблемы значение s = 18593,24999996 Приблизительно это число действительно равно 18593,25, но на самом деле, разумеется, отличается. Соответственно, при сравнении будет 21940,02999996 <> 21940,03 Причина заключается в том, что действительные числа, физически хранятся в памяти FoxPro в виде бинарных (двоичных) данных. Другими словами, они представлены в памяти FoxPro как число по основанию 2. А точно перевести дробное число по основанию 10 в число по основанию 2 - невозможно. Для решения проблемы, Вам надо либо работать с целыми числами и только результат делить на 100, либо округлять значение s перед выполнением операции Код: plaintext 1. 2. 3. 4. 5. 6.
Или Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 16:48 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
Да, без Dislpay Memory можно так Код: plaintext 1. 2. 3. 4. 5. 6. 7.
Т.е. не доверять автоматическому преобразованию числа в строку, а явно указать, что надо отобразить столько десятичных символов, сколько возможно. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2010, 16:53 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
ВладимирМ, спасибо за подробное разъяснение. Скажите, а почему настройка SET DECIMALS TO -влияет на результат вычисления,в первоночальном скрипте, если я правильно понял, то настройка должна влиять лишь на отображение числа. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2010, 13:20 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
quxixСкажите, а почему настройка SET DECIMALS TO -влияет на результат вычисления,в первоночальном скрипте, если я правильно понял, то настройка должна влиять лишь на отображение числа. Не знаю. Теоретически, не должна, хотя на практике это есть Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Если посмотреть на результат теста, то видно, что выход из цикла происходит в зависимости от того, на какой позиции заканчиваются цифры 9 в значении у функции ROUND(). Чем меньше значение SET DECIMALS, тем меньшее количество девяток необходимо. Тем позднее происходит вылет из цикла. Грубее сравнение. Например, для SET DECIMALS TO 2 имеем Код: plaintext 1. 2. 3. 4. 5.
Другими словами, если число равно 0,004999990, то оно округляется до 0,01, а если 0,004999900 (на одну девятку в конце меньше), то оно округляется до 0,00. Причем значение цифры после последней учитываемой девятки значение не имеет. Важно только, чтобы все учитываемые цифры после 4 были именно девятками. Чем больше настройка SET DECIMALS, тем бОльшее количество девяток учитывается при подобном бухгалтерском округлении. Тем раньше происходит вылет при сравнении, поскольку разница фактически становится равной 0.01 В принципе, такого быть не должно. В смысле, работа ROUND() не должна зависеть от SET DECIMALS. Однако, как видно из примера, зависит... Впрочем, все это происходит на пределе точности расчета FoxPro (до 16 значащих цифр). Так что, думаю, погрешность вполне допустимая. -------------------------------------------------------------------------------------------- Если нужны точные расчеты сумм, то лучше вместо полей типа Numeric использовать поле типа Currency, поскольку физически оно хранится как целоей число. Соответственно, нет погрешностей при переводе в двоичное представление. Преобразование NTOM() как раз и переводит число типа Numeric в число типа Currency. И уже тот же самый цикл никаких ошибок не покажет Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Однако следует иметь в виду, что математические операции с типом Currency дают точность не выше 4 значащих цифр после запятой. По правилам математики это значит, что 4 цифра - не достоверная, 3 - сомнительная. Т.е. доверять можно будет только первым 2 цифрам после запятой (до копейки). Также следует помнить, что если тип данных константы не будет задан явно, то дробные числа FoxPro интерпретирует как числа с типом Numeric. Как уже видели, прямое сравнение Numeric и Currency может дать парадоксальный результат из-за особенностей хранения в памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2010, 15:42 |
|
непонятки с округлением
|
|||
---|---|---|---|
#18+
Если интересно, то вот по этой ссылке http://forum.foxclub.ru/read.php?29,401694,page=1 Было обширное обсуждение аналогичной ошибки в функции INT(). А вот здесь http://support.microsoft.com/kb/78113/ru Статья от Microsoft с описанием того, почему арифметические операции над числами с плавающей точкой могут быть не точными. Там про Excel, но в FoxPro в отношении Numeric все то же самое ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2010, 16:23 |
|
|
start [/forum/topic.php?fid=41&tid=1585692]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
38ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 151ms |
0 / 0 |