Имя: Пароль:
1C
 
Как 1С округляет?
0 sikuda
 
05.04.24
18:09
В пятницу вечером осознал, что 1С округляет как-то странно

1/3
0.333333333333333333333333333
  123456789012345678901234567 - 27 знаков

1.1/3
0.366666666666666666666666666666666667
  123456789012345678901234567890123456 - 36 знаков

Какой-же полный алгоритм округления?
1 RomanYS
 
05.04.24
18:40
(0) округляй явно, если нужно
2 sikuda
 
05.04.24
18:55
(1) Это как получить 36 знаков для 1/3?
3 Волшебник
 
05.04.24
19:33
(0) Это смотря что Вы считаете.
4 sikuda
 
05.04.24
21:30
(3) Вот и получается, что 1С предприятие это чёрный ящик которому всё доверяют ;)
5 trdm
 
05.04.24
22:07
(4) как собственного говоря и ТЫ.
но 1С-у доверия больше.
6 Garykom
 
05.04.24
22:10
7 Garykom
 
05.04.24
22:25
Суть что числа (хранятся с фиксированной точкой) для вычислений переводятся в представление с плавающей точкой (мантисса + экспонента).
Производятся вычисления и затем обратно в фиксированную.
В итоге результат зависит от приближения в представлении с плавающей.
https://skillbox.ru/media/code/chisla-s-plavayushchey-tochkoy-chto-eto-takoe-i-kak-oni-rabotayut/
8 sikuda
 
05.04.24
23:12
(7) Насколько заметил там нет экспонентного представления. Челая часть всегда храниться полностью  а вот с дробной какие-то загадки!
9 Сергиус
 
06.04.24
03:12
(0)Для чего такая точность в учетной системе?
10 rphosts
 
06.04.24
05:01
(8) нет где? В стандарте IEEE 754 нет мантиссы?
11 sikuda
 
06.04.24
14:03
(10) Мы про храненние и работу чисел в 1С, а не про стандартв
12 Garykom
 
06.04.24
15:37
(11) Перечитай (7)
Хранятся с фиксированной
Вычисления происходят с плавающей (ибо так проще)
13 trad
 
06.04.24
17:21
(2) 1.0/3 ?
14 FIXXXL
 
07.04.24
00:04
бунтует,сцк :)
боролся с СКД на днях: Договор.Орг - есть
Договор.Контрагент - нет, красный крест
запрос - три строки, но есть расширение
15 lEvGl
 
07.04.24
09:35
(0) всегда так было, в запросах тоже самое. в прикладных задачах такой точности, которую она дает по умолчанию, обычно достаточно. другой вопрос, что буху/экономисту с калькулятором потом трудно доказать, что все нормально. она считает на машинке - выходит около того, но не в копейку
16 RomanYS
 
07.04.24
09:51
(14) Договор.Владелец?
17 Serg_1960
 
07.04.24
10:00
"Это... как получить 36 знаков для 1/3?"
1.1/3-0.1/3 = 0,333333333333333333333333333333333334
:)
18 Ненавижу 1С
 
07.04.24
10:26
(0) и вообще вы видите только текстовое представление результата, что там реально хранится так не узнать
19 Chai Nic
 
07.04.24
12:57
Чтобы повысить точность, нужно не пользоваться дробной частью при вычислениях, а вместо этого применять масштабный коэффициент в исходных данных. Считать не в рублях, а в микрокопейках, например. Или в нанокопейках. У 1с практически нет ограничения на точную длину целой части, в отличие от дробной.
20 sikuda
 
07.04.24
16:48
(19) Да соглашусь целая всегда остается сохраненной, но меня интересует точность в дробной
И так при делении, Если первый аргумент целый - 27 знаков
с 1 знака после запятой - 36 знаков
с 11 знака после запятой - 45 знаков
с 19 знака после запятой - 54 знака
с 28 знака после запятой - 63 знака
с 37 знака после запятой - 72 знака
...
Большие числа 1С рулят...
21 Гена
 
07.04.24
17:30
(20) Получается точность числителя + 35 (кроме целого). В принципе логично. Тридцать пять знаков запаса - выше крыши. Хочешь больше - добавляй в конце нули в числителе )
22 Гена
 
07.04.24
17:39
Похоже, что на диске физически добавляется место ещё для десятка цифр )
Интересно, а предел есть? )
23 RomanYS
 
07.04.24
19:02
(21) Хочешь больше - добавляй в конце нули в числителе )
1С не настолько глупа, для неё 1.000 остается целым. Цифры должны быть значащими
24 Гена
 
07.04.24
19:05
(23) Все, или последняя должна быть отлична от 0?
1.00000000000000000001
25 RomanYS
 
07.04.24
20:55
(24) последняя
26 sikuda
 
08.04.24
07:59
13.0000000000000000001/3 = 4.333333333333333333366666666666666666666666666666666667 (19->54)

13.1/3 = 4.366666666666666666666666666666666667(1->36)

13/3 = 4.333333333333333333333333333 (0->27)
27 Chai Nic
 
08.04.24
09:15
Лайфхак. Добавить в выражение коэффициент "1.{0...N нулей}1", и это задаст общую точность выражения не менее чем в N-1 знаков после запятой.
28 Chai Nic
 
08.04.24
09:23
(27) Хотя нет. Лажу какую-то считает.
Сообщить(1.0000000000000000000000000000001*(1/3));
Выдает
0,3333333333333333333333333330000333333333333333333333333333

Что это за нули в серединке?
29 sikuda
 
08.04.24
11:15
(28) Не доверяй, а проверяй
Действительно будет так и после последней цифры еще 5 нулей ;) итого 63 знака. Все сходится.
30 RomanYS
 
08.04.24
13:57
(28) Почему лажу? Ты внёс ошибку во входные данные, программа по ним посчитала результат
UPD Реально лажа. Нету смысла получать много цифр, если они неверные
31 Garykom
 
08.04.24
14:15
(28) все логично
платформа сначала посчитала 1/3 с урезанной точностью а затем умножила на 1.0000000000000000000000000000001
32 RomanYS
 
08.04.24
14:29
(31) при умножении на число больше 1 число должно было увеличиться, а оно уменьшилось.
Нет смысла увеличивать количество цифр, если они кривые

Да, (31) объясняет результат
33 Гена
 
08.04.24
14:39
(28) А если ПЕРЕД делением умножить?
(1.0000000000000000000000000000001*1)/3
34 Chai Nic
 
08.04.24
15:06
(33)
Можно каждый операнд таким образом "уточнять", умножением на 1.{0...N нулей}1  тогда и результат будет с повышенной точностью. Тут главное с большим запасом N задавать. Чтобы единичка в конце не вылезла случайно при умножении на "много".
А можно каждый операнд заменять на (операнд+0.{0...N нулей}1).
35 Djelf
 
08.04.24
15:16
Сия тайна велика есть...
ч=01.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001/3;     
сообщить(ч);
0,333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333336666666666666666666666666666666667
36 Гена
 
08.04.24
16:50
(35) Никакой тайны. 136 нулей задали точность, по которой получили 136 трёшек. А 137-я единичка добавила ещё 35 знаков для себя: шестёрки и 7 на конце.
37 Djelf
 
08.04.24
20:27
(36) Немного нарушает IEEE 754, тебе не кажется?
38 Chai Nic
 
09.04.24
07:23
(37) А кто вообще видел упоминания о "плавающей точке" в документации по 1с? Это их дело, каким образом представлять нецелые числа. Нас должна волновать лишь точность.

Плохо лишь то, что 1с, имея возможность считать и хранить числа с очень высокой точностью, при арифметических операциях эту точность загрубляет самопроизвольно по только ей известным правилам.

Было бы неплохо, если бы в глобальном контексте появился объект Арифметика, в котором было бы свойство ТочностьДесятичнойДроби, задающее минимальное число знаков после запятой, используемое в арифметических выражениях.

Да и ввести в платформу штатный механизм работы с натуральными дробями хотелось бы.
39 arsik
 
09.04.24
08:24
А вот так? 1.1/1.1/3
PS: Не так не работает
Вот так работает
(0.1/3)/0.1
40 sikuda
 
09.04.24
09:34
(38) Если смотреть на аналоги реализации Числа в 1С то это BigDecimal (Java) или bc Math (PHP) и там действительно есть понятие scale или точности.

А что вы подразумеваете под натуральными дробями и есть ли аналоги в других языках?
41 Гена
 
09.04.24
09:44
(40) Предположу, что это именно что работа с рациональными числами, которые по определению имеют вид дроби Z/N, где Z - целые числа, а N - натуральные.
42 Гена
 
09.04.24
09:46
Понятно, что частное от деления двух рациональных чисел есть тоже число рациональное, за исключением деления на ноль, естественно.
43 Chai Nic
 
09.04.24
10:47
(40) Натуральная дробь это объект, содержащий целое, числитель и знаменатель. Вот был у меня калькулятор МК-71, он мог считать в натуральных дробях по правилам дробной арифметики. С нахождением НОЗ, сокращением и нормализацией и т.п.. И только в том случае, когда невозможно обеспечить точную натуральную дробь из-за нехватки знаков, происходило преобразование в десятичную дробь с округлением.
44 sikuda
 
09.04.24
11:32
(43) Да калькуляторы знаю, еще специализированный софт (Mathematic, R) но получается при больших расчетах слишком накладно тащить полные дроби и формулы. Да еще константы с безумной точностью.