02.07.2021, 11:40 | #1 |
Участник
|
Поле "XXX" (= -0,000) может содержать только положительные числа
dax2012 R3
Поле имеет свойство AllowNegative = No. Т.е. запрет отрицательных значений X++: ttsbegin; qty = ( ); // здесь расчет значения qty = decRound(qty, 3); myTab.MyField = qty; if (myTab.MyField < 0) throw error('Отрицательное значение'); if (myTab.validateWrite()) { myTab.update(); } ttscommit; Иногда! При выполнении этого кода в пакете получаю указанную в названии темы ошибку Цитата:
Поле "XXX" (= -0,000) может содержать только положительные числа
Причем ошибка именно при работе в пакете. Если запускать обработку без пакета, то ошибка ни разу не возникала. Как следствие, сделать корректный тестовый пример для воспроизведения ошибки не получается. Просто не могу поймать, когда она возникает Пока обошел проблему вот так X++: ttsbegin; qty = ( ); // здесь расчет значения qty = decRound(qty, 3); // Если в результате расчет ноль, то явно указать ноль if (qty == 0) { qty = 0; } myTab.MyField = qty; if (myTab.MyField < 0) throw error('Отрицательное значение'); if (myTab.validateWrite()) { myTab.update(); } ttscommit;
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
02.07.2021, 12:21 | #2 |
Участник
|
Я не сталкивался, но есть догадка почему так получилось.
В X++ все real переменные - это BCD (binary coded decimals) поэтому там такой проблемы не возникает. А при выполнении в пакете работает CIL Там скорее всего используется какой-нибудь System.Double который годится для научных расчетов, но не очень для финансовых как раз из-за проблемы с округлениями. Можно для Excel построить простой пример когда в одном столбце попеременно вводится порядка 30 положительных и отрицательных целых чисел так что их сумма 0. Excel в итоге покажет сумму 1.0+e15 или -1.0+e15 Это та же проблема. Попробуйте просто в пакете своем поставить округление через X++ функции round или decRound Или если речь о деньгах, то по феншую заюзать Currency::Amount() или Currency::Price() Последний раз редактировалось Logger; 02.07.2021 в 12:24. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (2). |
02.07.2021, 12:26 | #3 |
Участник
|
пример
https://www.excel-vba.ru/chto-umeet-...itaet-pochemu/ Цитата:
Спасибо автору за разъяснения. Обнаружил ошибку при сравнении разности с числом, довел ситуацию до абсурда и выяснил, что в Excel 2013 ошибка возникает при действии с числами начиная с четвертого знака после запятой в 17-м знаке, хотя номер знака при сравнении разности с нулем не имеет значения
A B C A-B-C 1,3000000000 1,1000000000 0,2000000000 0,00000000000000000000 1,0300000000 1,0100000000 0,0200000000 0,00000000000000000000 1,0030000000 1,0010000000 0,0020000000 0,00000000000000000000 1,0003000000 1,0001000000 0,0002000000 -0,00000000000000002204 1,0000300000 1,0000100000 0,0000200000 -0,00000000000000009102 1,0000030000 1,0000010000 0,0000020000 0,00000000000000005751 Цитата:
1000003 1000001 2 0,000000000116415321826935000000
Последний раз редактировалось Logger; 02.07.2021 в 12:42. |
|
02.07.2021, 13:59 | #5 |
Участник
|
Несколько мест в DAX2012 видел где real прямо приводится к net double и в некоторых комментарии про ошибки округления в CIL.
Вот, навскидку пример: метод price2Amount класса PriceDisc X++: // As the precision are different between data type "Real" in X++ and "Decimal" in IL, it may result in rounding defference when // running X++ and IL. To resolve this issue, we convert "Decimal" to "Double" here if the code was running in IL, thus there is // a precision down, and the precission will extremely like data type "Real" in X++. if (xSession::isCLRSession()) { returnAmount = System.Convert::ToDouble(returnAmount); } |
|
|
За это сообщение автора поблагодарили: Владимир Максимов (5), S.Kuskov (2). |
Теги |
dax2012 |
|
|