Имя: Пароль:
1C
1С v8
Округление больших ("длинных") чисел, большим количеством знаков после запятой.
0 DjMah
 
02.03.16
09:01
Всем приветы.
Столкнулся с проблемкой:
После определенных вычислений получается ооочень длинное число с большим количеством знаков после запятой. Результат округления стандартным способом до двух знаков получается не верным (из 100% в каких то вычислениях получается 92%, в каких-то 109%).
Подскажите способ.
Есть вариант делать округление с последнего знака в числе, и так до ножного разряда округлять.
Может есть какой-нить способ попроще?
Заранее спасибо, всех с весной и с раздевающимися девушками.
1 Lama12
 
02.03.16
09:01
(0)Пример пожалуйса.
2 DjMah
 
02.03.16
09:02
1,23704159
1,70538824
1,827494366
0,580618726
0,580618726
0,580618726
1,234992829
1,671788568
1,843064946
0,858020897
1,234992829
0,842040565
0,842040565
3 DjMah
 
02.03.16
09:03
(1) Все не стал приводить числа, но вот такие результаты получаются.
Это число в процентах из 100% возможных.
4 lubitelxml
 
02.03.16
09:04
(3) что сделать то надо?
5 LordCMEPTb
 
02.03.16
09:04
(0) Как вариант, можно сначала производить расчеты, а затем округлять полученное число, а не округлять числа сначала, а затем производить расчеты.
6 Lama12
 
02.03.16
09:07
В результатах округления получается так?
1,24
1,71
1,83
0,58
0,58
1,23
1,67
1,84
0,86
1,23
0,84
0,84
Это классическое математическое округление.
Округлять с последнего знака в числе - глупо. Может набежать статистическая ошибка намного превышающая погрешность при классическом округлении.
Есть еще финансовые и другие виды округлений. Какой нужен?
7 DjMah
 
02.03.16
09:07
(4) Округлить каким-то способом, чтобы вот такие числа в сумме дали результат, как можно ближе к 100.
Сейчас получаются расхождения большие.

(5) У меня так и есть. Сначала расчеты, потом округление.
8 DjMah
 
02.03.16
09:09
(6) Да, такие получаются.
Я не слышал про другие виды округлений (простите за необразованность)
Нужен вариант который даст на выходе более точный результат.
9 Lama12
 
02.03.16
09:11
(7) Похоже я не совсем понял задачу. Смущают проценты. Правильно ли я понимаю что сумма полученного результата из (6) сравнивается с суммой из (2)?
10 ЧеловекДуши
 
02.03.16
09:12
(0) Округляй до 10-ти значков. В итоге округляй до 2-ух.
В общей картине получишь погрешность 0.01.
11 ЧеловекДуши
 
02.03.16
09:13
(6) Классический ...-изм округления и попыткой удивляться откуда разница :)
12 ЧеловекДуши
 
02.03.16
09:15
(7) Можно округлить вообще, что бы было 100.
Последний процент подгоняешь под 100, если он превышает :)
13 ЧеловекДуши
 
02.03.16
09:17
Вот любопытно, с каких пор процент можно складывать? :)
14 DjMah
 
02.03.16
09:17
(9) Хммм...
Это все результат расчета процентов из 100.
Грубо говоря, количество (процентов) голосов, зависимых от жилплощади по отношению к общей площади здания.
(12) Подгонять последний - айайайай!! =))
15 эксвилл
 
02.03.16
09:20
(8) Округление - это уменьшение точности. По определению. Если нужна большая точность - не округляй.
16 LordCMEPTb
 
02.03.16
09:25
(7) Не совсем понял, т.е. сумма чисел из (2) должна стремиться к 100, но она не получается, потому что какое-то округление числа дает от 0.92 до 1.09? Может дело в том, что исходные данные не подразумевают в сумме давать 1?
17 Lama12
 
02.03.16
09:25
(14) Понятно. Обычно поступаю двумя способами.
1. Распределяю накопившуюся погрешности пропорционально величине значения из конечного множества. Т.е. в нашем случае всю погрешность можно кинуть на величины 1.86, 1.83, 1.71 и т.д. в зависимости от паранои (можно только на 1.86).
2. Распределить округленные величины использовать как показатели доли для распределения первоначальной суммы алгоритмом пропорционального распределения (в УПП мне очень понравился алгоритм).
18 DjMah
 
02.03.16
09:28
(15) Я не спорю. Нужно чтобы это уменьшение было как можно меньше (простите за тавтологию))
Сложно сформулировать, дефчонки забили все сознание.
(16) в (2) только пример чисел из которых должно получится 100, но в результате округления 100 не получается =))
(17) Спасибо, попробую второй способ применить.
19 Lama12
 
02.03.16
09:30
(18)Это алгоритм...
// Процедура арифметически распределяет заданную сумму
// по столбцу таблицы значений пропрционально колонке базы распределения
// при этом размерность таблицы и базы распределения должны совпадать.
// Как правило база распределения - просто одна из колонок таблицы
Процедура РаспределитьСуммуПоСтолбцу(МассивБазыРаспределения, РаспределяемаяСумма, ТаблицаРезультата, ИдКолонкиРезультата) Экспорт

    // Определяем сумму базы
    СуммаБазы = 0;

    Для Индекс = 0 По МассивБазыРаспределения.Количество() - 1 Цикл
        СуммаБазы = СуммаБазы + МассивБазыРаспределения[Индекс];
    КонецЦикла;

    Если СуммаБазы > 0 Тогда
        // Выполняем распределение
        УчтеноБазыРаспределения = 0;
        УжеРаспределено = 0;

        Для Индекс = 0 По МассивБазыРаспределения.Количество() - 1 Цикл

            // Рассчитываем шаг распределения
            ШагРаспределения = Окр(РаспределяемаяСумма * (УчтеноБазыРаспределения + МассивБазыРаспределения[Индекс])/СуммаБазы, 2) - УжеРаспределено;

            // Записываем результат
            ТаблицаРезультата[Индекс][ИдКолонкиРезультата] = ШагРаспределения;

            // Учитываем полученный результат для вычисления последующих шагов распределения
            УчтеноБазыРаспределения = УчтеноБазыРаспределения + МассивБазыРаспределения[Индекс];
            УжеРаспределено         = УжеРаспределено + ШагРаспределения;

        КонецЦикла;

    КонецЕсли;

КонецПроцедуры // РаспределитьСуммуПоСтолбцу()
20 Serg_1960
 
02.03.16
09:32
Имхо, у автора классическая безнадёжная попытка поймать копейку в ведомости с "ИТОГО" - сумма округлений значений не равна округлению суммы значений :)
21 DjMah
 
02.03.16
09:33
(19) Спасибо! Попробую сейчас.
(20) Я не пытаюсь поймать копейку, я лишь спросил как можно уменьшить погрешность при округлении длинных чисел.
22 batman69
 
02.03.16
09:41
(21) А может вам и не нужно округлять, вы работайте с числом "1,234992829 ", а пользователю показывайте "1,24", ему достаточно для понимания процента.
23 Serg_1960
 
02.03.16
10:27
Мас = Новый Массив(); // массив исходных значений
    Мас.Добавить(1.23704159);
    Мас.Добавить(1.70538824);
    Мас.Добавить(1.827494366);
    Мас.Добавить(0.580618726);
    Мас.Добавить(0.580618726);
    Мас.Добавить(0.580618726);
    Мас.Добавить(1.234992829);
    Мас.Добавить(1.671788568);
    Мас.Добавить(1.843064946);
    Мас.Добавить(0.858020897);
    Мас.Добавить(1.234992829);
    Мас.Добавить(0.842040565);
    Мас.Добавить(0.842040565);
    
    Сум = 0; // сумма исходных значений
    Для Каждого х Из Мас Цикл
        Сум = Сум + х;
    КонецЦикла;
    
    Итого = 100; // планируемый результат
    к1 = 0; к2 = 0; // для учета погрешностей распределения
    Для х = 0 По Мас.Количество() - 1 Цикл
        Врм = Окр((Мас[х] + к1) * Итого / Сум, 2) - к2; // расчет значений распределения
        к1 = к1 + Мас[х];
        к2 = к2 + Врм;
        Мас[х]=Врм; // значение распределения
    КонецЦикла;
    
    Для х = 0 По Мас.Количество() - 1 Цикл
        Сообщить(Мас[х]); // показ для самопроверки
    КонецЦикла;
    Итого = 0; // фактический результат
    Для Каждого х Из Мас Цикл
        Итого = Итого + х;
    КонецЦикла;
    Сообщить(Итого); // показ для самопроверки

    Возврат;
24 Мэс33
 
02.03.16
10:31
(0) как сказали выше - везде работаете с точными данными (9 знаков после запятой как я понял).

Округляете в самом конце.
25 Мэс33
 
02.03.16
10:31
(24) а разницу - в карман
26 LordCMEPTb
 
02.03.16
10:32
(18) Понятнее не стало.
Если есть 3 числа:
0.33333
0.33333
0.33334
То в сумме они дают 1. Как ни округляй.
Но если их сначала округлить до 2 знаков, а затем сложить, то получим 0.99, а не 1.

Потому, если числа должны давать 100%, а не дают, то надо либо складывать исходные числа, а затем округлять, либо увеличивать каждое число на определенный коэффициент, чтобы подогнать общую сумму к 100%.
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс