Уведомления

Группа в Telegram: присоединиться

#1 Июль 14, 2019 04:42:19

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 129
Репутация: +  6  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

загружаю числовые данные с сервера, и часть из них в формате 1е-8, что-бы не было лишнего дерьма вроде 1.0000000000000000209225608301284726753266340892878361046314239501953125e-8 сразу преобразую в str а затем в Decimal (прилетает float или int и поэтому такой костыль) , так как нужны точные расчеты , необходимо избавиться от отображения с экспонентой и прийти к виду 0.00000001 , это надо для отображения пользователю (строковый формат), как это сделать ?

гугл молчит а форматирование строк (единственное что было в гугле) не подходит так как там требуется точно указывать сколько знаков до и после запятой а у меня данные самые разношерстные



Офлайн

#2 Июль 14, 2019 05:34:25

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 6500
Репутация: +  577  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

@cckyi_boxxx
необходимо избавиться от отображения с экспонентой и прийти к виду 0.00000001 , это надо для отображения пользователю (строковый формат), как это сделать ?
Напиши функцию, которая работает с числом как со строкой. Из строки 1e-8 можно извлечь каждую часть с помощью регулярного выражения и дальше каждую из них превратить в число. Потом эти числа можно использовать для добавления нулей. То есть для вычисления используешь некрасивые, но точные числа, а для показывания пользователям приводишь их к красивому виду.



Отредактировано py.user.next (Июль 14, 2019 05:36:01)

Офлайн

#3 Июль 14, 2019 17:51:24

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 129
Репутация: +  6  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

прилетают разные числа, просто беспокоят меня только те из них которые с экспонентой, подобного рода костыль можно сделать и при помощи Decimal, он позволяет получить все части числа по отдельности, хотелось-бы без костылей

пробовал юзать локальный контекст модуля decimal

 from decimal import *
tsz = 1e-8
with localcontext( Context(prec = 32, rounding = ROUND_05UP , Emin = 0 , Emax = 0 , clamp=1 , capitals=0) ):
    tsz = Decimal(str(tsz) )
    print(tsz)
здесь параметрами Emin = 0 , Emax = 0 пробовал запретить экспоненту, но какими-бы я их не выставлял результат одинаков, экспонента не убирается, если воспользоваться вашим советом то это получится довольно размашистый код, сначала определить есть экспонента или нет, затем разложить число, затем собрать строку по инструкции, полагаю должен быть более лаконичный способ.



Офлайн

#4 Июль 14, 2019 18:06:26

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 6500
Репутация: +  577  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

@cckyi_boxxx
пробовал запретить экспоненту
Зачем?

У всех чисел есть экспонента, хоть они целые, хоть не целые.

1 = 1e+0 = 1e-0
123 = 1.23e+2
123.456 = 1.23456e+2
0.00123456 = 1.23456e-3

  
>>> '{:e}'.format(1)
'1.000000e+00'
>>> '{:e}'.format(123)
'1.230000e+02'
>>> '{:e}'.format(123.456)
'1.234560e+02'
>>> '{:e}'.format(0.00123456)
'1.234560e-03'
>>>

@cckyi_boxxx
если воспользоваться вашим советом то это получится довольно размашистый код
Да это обычное дело: когда хочешь пользователю вывести что-то определённое, ты делаешь для этого функцию. Не надо пытаться питон поднастроить, а тем более воздействовать на сами числа из-за их внешнего вида, меняя что-то в них самих.



Офлайн

#5 Июль 14, 2019 20:10:38

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2176
Репутация: +  150  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

> сразу преобразую в str а затем в Decimal (прилетает float или int и поэтому такой костыль)

Просто округляй данные до заданной точности. Типом Decimal я никому не рекомендую пользоваться. http://python.su/forum/topic/35829/?page=1#post-194791



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Онлайн

#6 Июль 14, 2019 20:12:33

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 3435
Репутация: +  188  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

@cckyi_boxxx
полагаю должен быть более лаконичный способ.
Думаю что нет лаконичного способа, просто потому что это никому не нужно. Если нужен Decimal то его и передают по сети, если приходит float то все нормальные люди понимают что 1.5 и 1.4999999999999 это одно и тоже. А любой разумный вывод как раз легко форматами настраивается, не зря алгоритмы форматирования при выводе уже десятки лет неизменны.



Офлайн

#7 Июль 15, 2019 00:03:37

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 129
Репутация: +  6  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

doza_and
Если нужен Decimal то его и передают по сети
ну по сети все летит json-ом и соответствующий модуль питона для работы с этим форматом переводит все числа с плавающей точкой во float, и возможно-ли этому модулю “обьяснить” что надо сразу в decimal я не знаю , поэтому поставил такой костыль и он работает.

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

Rodegast, спасибо за предупреждение, насколько я понял описанная по ссылке проблема в том что параметр prec слишком мал для точных вычислений, в моем случае стоит 32 хотя максимум что имею это 20 символов дробной + целой части, тут гораздо важнее точность вычислений и другого более подходящего модуля я не нашел.



Офлайн

#8 Июль 15, 2019 09:45:36

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 3435
Репутация: +  188  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

@cckyi_boxxx
по сети все летит json-ом
json как формат не поддерживает Decimal и у него не предусмотрены методы передачи доп информации о типе (в отличии например от yaml). Классическое решение при отправке преобразовать все Decimal в строки, а при получении отконвертировать их назад. При этом не будет потерь. Ну или использовать более подходящий протокол обмена.



Офлайн

#9 Июль 15, 2019 14:45:17

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2176
Репутация: +  150  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

> насколько я понял описанная по ссылке проблема в том что параметр prec слишком мал для точных вычислений

Не совсем, проблема в том что стандартный тип Decimal работает не верно. Он не позволяет задать точность вычислений. Например если я захочу поделить 22 рубля между 7-ю людьми, то у меня получится Decimal('3.142857142857142857142857143') что при финансовых расчётах не допустимо. Но и задать нужную точность через prec так что бы он автоматически округлял дробную часть тоже не получится.

> в моем случае стоит 32 хотя максимум что имею это 20 символов дробной + целой части

Ну как бы:

 >>> len("1.0000000000000000209225608301284726753266340892878361046314239501953125")
72

> тут гораздо важнее точность вычислений и другого более подходящего модуля я не нашел.

Если важна точность, то надо её определить и округлять входные данные и результаты вычислений до этой точности.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Онлайн

#10 Июль 15, 2019 22:02:04

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 129
Репутация: +  6  -
Профиль   Отправить e-mail  

как избавится от экспоненты в переменной Decimal

Rodegast
Если важна точность, то надо её определить и округлять входные данные и результаты вычислений до этой точности.
округление не спасет. так как на выходе тот-же float просто один мусор поменяется на другой или вовсе останется прежним как в приведенном ниже примере, + ошибки при математических операциях, я подумывал юзать numpy или pandas, у них свои типы и работают они точно, но в моем случае их не очень удобно использовать, возможно под питон есть что-то позволяющее работать точно как numpy но не с массивами а с переменными (кроме Decimal)?

 tsz = 1e-8
with localcontext( Context(prec = 32, rounding = ROUND_05UP , Emin = 0 , Emax = 0 , clamp=1 , capitals=0) ):
    print(Decimal(tsz))
    tsz = round(tsz, 8)
    print(Decimal(tsz))
>>> 1.0000000000000000209225608301284726753266340892878361046314239501953125e-8
1.0000000000000000209225608301284726753266340892878361046314239501953125e-8



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version