|
Есть ли в 1с нормальный способ записать число обыкновенной дробью (числ/знам)? | ☑ | ||
---|---|---|---|---|
0
cube033
21.01.15
✎
06:22
|
8.3 Управляемое приложение.
Понятно, что можно разобрать число в строку. А потом, при необходимости собрать обратно. Но может кто находил стандартный способ? |
|||
1
Рэйв
21.01.15
✎
06:23
|
5/100
чем не устраивает? |
|||
2
igoza
21.01.15
✎
06:46
|
Формат("ЧРД=/")
|
|||
3
igoza
21.01.15
✎
06:47
|
"Текст" -> "Конструктор форматной строки..."
http://programmist1c.ru/st_programming/format-funkcija-formatirovanija-znachenij.html |
|||
4
Ненавижу 1С
гуру
21.01.15
✎
06:50
|
А мне кажется, что проблема больше хранения и преобразования в арифметики 1/2+1/3=5/6
|
|||
5
cube033
21.01.15
✎
07:10
|
(1) чем меня не устраивает конкретно, когда люди делят 5 на 100?
Чтобы было понятно: задача превратить при выводе в отчет "19,2" в "19 1/5". Хоть и криво как-то выглядит, ну или на худой конец 96/5 (2) Получится "19/2" (3) Только там нет ответа (4) Если есть алгоритм перевода в дробь, то можно слогаемые поделить как есть, а сумму снова перевести в дробь.Точность конечно потеряется. Но мы хоть как теряем точность при выводе данных пользователю, даже в десятичных дробях(округляем). Алгоритм я составил. Но может есть таки штатный функционал. |
|||
6
sda553
21.01.15
✎
07:12
|
Структура[числитель]=2;
Структура[знаменатель]=5; |
|||
7
ifso
21.01.15
✎
07:21
|
(5)
> можно слогаемые поделить как есть о5 получатся десятичные или в чем фишка? |
|||
8
Asmody
21.01.15
✎
07:21
|
(6) и реализовать арифметику
|
|||
9
cube033
21.01.15
✎
07:23
|
(6)(8) Не понял идеи. Вот у меня есть чило 19.2, которое мне нужно вывести в отчет как правильную обыкновенную дробь.
И тут: "Структура[числитель]=2; Структура[знаменатель]=5; и реализовать арифметику" |
|||
10
Asmody
21.01.15
✎
07:27
|
(9) напиши функцию, которая будет для числа возвращать Структура(Целое, Числитель, Знаменатель)
|
|||
11
cube033
21.01.15
✎
07:36
|
(7) 1/2+1/3=5/6
"> можно слогаемые поделить как есть" 0,5 + 0.33(потеря точности) = 0,83 "а сумму снова перевести в дробь" 83/100 (выразительность числа будет зависеть от округления(в ущерб точности). 0,5+0,3 = 0,8 = 8/10 = 4/5) Это ответ на "проблема больше хранения и преобразования в арифметики" - вот в чем фишка. Ахранение меня пока не сильно заботит, так как это формат вывода данных в отчет. (10) речь идет о выводе через СКД кстати. Алгоритм есть: Числитель = Дробная часть исходного числа, знаменатель = 1. Умножаем числитель и знаменатель на 10, пока не избавимся от дробной части числителя. Дальше пробуем делить числитель и знаменатель на "индекс от 2 до Числитель цикл" и так пока делится. Но в СКД это не очень удобно. |
|||
12
Лодырь
21.01.15
✎
07:45
|
(11) А с какой точностью вы хотите вычислять дроби?
|
|||
13
Лодырь
21.01.15
✎
07:46
|
Или например, захочет у вас 1С в отчете вывести иррациональное число, что будете делать?
|
|||
14
IUnknown
21.01.15
✎
07:48
|
(11)как-то через анус ты дробь переводишь ... находишь наибольший кратный делитель и имеешь счастье
|
|||
15
ifso
21.01.15
✎
07:55
|
(11) угу, идея понятна
но, если в рассмотренном примере в обоих случаях округлять с одинаковой точностью, то и разница нивелируется, не ? |
|||
16
Asmody
21.01.15
✎
07:56
|
(13) Не захочет. На 1С реализовать иррациональное число невозможно.
|
|||
17
Лодырь
21.01.15
✎
08:01
|
(16) Ок, выведет ему ктонибудь тридцатизначное число деленое на тридцатизначное. что он захочет показать? явно не то что надо. а захочет чтонибудь в стиле 45/100 или 36/50. Если сделать предположение, что теоретически можно не полениться и построить вычисляемое поле по попаданию в интервал.
|
|||
18
IUnknown
21.01.15
✎
08:04
|
0.333
(16)кстати а как сейчас просить создать персональную ветку и создают их или нет? |
|||
19
IUnknown
21.01.15
✎
08:04
|
(17)чего?
|
|||
20
Лодырь
21.01.15
✎
08:05
|
(19) того.
|
|||
21
IUnknown
21.01.15
✎
08:06
|
(20)"Если сделать предположение, что теоретически можно не полениться и построить вычисляемое поле по попаданию в интервал" вот под этим, что ты имел ввиду?
|
|||
22
Rebelx
21.01.15
✎
08:07
|
(0) задача элементарная
целая часть - вроде трудностей нет дробная - для числителя и знаменателя дробной части находим наибольший общий делитель и делим все |
|||
23
Лодырь
21.01.15
✎
08:09
|
(22) Подразумевалось, что мы строим разбиение интервала (0;1) на полуинтервалы (х;y] каждому которому ставим в соответствие дробь. И используем это в СКД при выводе.
|
|||
24
Лодырь
21.01.15
✎
08:10
|
тьфу. (23) к (21) а не (22)
|
|||
25
IUnknown
21.01.15
✎
08:11
|
(23)зачем?
|
|||
26
Ненавижу 1С
гуру
21.01.15
✎
08:12
|
(13) с иррациональными вообще засада в компьютерах
и с человекопредставлением их тоже |
|||
27
Лодырь
21.01.15
✎
08:16
|
(25) это надо спрашивать у топикстартера. это ему надо было такое представление.
|
|||
28
VladZ
21.01.15
✎
08:17
|
(0) К чему такие извращения?
|
|||
29
VladZ
21.01.15
✎
08:20
|
По-хорошему, нужно вводить новый тип данных. И писать под него "арифметику". Но таких возможностей в 1С нет. Можно выпендриться через Структуру.
Таким же способом можно реализовать комплексные числа. Но не понятно, зачем это нужно. |
|||
30
VladZ
21.01.15
✎
08:21
|
(4) Да и это все решаемо.
|
|||
31
Ненавижу 1С
гуру
21.01.15
✎
08:25
|
мне кажется у автора все проще
есть число фиксированной точности, например 3 знака после запятой: 1.235 и ему его надо представлять в виде 1235/1000 то есть: Формат(Ч,"ЧС=-3; ЧГ=0")+"/1000" как прописать только в функции формат я не понял |
|||
32
IUnknown
21.01.15
✎
08:25
|
(239)ему надо из 0.45 сделать 1/3 ... непонятно, для чего там какие-то графики строить
|
|||
33
IUnknown
21.01.15
✎
08:25
|
(31)формат ему не подходит, он говорил ...
|
|||
34
IUnknown
21.01.15
✎
08:26
|
надо упростить дробь
|
|||
35
VladZ
21.01.15
✎
08:27
|
(5) Нужно разработать функцию перевода десятичной дроби в обыкновенную. Дерзай! :)
|
|||
36
cube033
21.01.15
✎
08:53
|
(33) формат подходит. Просто нужного формата не нашел
|
|||
37
IUnknown
21.01.15
✎
09:04
|
то есть
0.34565656756 преобразовать в 34565656756/100000000000 тебя вполне устраивает? |
|||
38
cube033
21.01.15
✎
09:11
|
(31) идея интересная. Более того задачи свелась к разрядности 1/10. Тогда Формат("ЧРД= ")+"/10". Но далее это текстовое значение не сможет правильно вычисляться в группировках. Да и на практике пока не понятно как в СКД выполнять такого рода конкатенацию.
(37)В моем случае 0.34565656756 будет 3/10 и да - это достаточно. Но 0.35465656756 будет 4/10, а этого будет не достаточно. |
|||
39
cube033
21.01.15
✎
09:18
|
"формат подходит. Просто нужного формата не нашел" - Я имею ввиду - идеальным решением было бы нахождение формата при котором 1С делала бы работу за нас.Типа Формат(2,345,"СуперМегаИдеальныйФормат=2") = 2 17/50
|
|||
40
cube033
21.01.15
✎
09:40
|
Обращение десятичной дроби в обыкновенную
Вот еще обсуждение |
|||
41
НЕА123
21.01.15
✎
09:54
|
Стр = СтрЗаменить(Формат(а,"ЧРД=.; ЧН=; ЧГ=0"),Символы.ПС);
Рез = Формат(ПолучитьСТроку(Стр,1),"ЧН=; ЧГ=0"); Если СтрЧислоСтрок(Стр)=2 Тогда Р |
|||
42
НЕА123
21.01.15
✎
09:58
|
все не читал
Стр = СтрЗаменить(Формат(а,"ЧРД=.; ЧН=; ЧГ=0"),".",Символы.ПС); Рез = Формат(ПолучитьСТроку(Стр,1),"ЧН=; ЧГ=0"); Если СтрЧислоСтрок(Стр)=2 Тогда Рез = Рез+" "+Формат(ПолучитьСТроку(Стр,2),"ЧН=") + "/1" + Лев("0000000000000000000000",СтрДлина(ПолучитьСТроку(Стр,2)); КонецЕсли; |
|||
43
IUnknown
21.01.15
✎
09:59
|
(40)там и решения есть)
|
|||
44
НЕА123
21.01.15
✎
10:05
|
(42)+
* ПолучитьСтроку = СтрПолучитьСтроку обратно стр = СтрЗаменить(Рез," ", Символы.ПС); Число = Вычислить(СтрПолучитьСТроку(Стр,1) + ?(СтрЧислоСтрок(Стр)=2, "+"+СтрПолучитьСТроку(Стр,2),"")) |
|||
45
cube033
21.01.15
✎
10:32
|
(43) Да такие решения не сложно придумать. Там задача более математическая что ли. С одной стороны мой пример проще: мне не нужно преобразовывать число обратно. Мне не нужны приближения и отклонения. С другой стороны у меня есть серьезное осложнение, которое отбривает предложеннные решения - СКД.
По сути можно выделить 5 стадий формирования значения в скд 1. Получение набора данных 2. Вычисляемые поля 3. Ресурсы 4. Настройки (Условное оформление) 5. Макет (формат, шаблон) Поэтому я и спрашивал - нет ли формата нужного. Теперь понимаю что нет. Я бы уже готов был в шаблоне макета приписать "/10", но вопрос в том, что не всегда значения будут дробными или вообще заполнеными. В условном оформлении можно задать текст, но вроде нельзя его приплюсовать. |
|||
46
cube033
21.01.15
✎
11:14
|
Самый верный путь, как мне кажется - копать в сторону ресурсов. Допустим вот такая формула приписывает "/10" всем ячейкам, но игнорирует формат.
Выбор когда Сумма(Количество) = 0 Тогда 0 Иначе Выразить(Формат(Сумма(Индекс)/Сумма(Количество),"ЧДЦ=1; ЧРД=; ЧН=0; ЧГ="), "Строка") + "/10" Конец |
|||
47
quest
21.01.15
✎
11:23
|
sicp первая или вторая глава это обсуждается
|
|||
48
braslavets
21.01.15
✎
11:27
|
(0) Ну, если точность ограничить - завести рег.сведений, измерение - дробная часть, ресурс - строковое представление в виде "а/б". Один раз заполнить, а дальше просто выцеплять из него.
|
|||
49
ifso
21.01.15
✎
11:41
|
может быть все-таки стОит изначально определиться с требуемой точностью и спокойно юзать "классику", не ?
|
|||
50
cube033
21.01.15
✎
11:47
|
(47) 1.2.5. Нахождение наибольшего общего делителя
По определению, наибольший общий делитель (НОД) двух целых чисел a и b — это наибольшее целое число, на которое и a, и b делятся без остатка. Например, НОД 16 и 28 равен 4. В главе 2, когда мы будем исследовать реализацию арифметики на рациональных числах, нам потребуется вычислять НОДы, чтобы сокращать дроби. (Чтобы сократить дробь, нужно поделить ее числитель и знаменатель на их НОД. Например, 16/28 сокра- щается до 4/7.) Один из способов найти НОД двух чисел состоит в том, чтобы разбить каждое из них на простые множители и найти среди них общие, однако существует знаменитый и значительно более эффективный алгоритм. Этот алгоритм основан на том, что если r есть остаток от деления a на b, то общие делители a и b в точности те же, что и общие делители b и r. Таким образом, можно воспользоваться уравнением НОД(a, b) = НОД(b, r) чтобы последовательно свести задачу нахождения НОД к задаче нахождения НОД все 41Это упражнение нам предложил Джо Стойна основе примера из Kaldewaij 1990.1.2. Процедуры и порождаемые ими процессы 63 меньших и меньших пар целых чисел. Например, НОД(206, 40) = НОД(40, 6) = НОД(6, 4) = НОД(4, 2) = НОД(2, 0) = 2 сводит НОД(206, 40) к НОД(2, 0), что равняется двум. Можно показать, что если на- чать с произвольных двух целых чисел и производить последовательные редукции, в конце концов всегда получится пара, где вторым элементом будет 0. Этот способ нахож- дения НОД известен как алгоритм Евклида (Euclid’s Algorithm) Интересно, но всё не то. Надо 1С и СКД, а не математику) |
|||
51
cube033
21.01.15
✎
11:50
|
(48) Есть извращения и попроще Выбор когда Число%1 = 0.1 Тогда 1/10 когда Число%1 = 0.2 Тогда 1/5 .....
|
|||
52
cube033
21.01.15
✎
11:50
|
(49) Определился! Точность 1!!! Что за классика??!
|
|||
53
cube033
21.01.15
✎
13:10
|
Ап. Нет мастеров СКД?
|
|||
54
ifso
21.01.15
✎
15:00
|
(52) "классика" - десятичные )
|
|||
55
mooo
21.01.15
✎
15:14
|
(53) В общем модуле реализовать функцию "ПредставитьЧислоДробью()", в схеме у поля задать выражение представления.
|
|||
56
cube033
22.01.15
✎
05:20
|
(54) Я вот тоже боюсь, с точностью 1 знак после запятой - обыкновенные дроби читаемость отчета никак не повысят.
(55) Тема не распространенная, но интересная. Говорят только в ресурсах можно пользоваться. |
|||
57
cube033
22.01.15
✎
07:27
|
(55) Спасибо. В итоге вопрос РЕШЕН. Кто будет искать решение - Вот оно.
1.Создаем (или используем гтовый) общий модуль со свойствами: глобальный, сервер, внешнее соединение, вызов сервер. 2.Создаём Экспортную функцию. (в моем случае перевода в дробь нет, но это самое простое. Куча способов описана в этой теме и в теме по ссылке (40)). Функция ПолучитьДробьСтрокой(ЧислоВходящее) Экспорт Если ТипЗнч(ЧислоВходящее) = Тип("Null") Тогда Возврат Null; КонецЕсли; ДробнаяЧасть = ЧислоВходящее - Цел(ЧислоВходящее); Если ДробнаяЧасть = 0 тогда Возврат Строка(ЧислоВходящее); КонецЕсли; ДробнаяЧасть = Окр(ДробнаяЧасть,1); ЦелаяЧастьСтрока = ?(Цел(ЧислоВходящее) = 0,"",Строка(Цел(ЧислоВходящее))); Если ДробнаяЧасть = 0 Тогда Возврат ЦелаяЧастьСтрока; ИначеЕсли ДробнаяЧасть = 0.1 Тогда Возврат ЦелаяЧастьСтрока + " 1/10"; ......................................... ИначеЕсли ДробнаяЧасть = 0.9 Тогда Возврат ЦелаяЧастьСтрока + " 9/10"; ИначеЕсли ДробнаяЧасть = 1 Тогда Возврат Строка(Цел(ЧислоВходящее+1)); КонецЕсли; КонецФункции 3. В Схеме компоновки данных, на вкладке ресурсы берем выражение (например: Сумма(ХорошиеЧисла)/Сумма(ПлохиеЧисла)) и передаем его параметров, вызывая свою функцию "ПолучитьДробьСтрокой(Сумма(ХорошиеЧисла)/Сумма(ПлохиеЧисла))" Работает в файловом и серверном режимах. |
|||
58
VladZ
22.01.15
✎
08:00
|
ИначеЕсли ДробнаяЧасть = 0.1 Тогда
Возврат ЦелаяЧастьСтрока + " 1/10"; ......................................... ИначеЕсли ДробнаяЧасть = 0.9 Тогда Возврат ЦелаяЧастьСтрока + " 9/10"; ИначеЕсли ДробнаяЧасть = 1 Тогда ЫЫЫЫ... Эту часть можно было сделать и по-красивее. Раз у тебя точность 1 знак. Берем этот знак и делаем так: ПоследнийСимволСтрокой + "/10". И накаких тебе лестниц с "ИначеЕсли" не нужно. В целом: не нравится мне идея с округлением. Теряется часть инфы. |
|||
59
DrZombi
гуру
22.01.15
✎
08:02
|
(57) Шот там не то. Ты если взялси, то пили до конца.
А так, спасибо, но мы как нить обычным двоичным исчислением ограничимси :) |
|||
60
cube033
22.01.15
✎
08:04
|
(58) ЫЫЫ Ты же не думаешь, что я пропустил 2/10,3/10 итд))
Если ДробнаяЧасть = 0 Тогда Возврат ЦелаяЧастьСтрока; ИначеЕсли ДробнаяЧасть = 0.1 Тогда Возврат ЦелаяЧастьСтрока + " 1/10"; ИначеЕсли ДробнаяЧасть = 0.2 Тогда Возврат ЦелаяЧастьСтрока + " 1/5"; ИначеЕсли ДробнаяЧасть = 0.3 Тогда Возврат ЦелаяЧастьСтрока + " 3/10"; ИначеЕсли ДробнаяЧасть = 0.4 Тогда Возврат ЦелаяЧастьСтрока + " 2/5"; ИначеЕсли ДробнаяЧасть = 0.5 Тогда Возврат ЦелаяЧастьСтрока + " 1/5"; ИначеЕсли ДробнаяЧасть = 0.6 Тогда Возврат ЦелаяЧастьСтрока + " 3/5"; ИначеЕсли ДробнаяЧасть = 0.7 Тогда Возврат ЦелаяЧастьСтрока + " 7/10"; ИначеЕсли ДробнаяЧасть = 0.8 Тогда Возврат ЦелаяЧастьСтрока + " 4/5"; ИначеЕсли ДробнаяЧасть = 0.9 Тогда Возврат ЦелаяЧастьСтрока + " 9/10"; ИначеЕсли ДробнаяЧасть = 1 Тогда Возврат Строка(Цел(ЧислоВходящее+1)); КонецЕсли; |
|||
61
cube033
22.01.15
✎
08:07
|
(58) Это и есть до конца в каком-то смысле.
Задача была с точностью 1. Было бы не верным для 10 значений делать сначала цикл нахождения целых чисел, а потом нахождение НОД |
|||
62
VladZ
22.01.15
✎
08:11
|
(60) Я не про то.
ИначеЕсли (Прав(ДробнаяЧасть, 1) = "1") или (Прав(ДробнаяЧасть, 1) = "3") или (Прав(ДробнаяЧасть, 1) = "7") или (Прав(ДробнаяЧасть, 1) = "9") Возврат ЦелаяЧастьСтрока + " "+Прав(ДробнаяЧасть, 1)+"/10"; Тогда... |
|||
63
VladZ
22.01.15
✎
08:13
|
Или в случае, если бы не было всяких 1/5, 3/5 вообще приходим к одной строке.
|
|||
64
Провинциальный 1сник
22.01.15
✎
08:18
|
Рассмотрим вопрос шире - есть ли языки программирования, где есть тип данных "обыкновенная дробь" и соответственно математические операции над ними с сохранением обыкновенности (с числителем и знаменателем)?
|
|||
65
ifso
22.01.15
✎
08:21
|
(61) ну, пили уже и составные ^^
зы изучай клинопись - судя по ТЗ, клиенты вот-вот созреют и подтянуца ) |
|||
66
cube033
22.01.15
✎
08:48
|
(62) Спасибо. увидел свою ошибку 0.2 = 1/5
Если (Прав(ДробнаяЧасть, 1) = "1") или (Прав(ДробнаяЧасть, 1) = "3") или (Прав(ДробнаяЧасть, 1) = "7") или (Прав(ДробнаяЧасть, 1) = "9") Возврат ЦелаяЧастьСтрока + " "+Прав(ДробнаяЧасть, 1)+"/10"; ИначеЕсли (Прав(ДробнаяЧасть, 1) = "5") Возврат ЦелаяЧастьСтрока + " 1/2"; Иначе Возврат ЦелаяЧастьСтрока + " 1/5"; Мне кажется то же самое, только в профиль, но читаемость ниже. |
|||
67
cube033
22.01.15
✎
08:49
|
(66) Опять блин... Т.е 0,5 = 1/5 - это ошибка
|
|||
68
cube033
22.01.15
✎
08:52
|
"В целом: не нравится мне идея с округлением. Теряется часть инфы."
Изначально задача была - округление до целого. |
|||
69
VladZ
22.01.15
✎
08:55
|
(66) поставь сначала "извращения", потом все остальное. Читабельность будет лучше.
|
|||
70
VladZ
22.01.15
✎
08:59
|
как-то так:
ПоследнийСимволДробнойЧасти = Прав(ДробнаяЧасть, 1); Если (ПоследнийСимволДробнойЧасти = "5") Возврат ЦелаяЧастьСтрока + " 1/2"; ИначеЕсли ПоследнийСимволДробнойЧасти = "2" Возврат ЦелаяЧастьСтрока + " 1/5"; Иначе Возврат ЦелаяЧастьСтрока + " "+ПоследнийСимволДробнойЧасти + "/10"; КонецЕсли; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |